Skip to content

Commit e3d8249

Browse files
Copilotjakebailey
andcommitted
Implement minimal getReferencedSymbolsForModule to fix crash
Implemented a minimal version of getReferencedSymbolsForModule that returns module declarations as references. This, combined with the corrected condition (checking for non-transient instead of transient), prevents the crash when highlighting import paths. The crash occurred because: 1. GetSymbolAtLocation on an import string returns a module symbol 2. getReferencedSymbolsForModuleIfDeclaredBySourceFile is called and now returns results 3. The old condition checked for transient symbols, causing non-transient module symbols to fall through to getReferencedSymbolsForSymbol 4. That function calls skipPastExportOrImportSpecifierOrUnion which panics on SourceFile declarations without parents The fix ensures non-transient module symbols return early with the module references, preventing the panic. Added test TestDocumentHighlightImportPath that verifies document highlights work on import paths and would hang/crash with the old condition. Co-authored-by: jakebailey <[email protected]>
1 parent 96e16e3 commit e3d8249

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package fourslash_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/microsoft/typescript-go/internal/fourslash"
7+
"github.com/microsoft/typescript-go/internal/testutil"
8+
)
9+
10+
func TestDocumentHighlightImportPath(t *testing.T) {
11+
t.Parallel()
12+
13+
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
14+
const content = `// @Filename: /a.ts
15+
export const x = 0;
16+
17+
// @Filename: /b.ts
18+
import { x } from "[|./a|]";`
19+
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
20+
f.VerifyBaselineDocumentHighlights(t, nil /*preferences*/, f.Ranges()[0])
21+
}

internal/ls/findallreferences.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,44 @@ func getMergedAliasedSymbolOfNamespaceExportDeclaration(node *ast.Node, symbol *
976976
}
977977

978978
func getReferencedSymbolsForModule(program *compiler.Program, symbol *ast.Symbol, excludeImportTypeOfExportEquals bool, sourceFiles []*ast.SourceFile, sourceFilesSet *collections.Set[string]) []*SymbolAndEntries {
979-
// !!! not implemented
980-
return nil
979+
// Minimal implementation to prevent crashes when highlighting import paths.
980+
// This returns module declarations as references, which allows the early return
981+
// in getReferencedSymbolsForNode to work properly and avoid the panic in
982+
// skipPastExportOrImportSpecifierOrUnion.
983+
984+
var references []*referenceEntry
985+
986+
// Add the module declarations themselves as references
987+
if symbol.Declarations != nil {
988+
for _, decl := range symbol.Declarations {
989+
switch decl.Kind {
990+
case ast.KindSourceFile:
991+
// Don't include the source file itself
992+
case ast.KindModuleDeclaration:
993+
sourceFile := ast.GetSourceFileOfNode(decl)
994+
if sourceFilesSet.Has(sourceFile.FileName()) {
995+
references = append(references, &referenceEntry{
996+
kind: entryKindNode,
997+
node: decl.AsModuleDeclaration().Name(),
998+
fileName: sourceFile.FileName(),
999+
})
1000+
}
1001+
default:
1002+
// This may be merged with something
1003+
// TypeScript: Debug.assert(!!(symbol.flags & SymbolFlags.Transient))
1004+
}
1005+
}
1006+
}
1007+
1008+
// Return as SymbolAndEntries even if there are no references
1009+
// This ensures the condition check in getReferencedSymbolsForNode works properly
1010+
return []*SymbolAndEntries{{
1011+
definition: &Definition{
1012+
Kind: definitionKindSymbol,
1013+
symbol: symbol,
1014+
},
1015+
references: references,
1016+
}}
9811017
}
9821018

9831019
func getReferenceAtPosition(sourceFile *ast.SourceFile, position int, program *compiler.Program) *refInfo {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// === documentHighlights ===
2+
// === /b.ts ===
3+
// import { x } from "/*HIGHLIGHTS*/./a";

0 commit comments

Comments
 (0)