pushFrame = (name: string, node: Node) => {
    const nameInfo = {name, start: {...node.loc.start}};
    hookStack.unshift(nameInfo);
    hookNames.push(nameInfo);
  }
This function traverses the sourceAST and returns a mapping
that maps locations in the source code to their corresponding
Hook name, if there is a relevant Hook name for that location.

A location in the source code is represented by line and column
numbers as a Position object: { line, column }.
  - line is 1-indexed.
  - column is 0-indexed.

A Hook name will be assigned to a Hook CallExpression if the
CallExpression is for a variable declaration (i.e. it returns
a value that is assigned to a variable), and if we can reliably
infer the correct name to use (see comments in the function body
for more details).

The returned mapping is an array of locations and their assigned
names, sorted by location. Specifically, each entry in the array
contains a `name` and a `start` Position. The `name` of a given
entry is the "assigned" name in the source code until the `start`
of the **next** entry. This means that given the mapping, in order
to determine the Hook name assigned for a given source location, we
need to find the adjacent entries that most closely contain the given
location.

E.g. for the following code:

1|  function Component() {
2|    const [state, setState] = useState(0);
3|                              ^---------^ -> Cols 28 - 38: Hook CallExpression
4|
5|    useEffect(() => {...}); -> call ignored since not declaring a variable
6|
7|    return (...);
8|  }

The returned "mapping" would be something like:
  [
    {name: '<no-hook>', start: {line: 1, column: 0}},
    {name: 'state', start: {line: 2, column: 28}},
    {name: '<no-hook>', start: {line: 2, column: 38}},
  ]

Where the Hook name `state` (corresponding to the `state` variable)
is assigned to the location in the code for the CallExpression
representing the call to `useState(0)` (line 2, col 28-38).