diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 4c15abd4fe..2971ef562d 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -2353,6 +2353,9 @@ func IsArrayLiteralOrObjectLiteralDestructuringPattern(node *Node) bool { func accessKind(node *Node) AccessKind { parent := node.Parent + if parent == nil { + return AccessKindRead + } switch parent.Kind { case KindParenthesizedExpression: return accessKind(parent) @@ -2404,8 +2407,9 @@ func accessKind(node *Node) AccessKind { return AccessKindWrite } return AccessKindRead + default: + return AccessKindRead } - return AccessKindRead } func reverseAccessKind(a AccessKind) AccessKind { diff --git a/internal/fourslash/tests/documentHighlightReferenceDirective_test.go b/internal/fourslash/tests/documentHighlightReferenceDirective_test.go new file mode 100644 index 0000000000..c6ac898aa4 --- /dev/null +++ b/internal/fourslash/tests/documentHighlightReferenceDirective_test.go @@ -0,0 +1,24 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestDocumentHighlightReferenceDirective(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /a.ts +/// + +const x = 1; + +// @filename: b.ts +export type Foo = number; +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineDocumentHighlights(t, nil /*preferences*/, f.Ranges()[0]) +} diff --git a/internal/ls/documenthighlights.go b/internal/ls/documenthighlights.go index bab0f63b61..65d7039666 100644 --- a/internal/ls/documenthighlights.go +++ b/internal/ls/documenthighlights.go @@ -56,14 +56,13 @@ func (l *LanguageService) getSemanticDocumentHighlights(ctx context.Context, pos if referenceEntries == nil { return nil } + var highlights []*lsproto.DocumentHighlight for _, entry := range referenceEntries { for _, ref := range entry.references { - if ref.node != nil { - fileName, highlight := l.toDocumentHighlight(ref) - if fileName == sourceFile.FileName() { - highlights = append(highlights, highlight) - } + fileName, highlight := l.toDocumentHighlight(ref) + if fileName == sourceFile.FileName() { + highlights = append(highlights, highlight) } } } diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go index 4b937d094e..e5df1d9d9d 100644 --- a/internal/ls/findallreferences.go +++ b/internal/ls/findallreferences.go @@ -625,7 +625,7 @@ func (l *LanguageService) getReferencedSymbolsForNode(ctx context.Context, posit } if moduleSymbol := checker.GetMergedSymbol(resolvedRef.file.Symbol); moduleSymbol != nil { - return getReferencedSymbolsForModule(ctx, program, moduleSymbol /*excludeImportTypeOfExportEquals*/, false, sourceFiles, sourceFilesSet) + return l.getReferencedSymbolsForModule(ctx, program, moduleSymbol /*excludeImportTypeOfExportEquals*/, false, sourceFiles, sourceFilesSet) } // !!! not implemented @@ -673,7 +673,7 @@ func (l *LanguageService) getReferencedSymbolsForNode(ctx context.Context, posit } if symbol.Name == ast.InternalSymbolNameExportEquals { - return getReferencedSymbolsForModule(ctx, program, symbol.Parent, false /*excludeImportTypeOfExportEquals*/, sourceFiles, sourceFilesSet) + return l.getReferencedSymbolsForModule(ctx, program, symbol.Parent, false /*excludeImportTypeOfExportEquals*/, sourceFiles, sourceFilesSet) } moduleReferences := l.getReferencedSymbolsForModuleIfDeclaredBySourceFile(ctx, symbol, program, sourceFiles, checker, options, sourceFilesSet) // !!! cancellationToken @@ -700,7 +700,7 @@ func (l *LanguageService) getReferencedSymbolsForModuleIfDeclaredBySourceFile(ct } exportEquals := symbol.Exports[ast.InternalSymbolNameExportEquals] // If exportEquals != nil, we're about to add references to `import("mod")` anyway, so don't double-count them. - moduleReferences := getReferencedSymbolsForModule(ctx, program, symbol, exportEquals != nil, sourceFiles, sourceFilesSet) + moduleReferences := l.getReferencedSymbolsForModule(ctx, program, symbol, exportEquals != nil, sourceFiles, sourceFilesSet) if exportEquals == nil || !sourceFilesSet.Has(moduleSourceFileName) { return moduleReferences } @@ -1021,7 +1021,7 @@ func getMergedAliasedSymbolOfNamespaceExportDeclaration(node *ast.Node, symbol * return nil } -func getReferencedSymbolsForModule(ctx context.Context, program *compiler.Program, symbol *ast.Symbol, excludeImportTypeOfExportEquals bool, sourceFiles []*ast.SourceFile, sourceFilesSet *collections.Set[string]) []*SymbolAndEntries { +func (l *LanguageService) getReferencedSymbolsForModule(ctx context.Context, program *compiler.Program, symbol *ast.Symbol, excludeImportTypeOfExportEquals bool, sourceFiles []*ast.SourceFile, sourceFilesSet *collections.Set[string]) []*SymbolAndEntries { debug.Assert(symbol.ValueDeclaration != nil) checker, done := program.GetTypeChecker(ctx) @@ -1062,10 +1062,11 @@ func getReferencedSymbolsForModule(ctx context.Context, program *compiler.Progra } return newNodeEntry(rangeNode) case ModuleReferenceKindReference: - // or - // We can't easily create a proper range entry here without access to LanguageService, - // but we can create a node-based entry pointing to the source file which will be resolved later - return newNodeEntry(reference.referencingFile.AsNode()) + return &referenceEntry{ + kind: entryKindRange, + fileName: reference.referencingFile.FileName(), + textRange: l.createLspRangeFromBounds(reference.ref.Pos(), reference.ref.End(), reference.referencingFile), + } } return nil }) diff --git a/testdata/baselines/reference/fourslash/documentHighlights/documentHighlightReferenceDirective.baseline.jsonc b/testdata/baselines/reference/fourslash/documentHighlights/documentHighlightReferenceDirective.baseline.jsonc new file mode 100644 index 0000000000..affad0dae7 --- /dev/null +++ b/testdata/baselines/reference/fourslash/documentHighlights/documentHighlightReferenceDirective.baseline.jsonc @@ -0,0 +1,6 @@ +// === documentHighlights === +// === /a.ts === +// /// +// +// const x = 1; +// \ No newline at end of file