This turned out to be fairly simple. Given an import such as
```python
from foo.bar.baz import quux
```
we create an API-graph node for each valid dotted prefix of
`foo.bar.baz`, i.e. `foo`, `foo.bar`, and `foo.bar.baz`. For these, we
then insert nodes in the API graph, such that `foo` steps to `foo.bar`
along an edge labeled `bar`, etc.
Finally, we only allow undotted names to hang off of the API-graph
root. Thus, `foo` will have a `moduleImport` edge off of the root, and
a `getMember` edge for `bar` (which in turn has a `getMember` edge for
`baz`).
Relative imports are explicitly ignored.
Finally, this commit also adds inline tests for a variety of ways of
importing modules, including a copy of the "import-helper" tests (with
a few modifications to allow a single annotation per line, as these
get rather long quickly!).
Currently only supports the "use" side of things.
For the most part, this follows the corresponding implementation for
JavaScript. Major differences include:
- No `MkImportUse` nodes -- we just move directly from
`MkModuleImport` to its uses.
- Paths are no longer labelled by s-expressions, but rather by a
string that mirrors how you would access it in QL. This makes it very
easy to see how to access an API component -- simply look at its
`toString`!
This PR also extends `LocalSourceNode` to support looking up attribute
references and invocations of such nodes. This was again based on the
JavaScript equivalent (though without specific classes for
`InvokeNode` and the like, it's a bit more awkward to use).
This may be a slightly "bogus" location to provide for ESSA variables,
but it can be useful for debugging. For instance, where previously you
might just see
```
SSA variable x | ...
SSA variable x | ...
SSA variable x | ...
SSA variable x | ...
SSA variable x | ...
SSA variable x | ...
```
where each instance of `SSA variable x` was just a bare string, now
each occurrence will tell you (via its location) _where_ this variable
is being (re)defined.
- align synthetic pre-update nodes with synthetic post -update nodes
- move the classes into the modules
- rename modules after the new main class (eliding "needs")
After making https://github.com/github/codeql/pull/4995, I realized how easy
this would be :D
Will need to do some manual merge-conflict handling, but it should be all good
:)
This is quite a simpel model, but ends up matching what we were able to do with
points-to.
I think this modeling excercise really shows that we need a bit of a different
way to model HTTP responses... but I'm not going to try to fix that in this PR.