microsoft / microsoft/TypeScript
internal/ls: getContextNodeForNodeEntry returns nil for module-specifier literals (stock returns the enclosing import statement)
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
Stock's `getContextNodeForNodeEntry` ([src/services/findAllReferences.ts:338](https://github.com/microsoft/TypeScript/blob/v6.0.3/src/services/findAllReferences.ts#L338)) returns the enclosing import statement for a module-specifier string literal; tsgo returns nil. One visible effect: Go To Implementation on an import path returns a LocationLink whose target range is just the string literal instead of the whole import statement.
## Minimal repro
Run `go test ./internal/ls/ -run TestModuleSpecifierContextNode`:
```go
package ls
import (
"testing"
"github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/parser"
)
func TestModuleSpecifierContextNode(t *testing.T) {
t.Parallel()
text := "import { x } from \"./b\";\nx;\n"
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
FileName: "/a.ts",
Path: "/a.ts",
}, text, core.ScriptKindTS)
var literal *ast.Node
for _, stmt := range sourceFile.Statements.Nodes {
if ast.IsImportDeclaration(stmt) {
literal = stmt.AsImportDeclaration().ModuleSpecifier
}
}
if literal == nil || literal.Kind != ast.KindStringLiteral {
t.Fatalf("module specifier literal not found: %v", literal)
}
if ctx := getContextNodeForNodeEntry(literal); ctx == nil {
t.Fatal("getContextNodeForNodeEntry(module specifier) = nil; want the enclosing import statement")
}
}
```
Fails with `getContextNodeForNodeEntry(module specifier) = nil` on a pristine checkout (v7.0.2, `2bd066d8`).
The string-literal special case diverges from stock's version ([findAllReferences.ts:371](https://github.com/microsoft/TypeScript/blob/v6.0.3/src/services/findAllReferences.ts#L371)): the case keys on `node.Parent.Kind` instead of the node itself, the `FindAncestor` predicate closes over the outer `node` instead of testing its parameter, and the outer gate's `IsDeclaration(ImportDeclaration)` is true in tsgo but false in stock. Same result for the other forms `TryGetImportFromModuleSpecifier` handles (`export … from`, `import()`/`require()`, …).
Contributor guide
Assessment
This issue has not been assessed yet.