Skip to content

Improve property symbol parenting#450

Open
nicolas-guichard wants to merge 13 commits intosourcegraph:mainfrom
nicolas-guichard:property-parenting
Open

Improve property symbol parenting#450
nicolas-guichard wants to merge 13 commits intosourcegraph:mainfrom
nicolas-guichard:property-parenting

Conversation

@nicolas-guichard
Copy link
Copy Markdown

@nicolas-guichard nicolas-guichard commented Apr 7, 2026

In FileIndexer's scipSymbol, we used to try and get a symbol parent from its AST nodes's parent, which is wrong in many cases. This improves the situation for property definitions and assignments so that obj.property = {a: 1} correctly reports definitions for obj.property. and obj.property.a. instead of local symbols.

Along the way this attempts at reducing the number of spurious local symbols.

Conflicts/depends on #449

Fixes #409

Test plan

  • Added test to snapshot
  • Ensured updated snapshots still make sense
  • yarn test passes

This especially brings Typescript 5.9.3 and support for es2024.
When a symbol appears at line start, it used to have an extra carret:
```
symbol
//^^^^^ symbol
```

Now it doesn't anymore:
```
symbol
//^^^^ symbol
```

If the symbol is too short, it gets a north-west arrow:
```
s
//↖ symbol
```
Currently, assigning to the prototype property of an object creates and
references many local symbols which don't allow navigation across
multiple files.
Currently, this appears as many local symbols, or even worse the
`exports` in `module.exports` is marked as a reference to the whole
file.
When we visit a function definition, we actual visit the identifier and
pass that to getTSSymbolAtLocation and visitSymbolOccurrence. In the
constructor case however, we were passing the whole constructor node
and callees would handle constructors as a special case.

Instead, visit now gets the constructor keyword out of the constructor
node and pass that to other functions, which don't need to special-case
it anyumore.
This big ternary operator was hard to read IMO.
This avoids spurious local symbols, especially when assigning to a
property of a function.
The comment was wrong: it says blocks are local symbols that reached
this fallback but they are actually filtered out earlier to return
empty symbols.

This greatly reduces the number of local symbols for things that aren't
symbols at all.
This will allow extending getParent to fix a couple of cases were the
parent node in the AST isn't the semantic parent.
The parent of a property in a property definition isn't the parent in
the AST.

Take this example:
```js
obj.property = {a: 3}
```

Previously `property`'s parent would be the `obj.property`
`PropertyAccessExpression` node and `a`'s parent would be the
`BinaryExpression` node.

Neither of them really are symbols. Instead `property`'s parent should
be `obj` ie the `expression` of the `PropertyAccessExpression` node
and `a`'s parent should be `obj.property` ie the `left` part of the
`BinaryExpression` node.
When we export a class or function expression (as opposed to class or
function definition), the exported symbol should be used as the
canonical definition.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cross file definition not connected

1 participant