From 42ca92af1c399fd03f64a86bf139235e92380cff Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 10:16:29 -0800 Subject: [PATCH 01/46] Implement support for `IncludeDeclaration` in find-all-references. --- internal/ast/ast.go | 4 ++-- internal/ls/findallreferences.go | 40 +++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 7939f87efc..54e943d4a2 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -2214,11 +2214,11 @@ func IsWriteAccess(node *Node) bool { } func IsWriteAccessForReference(node *Node) bool { - decl := getDeclarationFromName(node) + decl := GetDeclarationFromName(node) return (decl != nil && declarationIsWriteAccess(decl)) || node.Kind == KindDefaultKeyword || IsWriteAccess(node) } -func getDeclarationFromName(name *Node) *Declaration { +func GetDeclarationFromName(name *Node) *Declaration { if name == nil || name.Parent == nil { return nil } diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go index 8853b503b0..d54ee9dfe5 100644 --- a/internal/ls/findallreferences.go +++ b/internal/ls/findallreferences.go @@ -426,7 +426,9 @@ func (l *LanguageService) ProvideReferences(ctx context.Context, params *lsproto symbolsAndEntries := l.getReferencedSymbolsForNode(ctx, position, node, program, program.GetSourceFiles(), options, nil) - locations := core.FlatMap(symbolsAndEntries, l.convertSymbolAndEntriesToLocations) + locations := core.FlatMap(symbolsAndEntries, func(s *SymbolAndEntries) []lsproto.Location { + return l.convertSymbolAndEntriesToLocations(s, params.Context.IncludeDeclaration) + }) return lsproto.LocationsOrNull{Locations: &locations}, nil } @@ -543,8 +545,40 @@ func (l *LanguageService) getTextForRename(originalNode *ast.Node, entry *Refere } // == functions for conversions == -func (l *LanguageService) convertSymbolAndEntriesToLocations(s *SymbolAndEntries) []lsproto.Location { - return l.convertEntriesToLocations(s.references) +func (l *LanguageService) convertSymbolAndEntriesToLocations(s *SymbolAndEntries, includeDeclarations bool) []lsproto.Location { + references := s.references + + if !includeDeclarations && s.definition != nil { + references = core.Filter(references, func(entry *ReferenceEntry) bool { + return !isDeclarationOfSymbol(entry.node, s.definition.symbol) + }) + } + + return l.convertEntriesToLocations(references) +} + +func isDeclarationOfSymbol(node *ast.Node, target *ast.Symbol) bool { + if target == nil { + return false + } + + var source *ast.Node + if decl := ast.GetDeclarationFromName(node); decl != nil { + source = decl + } else if node.Kind == ast.KindDefaultKeyword { + source = node.Parent + } else if ast.IsLiteralComputedPropertyDeclarationName(node) { + source = node.Parent.Parent + } else if node.Kind == ast.KindConstructorKeyword && ast.IsConstructorDeclaration(node.Parent) { + source = node.Parent.Parent + } + + // !!! + // const commonjsSource = source && isBinaryExpression(source) ? source.left as unknown as Declaration : undefined; + + return source != nil && core.Some(target.Declarations, func(decl *ast.Node) bool { + return decl == source + }) } func (l *LanguageService) convertEntriesToLocations(entries []*ReferenceEntry) []lsproto.Location { From 6a1bab54eebfa01463287f6b2b6dc69266e51944 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 10:24:23 -0800 Subject: [PATCH 02/46] Added some configuration to go-to-implementation. --- internal/ls/findallreferences.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go index d54ee9dfe5..f6d59b6a80 100644 --- a/internal/ls/findallreferences.go +++ b/internal/ls/findallreferences.go @@ -433,6 +433,17 @@ func (l *LanguageService) ProvideReferences(ctx context.Context, params *lsproto } func (l *LanguageService) ProvideImplementations(ctx context.Context, params *lsproto.ImplementationParams) (lsproto.ImplementationResponse, error) { + return l.provideImplementationsEx(ctx, params, provideImplementationsOpts{}) +} + +type provideImplementationsOpts struct { + // Force the result to be Location objects. + requireLocationsResult bool + // Omit node(s) containing the original position. + dropOriginNodes bool +} + +func (l *LanguageService) provideImplementationsEx(ctx context.Context, params *lsproto.ImplementationParams, opts provideImplementationsOpts) (lsproto.ImplementationResponse, error) { program, sourceFile := l.getProgramAndFile(params.TextDocument.Uri) position := int(l.converters.LineAndCharacterToPosition(sourceFile, params.Position)) node := astnav.GetTouchingPropertyName(sourceFile, position) @@ -449,12 +460,14 @@ func (l *LanguageService) ProvideImplementations(ctx context.Context, params *ls queue = queue[1:] if !seenNodes.Has(entry.node) { seenNodes.Add(entry.node) - entries = append(entries, entry) + if !(opts.dropOriginNodes && entry.node.Loc.ContainsInclusive(position)) { + entries = append(entries, entry) + } queue = append(queue, l.getImplementationReferenceEntries(ctx, program, entry.node, entry.node.Pos())...) } } - if lsproto.GetClientCapabilities(ctx).TextDocument.Implementation.LinkSupport { + if !opts.requireLocationsResult && lsproto.GetClientCapabilities(ctx).TextDocument.Implementation.LinkSupport { links := l.convertEntriesToLocationLinks(entries) return lsproto.LocationOrLocationsOrDefinitionLinksOrNull{DefinitionLinks: &links}, nil } From 145868f5515e801d88c809a7049d96ccfd81de6d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 10:24:49 -0800 Subject: [PATCH 03/46] Just hoist argument into variable. --- internal/ls/findallreferences.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go index f6d59b6a80..98e5ff3d61 100644 --- a/internal/ls/findallreferences.go +++ b/internal/ls/findallreferences.go @@ -1626,7 +1626,8 @@ func (state *refState) getReferencesInContainerOrFiles(symbol *ast.Symbol, searc // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). if scope := getSymbolScope(symbol); scope != nil { - state.getReferencesInContainer(scope, ast.GetSourceFileOfNode(scope), search /*addReferencesHere*/, !(scope.Kind == ast.KindSourceFile && !slices.Contains(state.sourceFiles, scope.AsSourceFile()))) + addReferencesHere := scope.Kind != ast.KindSourceFile || slices.Contains(state.sourceFiles, scope.AsSourceFile()) + state.getReferencesInContainer(scope, ast.GetSourceFileOfNode(scope), search, addReferencesHere) } else { // Global search for _, sourceFile := range state.sourceFiles { From ec585717eaf1b39375ac2447d657d555ccba9934 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 10:37:30 -0800 Subject: [PATCH 04/46] Implemented CodeLens. --- _extension/package.json | 5 + _extension/src/client.ts | 31 ++- internal/diagnostics/diagnostics_generated.go | 8 + .../diagnostics/extraDiagnosticMessages.json | 16 ++ internal/ls/codelens.go | 224 ++++++++++++++++++ internal/ls/lsutil/userpreferences.go | 53 +++++ internal/lsp/server.go | 23 ++ 7 files changed, 357 insertions(+), 3 deletions(-) create mode 100644 internal/ls/codelens.go diff --git a/_extension/package.json b/_extension/package.json index 1a1f2864a5..6a37381f14 100644 --- a/_extension/package.json +++ b/_extension/package.json @@ -91,6 +91,11 @@ "title": "Report Issue", "enablement": "typescript.native-preview.serverRunning", "category": "TypeScript Native Preview" + }, + { + "title": "Show References of CodeLens", + "command": "typescript.codeLens.showLocations", + "enablement": "false" } ] }, diff --git a/_extension/src/client.ts b/_extension/src/client.ts index b759501e97..a9a9028945 100644 --- a/_extension/src/client.ts +++ b/_extension/src/client.ts @@ -1,8 +1,11 @@ import * as vscode from "vscode"; import { + DocumentUri, LanguageClient, LanguageClientOptions, + Location, NotebookDocumentFilter, + Position, ServerOptions, TextDocumentFilter, TransportKind, @@ -119,10 +122,32 @@ export class Client { await this.client.start(); vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", true); this.onStartedCallbacks.forEach(callback => callback()); - return new vscode.Disposable(() => { - if (this.client) { - this.client.stop(); + + const codeLensLocationsCommand = vscode.commands.registerCommand("typescript.codeLens.showLocations", (...args: unknown[]) => { + if (args.length !== 3) { + throw new Error("Unexpected number of arguments."); } + + const lspUri = args[0] as DocumentUri; + const lspPosition = args[1] as Position; + const lspLocations = args[2] as Location[]; + + const editorUri = vscode.Uri.parse(lspUri); + const editorPosition = new vscode.Position(lspPosition.line, lspPosition.character); + const editorLocations = lspLocations.map(loc => new vscode.Location( + vscode.Uri.parse(loc.uri), + new vscode.Range( + new vscode.Position(loc.range.start.line, loc.range.start.character), + new vscode.Position(loc.range.end.line, loc.range.end.character), + ), + )); + + vscode.commands.executeCommand("editor.action.showReferences", editorUri, editorPosition, editorLocations); + }); + + return new vscode.Disposable(() => { + this.client?.stop(); + codeLensLocationsCommand.dispose(); vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", false); }); } diff --git a/internal/diagnostics/diagnostics_generated.go b/internal/diagnostics/diagnostics_generated.go index 7cfec6d219..7f37a6de19 100644 --- a/internal/diagnostics/diagnostics_generated.go +++ b/internal/diagnostics/diagnostics_generated.go @@ -4257,3 +4257,11 @@ var Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory = &Message{co var Set_the_number_of_checkers_per_project = &Message{code: 100003, category: CategoryMessage, key: "Set_the_number_of_checkers_per_project_100003", text: "Set the number of checkers per project."} var X_4_unless_singleThreaded_is_passed = &Message{code: 100004, category: CategoryMessage, key: "4_unless_singleThreaded_is_passed_100004", text: "4, unless --singleThreaded is passed."} + +var X_0_references = &Message{code: 100005, category: CategoryMessage, key: "_0_references_100005", text: "{0} references"} + +var X_1_reference = &Message{code: 100006, category: CategoryMessage, key: "1_reference_100006", text: "1 reference"} + +var X_0_implementations = &Message{code: 100007, category: CategoryMessage, key: "_0_implementations_100007", text: "{0} implementations"} + +var X_1_implementation = &Message{code: 100008, category: CategoryMessage, key: "1_implementation_100008", text: "1 implementation"} diff --git a/internal/diagnostics/extraDiagnosticMessages.json b/internal/diagnostics/extraDiagnosticMessages.json index edf9c5735b..38a29aa6d3 100644 --- a/internal/diagnostics/extraDiagnosticMessages.json +++ b/internal/diagnostics/extraDiagnosticMessages.json @@ -19,6 +19,22 @@ "category": "Message", "code": 100004 }, + "{0} references": { + "category": "Message", + "code": 100005 + }, + "1 reference": { + "category": "Message", + "code": 100006 + }, + "{0} implementations": { + "category": "Message", + "code": 100007 + }, + "1 implementation": { + "category": "Message", + "code": 100008 + }, "Non-relative paths are not allowed. Did you forget a leading './'?": { "category": "Error", "code": 5090 diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go new file mode 100644 index 0000000000..328d8610fc --- /dev/null +++ b/internal/ls/codelens.go @@ -0,0 +1,224 @@ +package ls + +import ( + "context" + "fmt" + + "github.com/go-json-experiment/json" + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/diagnostics" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/lsp/lsproto" + "github.com/microsoft/typescript-go/internal/scanner" +) + +type CodeLensKind string + +const ( + codeLensReferencesKind CodeLensKind = "references" + codeLensImplementationsKind CodeLensKind = "implementations" +) + +type CodeLensData struct { + Kind CodeLensKind `json:"kind"` + Uri lsproto.DocumentUri `json:"uri"` +} + +func GetCodeLensData(item *lsproto.CodeLens) (*CodeLensData, error) { + bytes, err := json.Marshal(item.Data) + if err != nil { + return nil, fmt.Errorf("failed to marshal completion item data: %w", err) + } + var itemData CodeLensData + if err := json.Unmarshal(bytes, &itemData); err != nil { + return nil, fmt.Errorf("failed to unmarshal completion item data: %w", err) + } + return &itemData, nil +} + +func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsproto.DocumentUri) (lsproto.CodeLensResponse, error) { + _, file := l.getProgramAndFile(documentURI) + + userPrefs := l.UserPreferences() + if !userPrefs.ReferencesCodeLensEnabled && !userPrefs.ImplementationsCodeLensEnabled { + return lsproto.CodeLensResponse{}, nil + } + + var lenses []*lsproto.CodeLens + var visit func(node *ast.Node) bool + visit = func(node *ast.Node) bool { + if ctx.Err() != nil { + return true + } + + if userPrefs.ReferencesCodeLensEnabled && isValidReferenceLensNode(node, userPrefs) { + lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, codeLensReferencesKind)) + } + + if userPrefs.ImplementationsCodeLensEnabled && isValidImplementationsCodeLensNode(node, userPrefs) { + lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, codeLensImplementationsKind)) + } + + node.ForEachChild(visit) + return false + } + + visit(file.AsNode()) + + return lsproto.CodeLensResponse{ + CodeLenss: &lenses, + }, nil +} + +func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto.CodeLens, codeLensData *CodeLensData) (*lsproto.CodeLens, error) { + uri := codeLensData.Uri + textDoc := lsproto.TextDocumentIdentifier{ + Uri: uri, + } + + var locs []lsproto.Location + var lensTitle string + switch codeLensData.Kind { + case codeLensReferencesKind: + references, err := l.ProvideReferences(ctx, &lsproto.ReferenceParams{ + TextDocument: textDoc, + Position: codeLens.Range.Start, + Context: &lsproto.ReferenceContext{ + // Don't include the declaration in the references count. + IncludeDeclaration: false, + }, + }) + if err != nil { + return nil, err + } + + if references.Locations != nil { + locs = *references.Locations + } + + if len(locs) == 1 { + lensTitle = diagnostics.X_1_reference.Message() + } else { + lensTitle = diagnostics.X_0_references.Format(len(locs)) + } + case codeLensImplementationsKind: + // "Force" link support to be false so that we only get `Locations` back, + // and don't include the "current" node in the results. + findImplsOptions := provideImplementationsOpts{ + requireLocationsResult: true, + dropOriginNodes: true, + } + implementations, err := l.provideImplementationsEx(ctx, &lsproto.ImplementationParams{ + TextDocument: textDoc, + Position: codeLens.Range.Start, + }, findImplsOptions) + if err != nil { + return nil, err + } + + if implementations.Locations != nil { + locs = *implementations.Locations + } + + if len(locs) == 1 { + lensTitle = diagnostics.X_1_implementation.Message() + } else { + lensTitle = diagnostics.X_0_implementations.Format(len(locs)) + } + } + + cmd := &lsproto.Command{ + Title: lensTitle, + } + if len(locs) > 0 { + cmd.Command = "typescript.codeLens.showLocations" + cmd.Arguments = &[]any{ + uri, + codeLens.Range.Start, + locs, + } + } + + codeLens.Command = cmd + return codeLens, nil +} + +func (l *LanguageService) newCodeLensForNode(fileUri lsproto.DocumentUri, file *ast.SourceFile, node *ast.Node, kind CodeLensKind) *lsproto.CodeLens { + nodeForRange := node + nodeName := node.Name() + if nodeName != nil { + nodeForRange = nodeName + } + pos := scanner.SkipTrivia(file.Text(), nodeForRange.Pos()) + + var data any = &CodeLensData{ + Kind: kind, + Uri: fileUri, + } + + return &lsproto.CodeLens{ + Range: lsproto.Range{ + Start: l.converters.PositionToLineAndCharacter(file, core.TextPos(pos)), + End: l.converters.PositionToLineAndCharacter(file, core.TextPos(node.End())), + }, + Data: &data, + } +} + +func isValidImplementationsCodeLensNode(node *ast.Node, userPrefs *lsutil.UserPreferences) bool { + switch node.Kind { + // Always show on interfaces + case ast.KindInterfaceDeclaration: + // TODO: ast.KindTypeAliasDeclaration? + return true + + // If configured, show on interface methods + case ast.KindMethodSignature: + return userPrefs.ImplementationsCodeLensShowOnInterfaceMethods && node.Parent.Kind == ast.KindInterfaceDeclaration + + // If configured, show on all class methods - but not private ones. + case ast.KindMethodDeclaration: + if userPrefs.ImplementationsCodeLensShowOnAllClassMethods && node.Parent.Kind == ast.KindClassDeclaration { + return !ast.HasModifier(node, ast.ModifierFlagsPrivate) && node.Name().Kind != ast.KindPrivateIdentifier + } + fallthrough + + // Always show on abstract classes/properties/methods + case ast.KindClassDeclaration, ast.KindConstructor, + ast.KindGetAccessor, ast.KindSetAccessor, ast.KindPropertyDeclaration: + return ast.HasModifier(node, ast.ModifierFlagsAbstract) + } + + return false +} + +func isValidReferenceLensNode(node *ast.Node, userPrefs *lsutil.UserPreferences) bool { + switch node.Kind { + case ast.KindFunctionDeclaration, ast.KindFunctionExpression: + if userPrefs.ReferencesCodeLensShowOnAllFunctions { + return true + } + fallthrough + + case ast.KindVariableDeclaration: + return ast.GetCombinedModifierFlags(node)&ast.ModifierFlagsExport != 0 + + case ast.KindClassDeclaration, ast.KindInterfaceDeclaration, ast.KindTypeAliasDeclaration, ast.KindEnumDeclaration, ast.KindEnumMember: + return true + + case ast.KindMethodDeclaration, ast.KindMethodSignature, ast.KindConstructor, + ast.KindGetAccessor, ast.KindSetAccessor, + ast.KindPropertyDeclaration, ast.KindPropertySignature: + // Don't show if child and parent have same start + // For https://github.com/microsoft/vscode/issues/90396 + // !!! + + switch node.Parent.Kind { + case ast.KindClassDeclaration, ast.KindInterfaceDeclaration, ast.KindTypeLiteral: + return true + } + } + + return false +} diff --git a/internal/ls/lsutil/userpreferences.go b/internal/ls/lsutil/userpreferences.go index b6ce0c9537..07a0680e3e 100644 --- a/internal/ls/lsutil/userpreferences.go +++ b/internal/ls/lsutil/userpreferences.go @@ -143,6 +143,13 @@ type UserPreferences struct { IncludeInlayFunctionLikeReturnTypeHints bool IncludeInlayEnumMemberValueHints bool + // ------- CodeLens ------- + ReferencesCodeLensEnabled bool + ImplementationsCodeLensEnabled bool + ReferencesCodeLensShowOnAllFunctions bool + ImplementationsCodeLensShowOnInterfaceMethods bool + ImplementationsCodeLensShowOnAllClassMethods bool + // ------- Misc ------- ExcludeLibrarySymbolsInNavTo bool // !!! @@ -376,6 +383,10 @@ func (p *UserPreferences) parseWorker(config map[string]any) { continue case "inlayHints": p.parseInlayHints(values) + case "referencesCodeLens": + p.parseReferencesCodeLens(values) + case "implementationsCodeLens": + p.parseImplementationsCodeLens(values) case "suggest": p.parseSuggest(values) case "preferences": @@ -437,6 +448,38 @@ func (p *UserPreferences) parseInlayHints(prefs any) { } } +func (p *UserPreferences) parseReferencesCodeLens(prefs any) { + referencesCodeLens, ok := prefs.(map[string]any) + if !ok { + return + } + for name, value := range referencesCodeLens { + switch name { + case "enabled": + p.set("referencesCodeLensEnabled", value) + case "showOnAllFunctions": + p.set("referencesCodeLensShowOnAllFunctions", value) + } + } +} + +func (p *UserPreferences) parseImplementationsCodeLens(prefs any) { + implementationsCodeLens, ok := prefs.(map[string]any) + if !ok { + return + } + for name, value := range implementationsCodeLens { + switch name { + case "enabled": + p.set("implementationsCodeLensEnabled", value) + case "showOnInterfaceMethods": + p.set("implementationsCodeLensShowOnInterfaceMethods", value) + case "showOnAllClassMethods": + p.set("implementationsCodeLensShowOnAllClassMethods", value) + } + } +} + func (p *UserPreferences) parseSuggest(prefs any) { completionsPreferences, ok := prefs.(map[string]any) if !ok { @@ -632,5 +675,15 @@ func (p *UserPreferences) set(name string, value any) { p.DisplayPartsForJSDoc = parseBoolWithDefault(value, true) case "reportstylechecksaswarnings": p.ReportStyleChecksAsWarnings = parseBoolWithDefault(value, true) + case "referencescodelensenabled": + p.ReferencesCodeLensEnabled = parseBoolWithDefault(value, false) + case "implementationscodelensenabled": + p.ImplementationsCodeLensEnabled = parseBoolWithDefault(value, false) + case "referencescodelensshowonallfunctions": + p.ReferencesCodeLensShowOnAllFunctions = parseBoolWithDefault(value, false) + case "implementationscodelensshowoninterfacemethods": + p.ImplementationsCodeLensShowOnInterfaceMethods = parseBoolWithDefault(value, false) + case "implementationscodelensshowonallclassmethods": + p.ImplementationsCodeLensShowOnAllClassMethods = parseBoolWithDefault(value, false) } } diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 2c3eafa3a7..1e38f951b5 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -498,7 +498,9 @@ var handlers = sync.OnceValue(func() handlerMap { registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentInlayHintInfo, (*Server).handleInlayHint) + registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCodeLensInfo, (*Server).handleCodeLens) registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) + registerRequestHandler(handlers, lsproto.CodeLensResolveInfo, (*Server).handleCodeLensResolve) registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol) registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve) @@ -690,6 +692,9 @@ func (s *Server) handleInitialize(ctx context.Context, params *lsproto.Initializ InlayHintProvider: &lsproto.BooleanOrInlayHintOptionsOrInlayHintRegistrationOptions{ Boolean: ptrTo(true), }, + CodeLensProvider: &lsproto.CodeLensOptions{ + ResolveProvider: ptrTo(true), + }, CodeActionProvider: &lsproto.BooleanOrCodeActionOptions{ CodeActionOptions: &lsproto.CodeActionOptions{ CodeActionKinds: &[]lsproto.CodeActionKind{ @@ -973,6 +978,24 @@ func (s *Server) handleInlayHint( return languageService.ProvideInlayHint(ctx, params) } +func (s *Server) handleCodeLens(ctx context.Context, ls *ls.LanguageService, params *lsproto.CodeLensParams) (lsproto.CodeLensResponse, error) { + return ls.ProvideCodeLenses(ctx, params.TextDocument.Uri) +} + +func (s *Server) handleCodeLensResolve(ctx context.Context, codeLens *lsproto.CodeLens, reqMsg *lsproto.RequestMessage) (*lsproto.CodeLens, error) { + data, err := ls.GetCodeLensData(codeLens) + if err != nil { + return nil, err + } + ls, err := s.session.GetLanguageService(ctx, data.Uri) + if err != nil { + return nil, err + } + defer s.recover(reqMsg) + + return ls.ResolveCodeLens(ctx, codeLens, data) +} + func (s *Server) Log(msg ...any) { fmt.Fprintln(s.stderr, msg...) } From ddb7ef68ae87fd721a0adf353f47325a4d185dc8 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 19:51:53 +0000 Subject: [PATCH 05/46] Set `IncludeDeclaration` for all tests. --- internal/fourslash/fourslash.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index cd4c486559..a1cfa5ed6e 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1243,7 +1243,9 @@ func (f *FourslashTest) VerifyBaselineFindAllReferences( Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, Position: f.currentCaretPosition, - Context: &lsproto.ReferenceContext{}, + Context: &lsproto.ReferenceContext{ + IncludeDeclaration: true, + }, } resMsg, result, resultOk := sendRequest(t, f, lsproto.TextDocumentReferencesInfo, params) if resMsg == nil { From 477863e3006af883106a4c76548c7801ba3fef7a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 21:29:17 +0000 Subject: [PATCH 06/46] Added custom `CodeLensData` types to `generate.mts` . --- internal/ls/codelens.go | 54 ++++----------- internal/lsp/lsproto/_generate/generate.mts | 39 ++++++++++- internal/lsp/lsproto/lsp_generated.go | 74 ++++++++++++++++++++- internal/lsp/server.go | 8 +-- 4 files changed, 124 insertions(+), 51 deletions(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index 328d8610fc..74864be061 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -2,9 +2,7 @@ package ls import ( "context" - "fmt" - "github.com/go-json-experiment/json" "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/diagnostics" @@ -13,30 +11,6 @@ import ( "github.com/microsoft/typescript-go/internal/scanner" ) -type CodeLensKind string - -const ( - codeLensReferencesKind CodeLensKind = "references" - codeLensImplementationsKind CodeLensKind = "implementations" -) - -type CodeLensData struct { - Kind CodeLensKind `json:"kind"` - Uri lsproto.DocumentUri `json:"uri"` -} - -func GetCodeLensData(item *lsproto.CodeLens) (*CodeLensData, error) { - bytes, err := json.Marshal(item.Data) - if err != nil { - return nil, fmt.Errorf("failed to marshal completion item data: %w", err) - } - var itemData CodeLensData - if err := json.Unmarshal(bytes, &itemData); err != nil { - return nil, fmt.Errorf("failed to unmarshal completion item data: %w", err) - } - return &itemData, nil -} - func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsproto.DocumentUri) (lsproto.CodeLensResponse, error) { _, file := l.getProgramAndFile(documentURI) @@ -53,11 +27,11 @@ func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsp } if userPrefs.ReferencesCodeLensEnabled && isValidReferenceLensNode(node, userPrefs) { - lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, codeLensReferencesKind)) + lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, lsproto.CodeLensKindReferences)) } if userPrefs.ImplementationsCodeLensEnabled && isValidImplementationsCodeLensNode(node, userPrefs) { - lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, codeLensImplementationsKind)) + lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, lsproto.CodeLensKindImplementations)) } node.ForEachChild(visit) @@ -67,20 +41,20 @@ func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsp visit(file.AsNode()) return lsproto.CodeLensResponse{ - CodeLenss: &lenses, + CodeLenses: &lenses, }, nil } -func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto.CodeLens, codeLensData *CodeLensData) (*lsproto.CodeLens, error) { - uri := codeLensData.Uri +func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto.CodeLens) (*lsproto.CodeLens, error) { + uri := codeLens.Data.Uri textDoc := lsproto.TextDocumentIdentifier{ Uri: uri, } var locs []lsproto.Location var lensTitle string - switch codeLensData.Kind { - case codeLensReferencesKind: + switch codeLens.Data.Kind { + case lsproto.CodeLensKindReferences: references, err := l.ProvideReferences(ctx, &lsproto.ReferenceParams{ TextDocument: textDoc, Position: codeLens.Range.Start, @@ -102,7 +76,7 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto } else { lensTitle = diagnostics.X_0_references.Format(len(locs)) } - case codeLensImplementationsKind: + case lsproto.CodeLensKindImplementations: // "Force" link support to be false so that we only get `Locations` back, // and don't include the "current" node in the results. findImplsOptions := provideImplementationsOpts{ @@ -144,7 +118,7 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto return codeLens, nil } -func (l *LanguageService) newCodeLensForNode(fileUri lsproto.DocumentUri, file *ast.SourceFile, node *ast.Node, kind CodeLensKind) *lsproto.CodeLens { +func (l *LanguageService) newCodeLensForNode(fileUri lsproto.DocumentUri, file *ast.SourceFile, node *ast.Node, kind lsproto.CodeLensKind) *lsproto.CodeLens { nodeForRange := node nodeName := node.Name() if nodeName != nil { @@ -152,17 +126,15 @@ func (l *LanguageService) newCodeLensForNode(fileUri lsproto.DocumentUri, file * } pos := scanner.SkipTrivia(file.Text(), nodeForRange.Pos()) - var data any = &CodeLensData{ - Kind: kind, - Uri: fileUri, - } - return &lsproto.CodeLens{ Range: lsproto.Range{ Start: l.converters.PositionToLineAndCharacter(file, core.TextPos(pos)), End: l.converters.PositionToLineAndCharacter(file, core.TextPos(node.End())), }, - Data: &data, + Data: &lsproto.CodeLensData{ + Kind: kind, + Uri: fileUri, + }, } } diff --git a/internal/lsp/lsproto/_generate/generate.mts b/internal/lsp/lsproto/_generate/generate.mts index a8dbf32115..5f4d366fa2 100644 --- a/internal/lsp/lsproto/_generate/generate.mts +++ b/internal/lsp/lsproto/_generate/generate.mts @@ -6,6 +6,7 @@ import path from "node:path"; import url from "node:url"; import which from "which"; import type { + Enumeration, MetaModel, Notification, OrType, @@ -151,6 +152,41 @@ const customStructures: Structure[] = [ ], documentation: "CompletionItemData is preserved on a CompletionItem between CompletionRequest and CompletionResolveRequest.", }, + { + name: "CodeLensData", + properties: [ + { + name: "kind", + type: { kind: "reference", name: "CodeLensKind" }, + documentation: `The kind of the code lens ("references" or "implementations").`, + }, + { + name: "uri", + type: { kind: "base", name: "DocumentUri" }, + documentation: `The document in which the code lens and its range are located.`, + }, + ], + }, +]; + +const customEnumerations: Enumeration[] = [ + { + name: "CodeLensKind", + type: { + kind: "base", + name: "string", + }, + values: [ + { + name: "References", + value: "references", + }, + { + name: "Implementations", + value: "implementations", + }, + ], + }, ]; // Track which custom Data structures were declared explicitly @@ -251,7 +287,8 @@ function patchAndPreprocessModel() { }); } - // Add custom structures and synthetic structures to the model + // Add custom enumerations, custom structures, and synthetic structures to the model + model.enumerations.push(...customEnumerations); model.structures.push(...customStructures, ...syntheticStructures); // Build structure map for preprocessing diff --git a/internal/lsp/lsproto/lsp_generated.go b/internal/lsp/lsproto/lsp_generated.go index 3c43d47da3..e5b3f0eb99 100644 --- a/internal/lsp/lsproto/lsp_generated.go +++ b/internal/lsp/lsproto/lsp_generated.go @@ -21579,6 +21579,70 @@ type CompletionItemData struct { AutoImport *AutoImportData `json:"autoImport,omitzero"` } +type CodeLensData struct { + // The kind of the code lens ("references" or "implementations"). + Kind CodeLensKind `json:"kind"` + + // The document in which the code lens and its range are located. + Uri DocumentUri `json:"uri"` +} + +var _ json.UnmarshalerFrom = (*CodeLensData)(nil) + +func (s *CodeLensData) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + const ( + missingKind uint = 1 << iota + missingUri + _missingLast + ) + missing := _missingLast - 1 + + if k := dec.PeekKind(); k != '{' { + return fmt.Errorf("expected object start, but encountered %v", k) + } + if _, err := dec.ReadToken(); err != nil { + return err + } + + for dec.PeekKind() != '}' { + name, err := dec.ReadValue() + if err != nil { + return err + } + switch string(name) { + case `"kind"`: + missing &^= missingKind + if err := json.UnmarshalDecode(dec, &s.Kind); err != nil { + return err + } + case `"uri"`: + missing &^= missingUri + if err := json.UnmarshalDecode(dec, &s.Uri); err != nil { + return err + } + default: + // Ignore unknown properties. + } + } + + if _, err := dec.ReadToken(); err != nil { + return err + } + + if missing != 0 { + var missingProps []string + if missing&missingKind != 0 { + missingProps = append(missingProps, "kind") + } + if missing&missingUri != 0 { + missingProps = append(missingProps, "uri") + } + return fmt.Errorf("missing required properties: %s", strings.Join(missingProps, ", ")) + } + + return nil +} + // CallHierarchyItemData is a placeholder for custom data preserved on a CallHierarchyItem. type CallHierarchyItemData struct{} @@ -21594,9 +21658,6 @@ type CodeActionData struct{} // WorkspaceSymbolData is a placeholder for custom data preserved on a WorkspaceSymbol. type WorkspaceSymbolData struct{} -// CodeLensData is a placeholder for custom data preserved on a CodeLens. -type CodeLensData struct{} - // DocumentLinkData is a placeholder for custom data preserved on a DocumentLink. type DocumentLinkData struct{} @@ -22431,6 +22492,13 @@ const ( TokenFormatRelative TokenFormat = "relative" ) +type CodeLensKind string + +const ( + CodeLensKindReferences CodeLensKind = "references" + CodeLensKindImplementations CodeLensKind = "implementations" +) + func unmarshalParams(method Method, data []byte) (any, error) { switch method { case MethodTextDocumentImplementation: diff --git a/internal/lsp/server.go b/internal/lsp/server.go index b92a92e10e..c8b1055618 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -981,17 +981,13 @@ func (s *Server) handleCodeLens(ctx context.Context, ls *ls.LanguageService, par } func (s *Server) handleCodeLensResolve(ctx context.Context, codeLens *lsproto.CodeLens, reqMsg *lsproto.RequestMessage) (*lsproto.CodeLens, error) { - data, err := ls.GetCodeLensData(codeLens) - if err != nil { - return nil, err - } - ls, err := s.session.GetLanguageService(ctx, data.Uri) + ls, err := s.session.GetLanguageService(ctx, codeLens.Data.Uri) if err != nil { return nil, err } defer s.recover(reqMsg) - return ls.ResolveCodeLens(ctx, codeLens, data) + return ls.ResolveCodeLens(ctx, codeLens) } func (s *Server) Log(msg ...any) { From 0596214a7cc3f65097c5d80d96692c0761bcb51b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 21 Nov 2025 22:44:11 +0000 Subject: [PATCH 07/46] Use a handshake for the CodeLens command name, and use an appropriately namespaced command in the extension. --- _extension/package.json | 16 ++++++++---- _extension/src/client.ts | 27 +++++++++++++-------- internal/ls/codelens.go | 6 ++--- internal/lsp/lsproto/_generate/generate.mts | 6 +++++ internal/lsp/lsproto/lsp_generated.go | 3 +++ internal/lsp/server.go | 2 +- 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/_extension/package.json b/_extension/package.json index 6a37381f14..2e92d16498 100644 --- a/_extension/package.json +++ b/_extension/package.json @@ -40,17 +40,23 @@ ], "default": "verbose", "description": "Trace TypeScript Go server communication.", - "tags": ["experimental"] + "tags": [ + "experimental" + ] }, "typescript.native-preview.pprofDir": { "type": "string", "description": "Directory to write pprof profiles to.", - "tags": ["experimental"] + "tags": [ + "experimental" + ] }, "typescript.native-preview.tsdk": { "type": "string", "description": "Path to the @typescript/native-preview package or tsgo binary directory. If not specified, the extension will look for it in the default location.", - "tags": ["experimental"] + "tags": [ + "experimental" + ] } } } @@ -94,7 +100,7 @@ }, { "title": "Show References of CodeLens", - "command": "typescript.codeLens.showLocations", + "command": "typescript.native-preview.codeLens.showLocations", "enablement": "false" } ] @@ -120,4 +126,4 @@ "@vscode/vsce": "^3.7.0", "esbuild": "^0.27.0" } -} +} \ No newline at end of file diff --git a/_extension/src/client.ts b/_extension/src/client.ts index a9a9028945..6b382fe896 100644 --- a/_extension/src/client.ts +++ b/_extension/src/client.ts @@ -17,6 +17,8 @@ import { } from "./util"; import { getLanguageForUri } from "./util"; +const codeLensShowLocationsCommandName = "typescript.native-preview.codeLens.showLocations"; + export class Client { private outputChannel: vscode.OutputChannel; private traceOutputChannel: vscode.OutputChannel; @@ -35,6 +37,9 @@ export class Client { ], outputChannel: this.outputChannel, traceOutputChannel: this.traceOutputChannel, + initializationOptions: { + codeLensShowLocationsCommandName, + }, diagnosticPullOptions: { onChange: true, onSave: true, @@ -123,7 +128,7 @@ export class Client { vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", true); this.onStartedCallbacks.forEach(callback => callback()); - const codeLensLocationsCommand = vscode.commands.registerCommand("typescript.codeLens.showLocations", (...args: unknown[]) => { + const codeLensLocationsCommand = vscode.commands.registerCommand(codeLensShowLocationsCommandName, (...args: unknown[]) => { if (args.length !== 3) { throw new Error("Unexpected number of arguments."); } @@ -131,17 +136,19 @@ export class Client { const lspUri = args[0] as DocumentUri; const lspPosition = args[1] as Position; const lspLocations = args[2] as Location[]; - + const editorUri = vscode.Uri.parse(lspUri); const editorPosition = new vscode.Position(lspPosition.line, lspPosition.character); - const editorLocations = lspLocations.map(loc => new vscode.Location( - vscode.Uri.parse(loc.uri), - new vscode.Range( - new vscode.Position(loc.range.start.line, loc.range.start.character), - new vscode.Position(loc.range.end.line, loc.range.end.character), - ), - )); - + const editorLocations = lspLocations.map(loc => + new vscode.Location( + vscode.Uri.parse(loc.uri), + new vscode.Range( + new vscode.Position(loc.range.start.line, loc.range.start.character), + new vscode.Position(loc.range.end.line, loc.range.end.character), + ), + ) + ); + vscode.commands.executeCommand("editor.action.showReferences", editorUri, editorPosition, editorLocations); }); diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index 74864be061..e0374e910f 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -45,7 +45,7 @@ func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsp }, nil } -func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto.CodeLens) (*lsproto.CodeLens, error) { +func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto.CodeLens, showLocationsCommandName *string) (*lsproto.CodeLens, error) { uri := codeLens.Data.Uri textDoc := lsproto.TextDocumentIdentifier{ Uri: uri, @@ -105,8 +105,8 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto cmd := &lsproto.Command{ Title: lensTitle, } - if len(locs) > 0 { - cmd.Command = "typescript.codeLens.showLocations" + if len(locs) > 0 && showLocationsCommandName != nil { + cmd.Command = *showLocationsCommandName cmd.Arguments = &[]any{ uri, codeLens.Range.Start, diff --git a/internal/lsp/lsproto/_generate/generate.mts b/internal/lsp/lsproto/_generate/generate.mts index 5f4d366fa2..6af721e5e2 100644 --- a/internal/lsp/lsproto/_generate/generate.mts +++ b/internal/lsp/lsproto/_generate/generate.mts @@ -41,6 +41,12 @@ const customStructures: Structure[] = [ optional: true, documentation: "DisablePushDiagnostics disables automatic pushing of diagnostics to the client.", }, + { + name: "codeLensShowLocationsCommandName", + type: { kind: "base", name: "string" }, + optional: true, + documentation: "The client-side command name that resolved references/implementations `CodeLens` should trigger. Arguments passed will be `(DocumentUri, Position, Location[])`.", + }, ], documentation: "InitializationOptions contains user-provided initialization options.", }, diff --git a/internal/lsp/lsproto/lsp_generated.go b/internal/lsp/lsproto/lsp_generated.go index e5b3f0eb99..5358df307a 100644 --- a/internal/lsp/lsproto/lsp_generated.go +++ b/internal/lsp/lsproto/lsp_generated.go @@ -21523,6 +21523,9 @@ type ClientSemanticTokensRequestFullDelta struct { type InitializationOptions struct { // DisablePushDiagnostics disables automatic pushing of diagnostics to the client. DisablePushDiagnostics *bool `json:"disablePushDiagnostics,omitzero"` + + // The client-side command name that resolved references/implementations `CodeLens` should trigger. Arguments passed will be `(DocumentUri, Position, Location[])`. + CodeLensShowLocationsCommandName *string `json:"codeLensShowLocationsCommandName,omitzero"` } // ExportInfoMapKey uniquely identifies an export for auto-import purposes. diff --git a/internal/lsp/server.go b/internal/lsp/server.go index c8b1055618..99dfc63b7e 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -987,7 +987,7 @@ func (s *Server) handleCodeLensResolve(ctx context.Context, codeLens *lsproto.Co } defer s.recover(reqMsg) - return ls.ResolveCodeLens(ctx, codeLens) + return ls.ResolveCodeLens(ctx, codeLens, s.initializeParams.InitializationOptions.CodeLensShowLocationsCommandName) } func (s *Server) Log(msg ...any) { From f3cc278eaff0c87f29f58c8f1ee76c298ac8c398 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 24 Nov 2025 21:51:33 +0000 Subject: [PATCH 08/46] Adapt code to changes from merge. --- internal/ls/codelens.go | 48 +++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index e0374e910f..242f142441 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -55,20 +55,28 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto var lensTitle string switch codeLens.Data.Kind { case lsproto.CodeLensKindReferences: - references, err := l.ProvideReferences(ctx, &lsproto.ReferenceParams{ - TextDocument: textDoc, - Position: codeLens.Range.Start, - Context: &lsproto.ReferenceContext{ - // Don't include the declaration in the references count. - IncludeDeclaration: false, - }, - }) - if err != nil { - return nil, err - } - - if references.Locations != nil { - locs = *references.Locations + origNode, symbolsAndEntries, ok := l.ProvideSymbolsAndEntries(ctx, uri, codeLens.Range.Start, false /*isRename*/) + if ok { + references, err := l.ProvideReferencesFromSymbolAndEntries( + ctx, + &lsproto.ReferenceParams{ + TextDocument: textDoc, + Position: codeLens.Range.Start, + Context: &lsproto.ReferenceContext{ + // Don't include the declaration in the references count. + IncludeDeclaration: false, + }, + }, + origNode, + symbolsAndEntries, + ) + if err != nil { + return nil, err + } + + if references.Locations != nil { + locs = *references.Locations + } } if len(locs) == 1 { @@ -83,10 +91,14 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto requireLocationsResult: true, dropOriginNodes: true, } - implementations, err := l.provideImplementationsEx(ctx, &lsproto.ImplementationParams{ - TextDocument: textDoc, - Position: codeLens.Range.Start, - }, findImplsOptions) + implementations, err := l.provideImplementationsEx( + ctx, + &lsproto.ImplementationParams{ + TextDocument: textDoc, + Position: codeLens.Range.Start, + }, + findImplsOptions, + ) if err != nil { return nil, err } From 034993555ba1c6f365267de35582a574a04231ad Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 24 Nov 2025 21:55:33 +0000 Subject: [PATCH 09/46] Accept baselines. --- .../fourslash/state/declarationMapsFindAllRefs.baseline | 2 +- .../declarationMapsFindAllRefsDefinitionInMappedFile.baseline | 2 +- .../declarationMapsFindAllRefsStartingAtDefinition.baseline | 2 +- .../declarationMapsFindAllRefsTargetDoesNotExist.baseline | 2 +- .../declarationMapsOpeningOriginalLocationProject.baseline | 2 +- ...ionProjectDisableSourceOfProjectReferenceRedirect.baseline | 2 +- .../state/findAllRefsAncestorSiblingProjectsLoading.baseline | 4 ++-- ...torSiblingProjectsLoadingDisableSolutionSearching.baseline | 4 ++-- ...sabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline | 2 +- ...sabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline | 2 +- ...isabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline | 2 +- ...isabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline | 2 +- ...nabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline | 2 +- ...nabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline | 2 +- ...EnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline | 2 +- ...EnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline | 2 +- ...sabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline | 2 +- ...sabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline | 2 +- ...isabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline | 2 +- ...isabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline | 2 +- ...nabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline | 2 +- ...nabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline | 2 +- ...EnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline | 2 +- ...EnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline | 2 +- ...oSearchProjectAfterItsUpdateDoesNotIncludeTheFile.baseline | 2 +- ...lRefsOpenFileInConfiguredProjectThatWillBeRemoved.baseline | 2 +- .../fourslash/state/findAllRefsOverlappingProjects.baseline | 4 ++-- ...tWithOwnFilesReferencingFileFromReferencedProject.baseline | 4 ++-- .../state/findAllRefsRootOfReferencedProject.baseline | 2 +- ...findAllRefsRootOfReferencedProjectDeclarationMaps.baseline | 2 +- ...dAllRefsSolutionReferencingDefaultProjectDirectly.baseline | 4 ++-- ...llRefsSolutionReferencingDefaultProjectIndirectly.baseline | 4 ++-- ...jectIndirectlyThroughDisableReferencedProjectLoad.baseline | 4 ++-- ...leReferencedProjectLoadInOneButWithoutItInAnother.baseline | 4 ++-- ...encedProjectLoadReferencingDefaultProjectDirectly.baseline | 4 ++-- ...ngOfLocalnessArrowFunctionAsObjectLiteralProperty.baseline | 2 +- ...ocalnessArrowFunctionAsObjectLiteralPropertyTypes.baseline | 2 +- ...SpecialHandlingOfLocalnessArrowFunctionAssignment.baseline | 2 +- ...SpecialHandlingOfLocalnessMethodOfClassExpression.baseline | 2 +- ...fsSpecialHandlingOfLocalnessObjectLiteralProperty.baseline | 2 +- ...findAllRefsTwoProjectsOpenAndOneProjectReferences.baseline | 2 +- 41 files changed, 50 insertions(+), 50 deletions(-) diff --git a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefs.baseline b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefs.baseline index 3403e09e0b..1b14590dcc 100644 --- a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefs.baseline +++ b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefs.baseline @@ -91,7 +91,7 @@ Config File Names:: "character": 29 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsDefinitionInMappedFile.baseline b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsDefinitionInMappedFile.baseline index 86588d5549..46a15f07a1 100644 --- a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsDefinitionInMappedFile.baseline +++ b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsDefinitionInMappedFile.baseline @@ -75,7 +75,7 @@ Config File Names:: "character": 0 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsStartingAtDefinition.baseline b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsStartingAtDefinition.baseline index e11f907aeb..146f249b7f 100644 --- a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsStartingAtDefinition.baseline +++ b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsStartingAtDefinition.baseline @@ -129,7 +129,7 @@ Config File Names:: "character": 16 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsTargetDoesNotExist.baseline b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsTargetDoesNotExist.baseline index c07f940327..07171af38b 100644 --- a/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsTargetDoesNotExist.baseline +++ b/testdata/baselines/reference/fourslash/state/declarationMapsFindAllRefsTargetDoesNotExist.baseline @@ -91,7 +91,7 @@ Config File Names:: "character": 38 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProject.baseline b/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProject.baseline index 19bddaea89..dab19dd2d9 100644 --- a/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProject.baseline +++ b/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProject.baseline @@ -73,7 +73,7 @@ Config File Names:: "character": 4 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProjectDisableSourceOfProjectReferenceRedirect.baseline b/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProjectDisableSourceOfProjectReferenceRedirect.baseline index fa57e3f9aa..7bea29dfe6 100644 --- a/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProjectDisableSourceOfProjectReferenceRedirect.baseline +++ b/testdata/baselines/reference/fourslash/state/declarationMapsOpeningOriginalLocationProjectDisableSourceOfProjectReferenceRedirect.baseline @@ -73,7 +73,7 @@ Config File Names:: "character": 4 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoading.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoading.baseline index ec8c01300b..495562c581 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoading.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoading.baseline @@ -91,7 +91,7 @@ Config File Names:: "character": 25 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -118,7 +118,7 @@ Config File Names:: "character": 2 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoadingDisableSolutionSearching.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoadingDisableSolutionSearching.baseline index e544f1b7eb..fe379c37dc 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoadingDisableSolutionSearching.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsAncestorSiblingProjectsLoadingDisableSolutionSearching.baseline @@ -87,7 +87,7 @@ Config File Names:: "character": 25 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -114,7 +114,7 @@ Config File Names:: "character": 2 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline index d650756384..f8e6887b3f 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline @@ -110,7 +110,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline index 26e0d60718..deff2e52f3 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline @@ -119,7 +119,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline index 26e216f15e..0792eae63f 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline @@ -110,7 +110,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline index 34ead087ea..92d0083b8e 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline @@ -119,7 +119,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline index 744a08f01c..b7c5655862 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline @@ -110,7 +110,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline index a84a5fd038..486127f0d9 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline @@ -119,7 +119,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline index b9b50f45dc..91f7b2f7dd 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline @@ -110,7 +110,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline index 8f986664fd..1e0455ffa4 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline @@ -119,7 +119,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline index 23659d8d85..fbf99a5940 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline @@ -68,7 +68,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline index 46b5b8d577..c88b86be0c 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline @@ -77,7 +77,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline index bf66bd9fe5..04c077884c 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline @@ -68,7 +68,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline index b7fcab8376..387d2817ab 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsDisabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline @@ -77,7 +77,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline index e75c517c0a..10f5deff34 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsMissing.baseline @@ -68,7 +68,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline index d98007bb4b..b20b88cacd 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreDisabledDeclMapIsPresent.baseline @@ -77,7 +77,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline index fd2ef7802c..634f5d5ab0 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsMissing.baseline @@ -68,7 +68,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline index 455c0744bc..be1499ba2e 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDeclarationInOtherProjectProjIsNotLoadedRefdProjLoadingIsEnabledProjRefRedirectsAreEnabledDeclMapIsPresent.baseline @@ -77,7 +77,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsDoesNotTryToSearchProjectAfterItsUpdateDoesNotIncludeTheFile.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsDoesNotTryToSearchProjectAfterItsUpdateDoesNotIncludeTheFile.baseline index 109e42807c..1cf21205b1 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsDoesNotTryToSearchProjectAfterItsUpdateDoesNotIncludeTheFile.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsDoesNotTryToSearchProjectAfterItsUpdateDoesNotIncludeTheFile.baseline @@ -412,7 +412,7 @@ Config File Names:: "character": 1 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsOpenFileInConfiguredProjectThatWillBeRemoved.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsOpenFileInConfiguredProjectThatWillBeRemoved.baseline index 176a89c9d9..e051740ac2 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsOpenFileInConfiguredProjectThatWillBeRemoved.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsOpenFileInConfiguredProjectThatWillBeRemoved.baseline @@ -108,7 +108,7 @@ Config File Names:: "character": 16 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsOverlappingProjects.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsOverlappingProjects.baseline index 4707f0a907..658e491242 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsOverlappingProjects.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsOverlappingProjects.baseline @@ -114,7 +114,7 @@ Config File Names:: "character": 26 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -205,7 +205,7 @@ Config:: "character": 26 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsProjectWithOwnFilesReferencingFileFromReferencedProject.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsProjectWithOwnFilesReferencingFileFromReferencedProject.baseline index aaf116174f..22558923b8 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsProjectWithOwnFilesReferencingFileFromReferencedProject.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsProjectWithOwnFilesReferencingFileFromReferencedProject.baseline @@ -387,7 +387,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -465,7 +465,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProject.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProject.baseline index d98432e861..e09956e1dc 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProject.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProject.baseline @@ -137,7 +137,7 @@ Config File Names:: "character": 16 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProjectDeclarationMaps.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProjectDeclarationMaps.baseline index 1c5b3a7160..8d8dd028ab 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProjectDeclarationMaps.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsRootOfReferencedProjectDeclarationMaps.baseline @@ -342,7 +342,7 @@ Config File Names:: "character": 16 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectDirectly.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectDirectly.baseline index 9c58b15719..ba44b28478 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectDirectly.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectDirectly.baseline @@ -331,7 +331,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -405,7 +405,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectly.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectly.baseline index 5eaa2c7552..43a1190dc9 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectly.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectly.baseline @@ -504,7 +504,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -580,7 +580,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoad.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoad.baseline index 5a6e45d798..3b8eae0e67 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoad.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoad.baseline @@ -490,7 +490,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -565,7 +565,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoadInOneButWithoutItInAnother.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoadInOneButWithoutItInAnother.baseline index 2f2df123c2..19287e15a1 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoadInOneButWithoutItInAnother.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionReferencingDefaultProjectIndirectlyThroughDisableReferencedProjectLoadInOneButWithoutItInAnother.baseline @@ -505,7 +505,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -581,7 +581,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionWithDisableReferencedProjectLoadReferencingDefaultProjectDirectly.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionWithDisableReferencedProjectLoadReferencingDefaultProjectDirectly.baseline index 42f55d9673..4900d5c940 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSolutionWithDisableReferencedProjectLoadReferencingDefaultProjectDirectly.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSolutionWithDisableReferencedProjectLoadReferencingDefaultProjectDirectly.baseline @@ -318,7 +318,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } @@ -391,7 +391,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralProperty.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralProperty.baseline index 91a1f25a3a..323d02cd99 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralProperty.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralProperty.baseline @@ -94,7 +94,7 @@ Config File Names:: "character": 11 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralPropertyTypes.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralPropertyTypes.baseline index 950d470291..8060e5b002 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralPropertyTypes.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAsObjectLiteralPropertyTypes.baseline @@ -93,7 +93,7 @@ Config File Names:: "character": 11 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAssignment.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAssignment.baseline index 79d114c2db..5b71886470 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAssignment.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessArrowFunctionAssignment.baseline @@ -93,7 +93,7 @@ Config File Names:: "character": 7 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessMethodOfClassExpression.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessMethodOfClassExpression.baseline index ea029f1196..93e19e4982 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessMethodOfClassExpression.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessMethodOfClassExpression.baseline @@ -95,7 +95,7 @@ Config File Names:: "character": 9 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessObjectLiteralProperty.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessObjectLiteralProperty.baseline index 00d57bb417..2b1d25aaa1 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessObjectLiteralProperty.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsSpecialHandlingOfLocalnessObjectLiteralProperty.baseline @@ -93,7 +93,7 @@ Config File Names:: "character": 11 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } diff --git a/testdata/baselines/reference/fourslash/state/findAllRefsTwoProjectsOpenAndOneProjectReferences.baseline b/testdata/baselines/reference/fourslash/state/findAllRefsTwoProjectsOpenAndOneProjectReferences.baseline index d1dde71935..78d043b553 100644 --- a/testdata/baselines/reference/fourslash/state/findAllRefsTwoProjectsOpenAndOneProjectReferences.baseline +++ b/testdata/baselines/reference/fourslash/state/findAllRefsTwoProjectsOpenAndOneProjectReferences.baseline @@ -280,7 +280,7 @@ Config File Names:: "character": 13 }, "context": { - "includeDeclaration": false + "includeDeclaration": true } } } From ed72b96e819c74d6a3aa52e4d849b043a9ae666b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 01:26:31 +0000 Subject: [PATCH 10/46] Add testing for Code Lens (`VerifyBaselineCodeLensForActiveFile`). --- internal/fourslash/baselineutil.go | 1 + internal/fourslash/fourslash.go | 55 ++++++++++++++++- .../codeLensFunctionsAndConstants01_test.go | 50 ++++++++++++++++ .../tests/codeLensInterface01_test.go | 59 +++++++++++++++++++ 4 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go create mode 100644 internal/fourslash/tests/codeLensInterface01_test.go diff --git a/internal/fourslash/baselineutil.go b/internal/fourslash/baselineutil.go index 051b97a9ee..00320678e2 100644 --- a/internal/fourslash/baselineutil.go +++ b/internal/fourslash/baselineutil.go @@ -33,6 +33,7 @@ const ( renameCmd baselineCommand = "findRenameLocations" signatureHelpCmd baselineCommand = "SignatureHelp" smartSelectionCmd baselineCommand = "Smart Selection" + codeLensesCmd baselineCommand = "Code Lenses" ) type baselineCommand string diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index fb15fd13e9..1c4fe24e85 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -276,13 +276,16 @@ func (f *FourslashTest) nextID() int32 { return id } +const showCodeLensLocationsCommandName = "typescript.showCodeLensLocations" + func (f *FourslashTest) initialize(t *testing.T, capabilities *lsproto.ClientCapabilities) { params := &lsproto.InitializeParams{ Locale: ptrTo("en-US"), InitializationOptions: &lsproto.InitializationOptions{ // Hack: disable push diagnostics entirely, since the fourslash runner does not // yet gracefully handle non-request messages. - DisablePushDiagnostics: ptrTo(true), + DisablePushDiagnostics: ptrTo(true), + CodeLensShowLocationsCommandName: ptrTo(showCodeLensLocationsCommandName), }, } params.Capabilities = getCapabilitiesWithDefaults(capabilities) @@ -1314,6 +1317,56 @@ func (f *FourslashTest) VerifyBaselineFindAllReferences( } } +func (f *FourslashTest) VerifyBaselineCodeLensForActiveFile(t *testing.T, preferences *lsutil.UserPreferences) { + if preferences != nil { + reset := f.ConfigureWithReset(t, preferences) + defer reset() + } + + params := &lsproto.CodeLensParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: lsconv.FileNameToDocumentURI(f.activeFilename), + }, + } + unresolvedCodeLensList := sendRequest(t, f, lsproto.TextDocumentCodeLensInfo, params) + + if unresolvedCodeLensList.CodeLenses == nil || len(*unresolvedCodeLensList.CodeLenses) == 0 { + t.Fatalf("Expected at least one code lens in file %s, but got none.", f.activeFilename) + } + + for _, unresolvedCodeLens := range *unresolvedCodeLensList.CodeLenses { + assert.Assert(t, unresolvedCodeLens != nil) + resolvedCodeLens := sendRequest(t, f, lsproto.CodeLensResolveInfo, unresolvedCodeLens) + assert.Assert(t, resolvedCodeLens != nil) + assert.Assert(t, resolvedCodeLens.Command != nil, "Expected resolved code lens to have a command.") + if len(resolvedCodeLens.Command.Command) > 0 { + assert.Equal(t, resolvedCodeLens.Command.Command, showCodeLensLocationsCommandName) + } + + var locations []lsproto.Location + // commandArgs: (DocumentUri, Position, Location[]) + if commandArgs := resolvedCodeLens.Command.Arguments; commandArgs != nil { + // TODO: inevitably this would fail if we were actually going over the wire + // since the type info will be lost in that `any`. + untypedLocs := (*commandArgs)[2] + if locs, ok := untypedLocs.([]lsproto.Location); ok { + locations = locs + } else { + t.Fatalf("Expected code lens command arguments to contain a list of locations, but got %T", untypedLocs) + } + } + + f.addResultToBaseline(t, codeLensesCmd, f.getBaselineForLocationsWithFileContents(locations, baselineFourslashLocationsOptions{ + marker: &RangeMarker{ + fileName: f.activeFilename, + LSRange: resolvedCodeLens.Range, + Range: f.converters.FromLSPRange(f.getScriptInfo(f.activeFilename), resolvedCodeLens.Range), + }, + markerName: "/*CODELENS: " + resolvedCodeLens.Command.Title + "*/", + })) + } +} + func (f *FourslashTest) MarkTestAsStradaServer() { f.isStradaServer = true } diff --git a/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go b/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go new file mode 100644 index 0000000000..c57442de56 --- /dev/null +++ b/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go @@ -0,0 +1,50 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCodeLensFunctionsAndConstants01(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +// @module: preserve + +// @filename: ./exports.ts + +let callCount = 0; +export function foo(n: number): void { + callCount++; + if (n > 0) { + foo(n - 1); + } + else { + console.log("function was called " + callCount + " times"); + } +} + +foo(5); + +export const bar = 123; + +// @filename: ./importer.ts +import { foo, bar } from "./exports"; + +foo(5); +console.log(bar); +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLensForActiveFile(t, &lsutil.UserPreferences{ + ReferencesCodeLensEnabled: true, + ReferencesCodeLensShowOnAllFunctions: true, + + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnInterfaceMethods: true, + ImplementationsCodeLensShowOnAllClassMethods: true, + }) +} diff --git a/internal/fourslash/tests/codeLensInterface01_test.go b/internal/fourslash/tests/codeLensInterface01_test.go new file mode 100644 index 0000000000..de6e4a83da --- /dev/null +++ b/internal/fourslash/tests/codeLensInterface01_test.go @@ -0,0 +1,59 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCodeLensInterface01(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +// @module: preserve + +// @filename: ./pointable.ts +export interface Pointable { + getX(): number; + getY(): number; +} + +// @filename: ./classPointable.ts +import { Pointable } from "./pointable"; + +class Point implements Pointable { + getX(): number { + return 0; + } + getY(): number { + return 0; + } +} + +// @filename: ./objectPointable.ts +import { Pointable } from "./pointable"; + +let x = 0; +let y = 0; +const p: Pointable = { + getX(): number { + return x; + }, + getY(): number { + return y; + }, +}; +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLensForActiveFile(t, &lsutil.UserPreferences{ + ReferencesCodeLensEnabled: true, + ReferencesCodeLensShowOnAllFunctions: true, + + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnInterfaceMethods: true, + ImplementationsCodeLensShowOnAllClassMethods: true, + }) +} From 5e9aca3ae233826c4ca0b7628e6abdfcd2319102 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 01:26:38 +0000 Subject: [PATCH 11/46] Update baselines. --- ...LensFunctionsAndConstants01.baseline.jsonc | 42 +++++ .../codeLensInterface01.baseline.jsonc | 153 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsAndConstants01.baseline.jsonc create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsAndConstants01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsAndConstants01.baseline.jsonc new file mode 100644 index 0000000000..5c306865e3 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsAndConstants01.baseline.jsonc @@ -0,0 +1,42 @@ +// === Code Lenses === +// === /exports.ts === +// let callCount = 0; +// export function /*CODELENS: 3 references*/foo(n: number): void { +// callCount++; +// if (n > 0) { +// [|foo|](n - 1); +// } +// else { +// console.log("function was called " + callCount + " times"); +// } +// } +// +// [|foo|](5); +// +// export const bar = 123; +// + +// === /importer.ts === +// import { foo, bar } from "./exports"; +// +// [|foo|](5); +// console.log(bar); +// + + + +// === Code Lenses === +// === /importer.ts === +// import { foo, bar } from "./exports"; +// +// foo(5); +// console.log([|bar|]); +// + +// === /exports.ts === +// --- (line: 10) skipped --- +// +// foo(5); +// +// export const /*CODELENS: 1 reference*/bar = 123; +// \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc new file mode 100644 index 0000000000..9d267b1af6 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc @@ -0,0 +1,153 @@ +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class Point implements [|Pointable|] { +// getX(): number { +// return 0; +// } +// --- (line: 7) skipped --- + +// === /objectPointable.ts === +// import { Pointable } from "./pointable"; +// +// let x = 0; +// let y = 0; +// const p: [|Pointable|] = { +// getX(): number { +// return x; +// }, +// --- (line: 9) skipped --- + +// === /pointable.ts === +// export interface /*CODELENS: 2 references*/Pointable { +// getX(): number; +// getY(): number; +// } +// + + + +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class [|Point|] implements Pointable { +// getX(): number { +// return 0; +// } +// --- (line: 7) skipped --- + +// === /pointable.ts === +// export interface /*CODELENS: 1 implementation*/Pointable { +// getX(): number; +// getY(): number; +// } +// + + + +// === Code Lenses === +// === /objectPointable.ts === +// import { Pointable } from "./pointable"; +// +// let x = 0; +// let y = 0; +// const p: Pointable = { +// [|getX|](): number { +// return x; +// }, +// getY(): number { +// --- (line: 10) skipped --- + +// === /pointable.ts === +// export interface Pointable { +// /*CODELENS: 1 reference*/getX(): number; +// getY(): number; +// } +// + + + +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class Point implements Pointable { +// [|getX|](): number { +// return 0; +// } +// getY(): number { +// --- (line: 8) skipped --- + +// === /objectPointable.ts === +// import { Pointable } from "./pointable"; +// +// let x = 0; +// let y = 0; +// const p: Pointable = { +// [|getX|](): number { +// return x; +// }, +// getY(): number { +// --- (line: 10) skipped --- + +// === /pointable.ts === +// export interface Pointable { +// /*CODELENS: 2 implementations*/getX(): number; +// getY(): number; +// } +// + + + +// === Code Lenses === +// === /objectPointable.ts === +// --- (line: 5) skipped --- +// getX(): number { +// return x; +// }, +// [|getY|](): number { +// return y; +// }, +// }; +// + +// === /pointable.ts === +// export interface Pointable { +// getX(): number; +// /*CODELENS: 1 reference*/getY(): number; +// } +// + + + +// === Code Lenses === +// === /classPointable.ts === +// --- (line: 3) skipped --- +// getX(): number { +// return 0; +// } +// [|getY|](): number { +// return 0; +// } +// } +// + +// === /objectPointable.ts === +// --- (line: 5) skipped --- +// getX(): number { +// return x; +// }, +// [|getY|](): number { +// return y; +// }, +// }; +// + +// === /pointable.ts === +// export interface Pointable { +// getX(): number; +// /*CODELENS: 2 implementations*/getY(): number; +// } +// \ No newline at end of file From 5e32b670d0ccaf01cf6088ae90c34208b6ee938e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 01:44:04 +0000 Subject: [PATCH 12/46] Request codelenses across all files. --- internal/fourslash/fourslash.go | 80 ++++++++++--------- .../codeLensFunctionsAndConstants01_test.go | 2 +- .../tests/codeLensInterface01_test.go | 2 +- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index 1c4fe24e85..0451724b27 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1317,53 +1317,61 @@ func (f *FourslashTest) VerifyBaselineFindAllReferences( } } -func (f *FourslashTest) VerifyBaselineCodeLensForActiveFile(t *testing.T, preferences *lsutil.UserPreferences) { +func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil.UserPreferences) { if preferences != nil { reset := f.ConfigureWithReset(t, preferences) defer reset() } - params := &lsproto.CodeLensParams{ - TextDocument: lsproto.TextDocumentIdentifier{ - Uri: lsconv.FileNameToDocumentURI(f.activeFilename), - }, - } - unresolvedCodeLensList := sendRequest(t, f, lsproto.TextDocumentCodeLensInfo, params) - - if unresolvedCodeLensList.CodeLenses == nil || len(*unresolvedCodeLensList.CodeLenses) == 0 { - t.Fatalf("Expected at least one code lens in file %s, but got none.", f.activeFilename) - } + foundAtLeastOneCodeLens := false + for openFile := range f.openFiles { + params := &lsproto.CodeLensParams{ + TextDocument: lsproto.TextDocumentIdentifier{ + Uri: lsconv.FileNameToDocumentURI(openFile), + }, + } - for _, unresolvedCodeLens := range *unresolvedCodeLensList.CodeLenses { - assert.Assert(t, unresolvedCodeLens != nil) - resolvedCodeLens := sendRequest(t, f, lsproto.CodeLensResolveInfo, unresolvedCodeLens) - assert.Assert(t, resolvedCodeLens != nil) - assert.Assert(t, resolvedCodeLens.Command != nil, "Expected resolved code lens to have a command.") - if len(resolvedCodeLens.Command.Command) > 0 { - assert.Equal(t, resolvedCodeLens.Command.Command, showCodeLensLocationsCommandName) + unresolvedCodeLensList := sendRequest(t, f, lsproto.TextDocumentCodeLensInfo, params) + if unresolvedCodeLensList.CodeLenses == nil || len(*unresolvedCodeLensList.CodeLenses) == 0 { + continue } + foundAtLeastOneCodeLens = true - var locations []lsproto.Location - // commandArgs: (DocumentUri, Position, Location[]) - if commandArgs := resolvedCodeLens.Command.Arguments; commandArgs != nil { - // TODO: inevitably this would fail if we were actually going over the wire - // since the type info will be lost in that `any`. - untypedLocs := (*commandArgs)[2] - if locs, ok := untypedLocs.([]lsproto.Location); ok { - locations = locs - } else { - t.Fatalf("Expected code lens command arguments to contain a list of locations, but got %T", untypedLocs) + for _, unresolvedCodeLens := range *unresolvedCodeLensList.CodeLenses { + assert.Assert(t, unresolvedCodeLens != nil) + resolvedCodeLens := sendRequest(t, f, lsproto.CodeLensResolveInfo, unresolvedCodeLens) + assert.Assert(t, resolvedCodeLens != nil) + assert.Assert(t, resolvedCodeLens.Command != nil, "Expected resolved code lens to have a command.") + if len(resolvedCodeLens.Command.Command) > 0 { + assert.Equal(t, resolvedCodeLens.Command.Command, showCodeLensLocationsCommandName) + } + + var locations []lsproto.Location + // commandArgs: (DocumentUri, Position, Location[]) + if commandArgs := resolvedCodeLens.Command.Arguments; commandArgs != nil { + // TODO: inevitably this would fail if we were actually going over the wire + // since the type info will be lost in that `any`. + untypedLocs := (*commandArgs)[2] + if locs, ok := untypedLocs.([]lsproto.Location); ok { + locations = locs + } else { + t.Fatalf("Expected code lens command arguments to contain a list of locations, but got %T", untypedLocs) + } } + + f.addResultToBaseline(t, codeLensesCmd, f.getBaselineForLocationsWithFileContents(locations, baselineFourslashLocationsOptions{ + marker: &RangeMarker{ + fileName: openFile, + LSRange: resolvedCodeLens.Range, + Range: f.converters.FromLSPRange(f.getScriptInfo(openFile), resolvedCodeLens.Range), + }, + markerName: "/*CODELENS: " + resolvedCodeLens.Command.Title + "*/", + })) } + } - f.addResultToBaseline(t, codeLensesCmd, f.getBaselineForLocationsWithFileContents(locations, baselineFourslashLocationsOptions{ - marker: &RangeMarker{ - fileName: f.activeFilename, - LSRange: resolvedCodeLens.Range, - Range: f.converters.FromLSPRange(f.getScriptInfo(f.activeFilename), resolvedCodeLens.Range), - }, - markerName: "/*CODELENS: " + resolvedCodeLens.Command.Title + "*/", - })) + if !foundAtLeastOneCodeLens { + t.Fatalf("Expected at least one code lens in any open file, but got none.") } } diff --git a/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go b/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go index c57442de56..bad700760e 100644 --- a/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go +++ b/internal/fourslash/tests/codeLensFunctionsAndConstants01_test.go @@ -39,7 +39,7 @@ foo(5); console.log(bar); ` f := fourslash.NewFourslash(t, nil /*capabilities*/, content) - f.VerifyBaselineCodeLensForActiveFile(t, &lsutil.UserPreferences{ + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ ReferencesCodeLensEnabled: true, ReferencesCodeLensShowOnAllFunctions: true, diff --git a/internal/fourslash/tests/codeLensInterface01_test.go b/internal/fourslash/tests/codeLensInterface01_test.go index de6e4a83da..a1e9a42368 100644 --- a/internal/fourslash/tests/codeLensInterface01_test.go +++ b/internal/fourslash/tests/codeLensInterface01_test.go @@ -48,7 +48,7 @@ const p: Pointable = { }; ` f := fourslash.NewFourslash(t, nil /*capabilities*/, content) - f.VerifyBaselineCodeLensForActiveFile(t, &lsutil.UserPreferences{ + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ ReferencesCodeLensEnabled: true, ReferencesCodeLensShowOnAllFunctions: true, From c6ee5d86a7a43edb80c01ed3d67f9e237c6cb099 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 01:44:10 +0000 Subject: [PATCH 13/46] Update baselines. --- .../codeLensInterface01.baseline.jsonc | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc index 9d267b1af6..e0d652c25b 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc @@ -150,4 +150,93 @@ // getX(): number; // /*CODELENS: 2 implementations*/getY(): number; // } +// + + + +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class /*CODELENS: 0 references*/Point implements Pointable { +// getX(): number { +// return 0; +// } +// --- (line: 7) skipped --- + + + +// === Code Lenses === +// === /objectPointable.ts === +// import { Pointable } from "./pointable"; +// +// let x = 0; +// let y = 0; +// const p: Pointable = { +// [|getX|](): number { +// return x; +// }, +// getY(): number { +// --- (line: 10) skipped --- + +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class Point implements Pointable { +// /*CODELENS: 1 reference*/getX(): number { +// return 0; +// } +// getY(): number { +// --- (line: 8) skipped --- + + + +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class Point implements Pointable { +// /*CODELENS: 0 implementations*/getX(): number { +// return 0; +// } +// getY(): number { +// --- (line: 8) skipped --- + + + +// === Code Lenses === +// === /objectPointable.ts === +// --- (line: 5) skipped --- +// getX(): number { +// return x; +// }, +// [|getY|](): number { +// return y; +// }, +// }; +// + +// === /classPointable.ts === +// --- (line: 3) skipped --- +// getX(): number { +// return 0; +// } +// /*CODELENS: 1 reference*/getY(): number { +// return 0; +// } +// } +// + + + +// === Code Lenses === +// === /classPointable.ts === +// --- (line: 3) skipped --- +// getX(): number { +// return 0; +// } +// /*CODELENS: 0 implementations*/getY(): number { +// return 0; +// } +// } // \ No newline at end of file From 56255397e716b4d156d06d5489eaccccd384a82a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 01:57:13 +0000 Subject: [PATCH 14/46] Localize titles for lenses. --- internal/ls/codelens.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index 242f142441..f065410bff 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -6,6 +6,7 @@ import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/core" "github.com/microsoft/typescript-go/internal/diagnostics" + "github.com/microsoft/typescript-go/internal/locale" "github.com/microsoft/typescript-go/internal/ls/lsutil" "github.com/microsoft/typescript-go/internal/lsp/lsproto" "github.com/microsoft/typescript-go/internal/scanner" @@ -50,6 +51,7 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto textDoc := lsproto.TextDocumentIdentifier{ Uri: uri, } + locale := locale.FromContext(ctx) var locs []lsproto.Location var lensTitle string @@ -80,9 +82,9 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto } if len(locs) == 1 { - lensTitle = diagnostics.X_1_reference.Message() + lensTitle = diagnostics.X_1_reference.Localize(locale) } else { - lensTitle = diagnostics.X_0_references.Format(len(locs)) + lensTitle = diagnostics.X_0_references.Localize(locale, len(locs)) } case lsproto.CodeLensKindImplementations: // "Force" link support to be false so that we only get `Locations` back, @@ -108,9 +110,9 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto } if len(locs) == 1 { - lensTitle = diagnostics.X_1_implementation.Message() + lensTitle = diagnostics.X_1_implementation.Localize(locale) } else { - lensTitle = diagnostics.X_0_implementations.Format(len(locs)) + lensTitle = diagnostics.X_0_implementations.Localize(locale, len(locs)) } } From 494b5f7aa87c99dea77a705619f403f5b631ddbf Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 05:43:04 +0000 Subject: [PATCH 15/46] Format. --- _extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_extension/package.json b/_extension/package.json index 2e92d16498..5d844f3d54 100644 --- a/_extension/package.json +++ b/_extension/package.json @@ -126,4 +126,4 @@ "@vscode/vsce": "^3.7.0", "esbuild": "^0.27.0" } -} \ No newline at end of file +} From 42d5741bcd4d131572738bc11843aea9fa209346 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:08:39 +0000 Subject: [PATCH 16/46] Force ordering of file iteration. --- internal/fourslash/fourslash.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index fafbbda872..fa4204bb43 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1325,7 +1325,7 @@ func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil } foundAtLeastOneCodeLens := false - for openFile := range f.openFiles { + for _, openFile := range slices.Sorted(maps.Keys(f.openFiles)) { params := &lsproto.CodeLensParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(openFile), From 704cae6b368ebe90b6aa8fbd1ad704a1756c6314 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:08:48 +0000 Subject: [PATCH 17/46] Drive-by fix. --- internal/ls/completions.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/ls/completions.go b/internal/ls/completions.go index b74f0000e3..3459b3fb8f 100644 --- a/internal/ls/completions.go +++ b/internal/ls/completions.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "maps" "slices" "strings" "sync" @@ -1989,7 +1988,7 @@ func (l *LanguageService) getCompletionEntriesFromSymbols( } uniqueSet := collections.NewSetWithSizeHint[string](len(uniques)) - for name := range maps.Keys(uniques) { + for name := range uniques { uniqueSet.Add(name) } return *uniqueSet, sortedEntries From 188f9c77d187d33548be72fcbad8740378aa3609 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:09:47 +0000 Subject: [PATCH 18/46] Update baselines. --- .../codeLensInterface01.baseline.jsonc | 178 +++++++++--------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc index e0d652c25b..dc284d737a 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensInterface01.baseline.jsonc @@ -1,3 +1,92 @@ +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class /*CODELENS: 0 references*/Point implements Pointable { +// getX(): number { +// return 0; +// } +// --- (line: 7) skipped --- + + + +// === Code Lenses === +// === /objectPointable.ts === +// import { Pointable } from "./pointable"; +// +// let x = 0; +// let y = 0; +// const p: Pointable = { +// [|getX|](): number { +// return x; +// }, +// getY(): number { +// --- (line: 10) skipped --- + +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class Point implements Pointable { +// /*CODELENS: 1 reference*/getX(): number { +// return 0; +// } +// getY(): number { +// --- (line: 8) skipped --- + + + +// === Code Lenses === +// === /classPointable.ts === +// import { Pointable } from "./pointable"; +// +// class Point implements Pointable { +// /*CODELENS: 0 implementations*/getX(): number { +// return 0; +// } +// getY(): number { +// --- (line: 8) skipped --- + + + +// === Code Lenses === +// === /objectPointable.ts === +// --- (line: 5) skipped --- +// getX(): number { +// return x; +// }, +// [|getY|](): number { +// return y; +// }, +// }; +// + +// === /classPointable.ts === +// --- (line: 3) skipped --- +// getX(): number { +// return 0; +// } +// /*CODELENS: 1 reference*/getY(): number { +// return 0; +// } +// } +// + + + +// === Code Lenses === +// === /classPointable.ts === +// --- (line: 3) skipped --- +// getX(): number { +// return 0; +// } +// /*CODELENS: 0 implementations*/getY(): number { +// return 0; +// } +// } +// + + + // === Code Lenses === // === /classPointable.ts === // import { Pointable } from "./pointable"; @@ -150,93 +239,4 @@ // getX(): number; // /*CODELENS: 2 implementations*/getY(): number; // } -// - - - -// === Code Lenses === -// === /classPointable.ts === -// import { Pointable } from "./pointable"; -// -// class /*CODELENS: 0 references*/Point implements Pointable { -// getX(): number { -// return 0; -// } -// --- (line: 7) skipped --- - - - -// === Code Lenses === -// === /objectPointable.ts === -// import { Pointable } from "./pointable"; -// -// let x = 0; -// let y = 0; -// const p: Pointable = { -// [|getX|](): number { -// return x; -// }, -// getY(): number { -// --- (line: 10) skipped --- - -// === /classPointable.ts === -// import { Pointable } from "./pointable"; -// -// class Point implements Pointable { -// /*CODELENS: 1 reference*/getX(): number { -// return 0; -// } -// getY(): number { -// --- (line: 8) skipped --- - - - -// === Code Lenses === -// === /classPointable.ts === -// import { Pointable } from "./pointable"; -// -// class Point implements Pointable { -// /*CODELENS: 0 implementations*/getX(): number { -// return 0; -// } -// getY(): number { -// --- (line: 8) skipped --- - - - -// === Code Lenses === -// === /objectPointable.ts === -// --- (line: 5) skipped --- -// getX(): number { -// return x; -// }, -// [|getY|](): number { -// return y; -// }, -// }; -// - -// === /classPointable.ts === -// --- (line: 3) skipped --- -// getX(): number { -// return 0; -// } -// /*CODELENS: 1 reference*/getY(): number { -// return 0; -// } -// } -// - - - -// === Code Lenses === -// === /classPointable.ts === -// --- (line: 3) skipped --- -// getX(): number { -// return 0; -// } -// /*CODELENS: 0 implementations*/getY(): number { -// return 0; -// } -// } // \ No newline at end of file From c69f55a395d7cc86a7258957248329381fb6d44b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:15:20 +0000 Subject: [PATCH 19/46] Add test for overloads. --- .../tests/codeLensOverloads01_test.go | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 internal/fourslash/tests/codeLensOverloads01_test.go diff --git a/internal/fourslash/tests/codeLensOverloads01_test.go b/internal/fourslash/tests/codeLensOverloads01_test.go new file mode 100644 index 0000000000..02e863c30e --- /dev/null +++ b/internal/fourslash/tests/codeLensOverloads01_test.go @@ -0,0 +1,39 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCodeLensOverloads01(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +export function foo(x: number): number; +export function foo(x: string): string; +export function foo(x: string | number): string | number { + return x; +} + +foo(1); + +foo("hello"); + +// This one isn't expected to match any overload, +// but is really just here to test how it affects how code lens. +foo(Math.random() ? 1 : "hello"); +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ReferencesCodeLensEnabled: true, + ReferencesCodeLensShowOnAllFunctions: true, + + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnInterfaceMethods: true, + ImplementationsCodeLensShowOnAllClassMethods: true, + }) +} From a2d62fb0f1e0c4b0a1970dfac19a656090a62115 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:15:25 +0000 Subject: [PATCH 20/46] Update baselines. --- .../codeLensOverloads01.baseline.jsonc | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc new file mode 100644 index 0000000000..13b5200b36 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc @@ -0,0 +1,54 @@ +// === Code Lenses === +// === /codeLensOverloads01.ts === +// export function /*CODELENS: 3 references*/foo(x: number): number; +// export function foo(x: string): string; +// export function foo(x: string | number): string | number { +// return x; +// } +// +// [|foo|](1); +// +// [|foo|]("hello"); +// +// // This one isn't expected to match any overload, +// // but is really just here to test how it affects how code lens. +// [|foo|](Math.random() ? 1 : "hello"); +// + + + +// === Code Lenses === +// === /codeLensOverloads01.ts === +// export function foo(x: number): number; +// export function /*CODELENS: 3 references*/foo(x: string): string; +// export function foo(x: string | number): string | number { +// return x; +// } +// +// [|foo|](1); +// +// [|foo|]("hello"); +// +// // This one isn't expected to match any overload, +// // but is really just here to test how it affects how code lens. +// [|foo|](Math.random() ? 1 : "hello"); +// + + + +// === Code Lenses === +// === /codeLensOverloads01.ts === +// export function foo(x: number): number; +// export function foo(x: string): string; +// export function /*CODELENS: 3 references*/foo(x: string | number): string | number { +// return x; +// } +// +// [|foo|](1); +// +// [|foo|]("hello"); +// +// // This one isn't expected to match any overload, +// // but is really just here to test how it affects how code lens. +// [|foo|](Math.random() ? 1 : "hello"); +// \ No newline at end of file From 901d1995fa28f01c90a1926869c23b05bff1be83 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:37:06 +0000 Subject: [PATCH 21/46] Only print on the first-ish overload. --- internal/ls/codelens.go | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index f065410bff..7aaaa85b5b 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -20,29 +20,37 @@ func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsp return lsproto.CodeLensResponse{}, nil } - var lenses []*lsproto.CodeLens + // Keeps track of the last symbol to avoid duplicating code lenses across overloads. + var lastSymbol *ast.Symbol + var result []*lsproto.CodeLens var visit func(node *ast.Node) bool visit = func(node *ast.Node) bool { if ctx.Err() != nil { return true } - if userPrefs.ReferencesCodeLensEnabled && isValidReferenceLensNode(node, userPrefs) { - lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, lsproto.CodeLensKindReferences)) - } + if currentSymbol := node.Symbol(); lastSymbol != currentSymbol { + lastSymbol = currentSymbol + + if userPrefs.ReferencesCodeLensEnabled && isValidReferenceLensNode(node, userPrefs) { + result = append(result, l.newCodeLensForNode(documentURI, file, node, lsproto.CodeLensKindReferences)) + } - if userPrefs.ImplementationsCodeLensEnabled && isValidImplementationsCodeLensNode(node, userPrefs) { - lenses = append(lenses, l.newCodeLensForNode(documentURI, file, node, lsproto.CodeLensKindImplementations)) + if userPrefs.ImplementationsCodeLensEnabled && isValidImplementationsCodeLensNode(node, userPrefs) { + result = append(result, l.newCodeLensForNode(documentURI, file, node, lsproto.CodeLensKindImplementations)) + } } + savedLastSymbol := lastSymbol node.ForEachChild(visit) + lastSymbol = savedLastSymbol return false } visit(file.AsNode()) return lsproto.CodeLensResponse{ - CodeLenses: &lenses, + CodeLenses: &result, }, nil } From 5714e7a1b1b207d79fd306c2a6a5177fcc18b3a2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:37:15 +0000 Subject: [PATCH 22/46] Update baselines. --- .../codeLensOverloads01.baseline.jsonc | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc index 13b5200b36..f8163d73a4 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensOverloads01.baseline.jsonc @@ -13,42 +13,4 @@ // // This one isn't expected to match any overload, // // but is really just here to test how it affects how code lens. // [|foo|](Math.random() ? 1 : "hello"); -// - - - -// === Code Lenses === -// === /codeLensOverloads01.ts === -// export function foo(x: number): number; -// export function /*CODELENS: 3 references*/foo(x: string): string; -// export function foo(x: string | number): string | number { -// return x; -// } -// -// [|foo|](1); -// -// [|foo|]("hello"); -// -// // This one isn't expected to match any overload, -// // but is really just here to test how it affects how code lens. -// [|foo|](Math.random() ? 1 : "hello"); -// - - - -// === Code Lenses === -// === /codeLensOverloads01.ts === -// export function foo(x: number): number; -// export function foo(x: string): string; -// export function /*CODELENS: 3 references*/foo(x: string | number): string | number { -// return x; -// } -// -// [|foo|](1); -// -// [|foo|]("hello"); -// -// // This one isn't expected to match any overload, -// // but is really just here to test how it affects how code lens. -// [|foo|](Math.random() ? 1 : "hello"); // \ No newline at end of file From 3595713115a87bfc482a26ec05d89a254420540d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:53:06 +0000 Subject: [PATCH 23/46] Add codelens test for function expressions. --- .../codeLensFunctionExpressions01_test.go | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 internal/fourslash/tests/codeLensFunctionExpressions01_test.go diff --git a/internal/fourslash/tests/codeLensFunctionExpressions01_test.go b/internal/fourslash/tests/codeLensFunctionExpressions01_test.go new file mode 100644 index 0000000000..4ba6ebccfd --- /dev/null +++ b/internal/fourslash/tests/codeLensFunctionExpressions01_test.go @@ -0,0 +1,46 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCodeLensFunctionsExpressions01(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +// @filename: anonymousFunctionExpressions.ts +export let anonFn1 = function () {}; +export const anonFn2 = function () {}; + +let anonFn3 = function () {}; +const anonFn4 = function () {}; + +// @filename: arrowFunctions.ts +export let arrowFn1 = () => {}; +export const arrowFn2 = () => {}; + +let arrowFn3 = () => {}; +const arrowFn4 = () => {}; + +// @filename: namedFunctions.ts +export let namedFn1 = function namedFn1() {} +export const namedFn2 = function namedFn2() {} + +let namedFn3 = function namedFn3() {} +const namedFn4 = function namedFn4() {} +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ReferencesCodeLensEnabled: true, + ReferencesCodeLensShowOnAllFunctions: true, + + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnInterfaceMethods: true, + ImplementationsCodeLensShowOnAllClassMethods: true, + }) +} From 2f270fe622d81e611bd2ca59325ba408dc5777af Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:53:10 +0000 Subject: [PATCH 24/46] Update baselines. --- ...eLensFunctionsExpressions01.baseline.jsonc | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc new file mode 100644 index 0000000000..c5e9f7cb71 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc @@ -0,0 +1,151 @@ +// === Code Lenses === +// === /anonymousFunctionExpressions.ts === +// export let /*CODELENS: 0 references*/anonFn1 = function () {}; +// export const anonFn2 = function () {}; +// +// let anonFn3 = function () {}; +// const anonFn4 = function () {}; +// + + + +// === Code Lenses === +// === /anonymousFunctionExpressions.ts === +// export let anonFn1 = /*CODELENS: 0 references*/function () {}; +// export const anonFn2 = function () {}; +// +// let anonFn3 = function () {}; +// const anonFn4 = function () {}; +// + + + +// === Code Lenses === +// === /anonymousFunctionExpressions.ts === +// export let anonFn1 = function () {}; +// export const /*CODELENS: 0 references*/anonFn2 = function () {}; +// +// let anonFn3 = function () {}; +// const anonFn4 = function () {}; +// + + + +// === Code Lenses === +// === /anonymousFunctionExpressions.ts === +// export let anonFn1 = function () {}; +// export const anonFn2 = /*CODELENS: 0 references*/function () {}; +// +// let anonFn3 = function () {}; +// const anonFn4 = function () {}; +// + + + +// === Code Lenses === +// === /anonymousFunctionExpressions.ts === +// export let anonFn1 = function () {}; +// export const anonFn2 = function () {}; +// +// let anonFn3 = /*CODELENS: 0 references*/function () {}; +// const anonFn4 = function () {}; +// + + + +// === Code Lenses === +// === /anonymousFunctionExpressions.ts === +// export let anonFn1 = function () {}; +// export const anonFn2 = function () {}; +// +// let anonFn3 = function () {}; +// const anonFn4 = /*CODELENS: 0 references*/function () {}; +// + + + +// === Code Lenses === +// === /arrowFunctions.ts === +// export let /*CODELENS: 0 references*/arrowFn1 = () => {}; +// export const arrowFn2 = () => {}; +// +// let arrowFn3 = () => {}; +// const arrowFn4 = () => {}; +// + + + +// === Code Lenses === +// === /arrowFunctions.ts === +// export let arrowFn1 = () => {}; +// export const /*CODELENS: 0 references*/arrowFn2 = () => {}; +// +// let arrowFn3 = () => {}; +// const arrowFn4 = () => {}; +// + + + +// === Code Lenses === +// === /namedFunctions.ts === +// export let /*CODELENS: 0 references*/namedFn1 = function namedFn1() {} +// export const namedFn2 = function namedFn2() {} +// +// let namedFn3 = function namedFn3() {} +// const namedFn4 = function namedFn4() {} +// + + + +// === Code Lenses === +// === /namedFunctions.ts === +// export let namedFn1 = function /*CODELENS: 0 references*/namedFn1() {} +// export const namedFn2 = function namedFn2() {} +// +// let namedFn3 = function namedFn3() {} +// const namedFn4 = function namedFn4() {} +// + + + +// === Code Lenses === +// === /namedFunctions.ts === +// export let namedFn1 = function namedFn1() {} +// export const /*CODELENS: 0 references*/namedFn2 = function namedFn2() {} +// +// let namedFn3 = function namedFn3() {} +// const namedFn4 = function namedFn4() {} +// + + + +// === Code Lenses === +// === /namedFunctions.ts === +// export let namedFn1 = function namedFn1() {} +// export const namedFn2 = function /*CODELENS: 0 references*/namedFn2() {} +// +// let namedFn3 = function namedFn3() {} +// const namedFn4 = function namedFn4() {} +// + + + +// === Code Lenses === +// === /namedFunctions.ts === +// export let namedFn1 = function namedFn1() {} +// export const namedFn2 = function namedFn2() {} +// +// let namedFn3 = function /*CODELENS: 0 references*/namedFn3() {} +// const namedFn4 = function namedFn4() {} +// + + + +// === Code Lenses === +// === /namedFunctions.ts === +// export let namedFn1 = function namedFn1() {} +// export const namedFn2 = function namedFn2() {} +// +// let namedFn3 = function namedFn3() {} +// const namedFn4 = function /*CODELENS: 0 references*/namedFn4() {} +// \ No newline at end of file From 37bb97740f5e1cd4e7057e03a1a37ebbc8e28b1b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:55:33 +0000 Subject: [PATCH 25/46] Don't provide code lenses on any types of function expressions. --- internal/ls/codelens.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index 7aaaa85b5b..0b38016b3d 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -189,7 +189,7 @@ func isValidImplementationsCodeLensNode(node *ast.Node, userPrefs *lsutil.UserPr func isValidReferenceLensNode(node *ast.Node, userPrefs *lsutil.UserPreferences) bool { switch node.Kind { - case ast.KindFunctionDeclaration, ast.KindFunctionExpression: + case ast.KindFunctionDeclaration: if userPrefs.ReferencesCodeLensShowOnAllFunctions { return true } From 0947f7398d6bf164b07bb5f8a30977b0d04824ee Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:55:42 +0000 Subject: [PATCH 26/46] Update baselines. --- ...eLensFunctionsExpressions01.baseline.jsonc | 88 ------------------- 1 file changed, 88 deletions(-) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc index c5e9f7cb71..781e30b22e 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc @@ -9,17 +9,6 @@ -// === Code Lenses === -// === /anonymousFunctionExpressions.ts === -// export let anonFn1 = /*CODELENS: 0 references*/function () {}; -// export const anonFn2 = function () {}; -// -// let anonFn3 = function () {}; -// const anonFn4 = function () {}; -// - - - // === Code Lenses === // === /anonymousFunctionExpressions.ts === // export let anonFn1 = function () {}; @@ -31,39 +20,6 @@ -// === Code Lenses === -// === /anonymousFunctionExpressions.ts === -// export let anonFn1 = function () {}; -// export const anonFn2 = /*CODELENS: 0 references*/function () {}; -// -// let anonFn3 = function () {}; -// const anonFn4 = function () {}; -// - - - -// === Code Lenses === -// === /anonymousFunctionExpressions.ts === -// export let anonFn1 = function () {}; -// export const anonFn2 = function () {}; -// -// let anonFn3 = /*CODELENS: 0 references*/function () {}; -// const anonFn4 = function () {}; -// - - - -// === Code Lenses === -// === /anonymousFunctionExpressions.ts === -// export let anonFn1 = function () {}; -// export const anonFn2 = function () {}; -// -// let anonFn3 = function () {}; -// const anonFn4 = /*CODELENS: 0 references*/function () {}; -// - - - // === Code Lenses === // === /arrowFunctions.ts === // export let /*CODELENS: 0 references*/arrowFn1 = () => {}; @@ -97,17 +53,6 @@ -// === Code Lenses === -// === /namedFunctions.ts === -// export let namedFn1 = function /*CODELENS: 0 references*/namedFn1() {} -// export const namedFn2 = function namedFn2() {} -// -// let namedFn3 = function namedFn3() {} -// const namedFn4 = function namedFn4() {} -// - - - // === Code Lenses === // === /namedFunctions.ts === // export let namedFn1 = function namedFn1() {} @@ -115,37 +60,4 @@ // // let namedFn3 = function namedFn3() {} // const namedFn4 = function namedFn4() {} -// - - - -// === Code Lenses === -// === /namedFunctions.ts === -// export let namedFn1 = function namedFn1() {} -// export const namedFn2 = function /*CODELENS: 0 references*/namedFn2() {} -// -// let namedFn3 = function namedFn3() {} -// const namedFn4 = function namedFn4() {} -// - - - -// === Code Lenses === -// === /namedFunctions.ts === -// export let namedFn1 = function namedFn1() {} -// export const namedFn2 = function namedFn2() {} -// -// let namedFn3 = function /*CODELENS: 0 references*/namedFn3() {} -// const namedFn4 = function namedFn4() {} -// - - - -// === Code Lenses === -// === /namedFunctions.ts === -// export let namedFn1 = function namedFn1() {} -// export const namedFn2 = function namedFn2() {} -// -// let namedFn3 = function namedFn3() {} -// const namedFn4 = function /*CODELENS: 0 references*/namedFn4() {} // \ No newline at end of file From c4e242b4aec2898ac169e4ced2ff87f465701e01 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 22:57:40 +0000 Subject: [PATCH 27/46] Rename test. --- internal/fourslash/tests/codeLensFunctionExpressions01_test.go | 2 +- ...eline.jsonc => codeLensFunctionExpressions01.baseline.jsonc} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename testdata/baselines/reference/fourslash/codeLenses/{codeLensFunctionsExpressions01.baseline.jsonc => codeLensFunctionExpressions01.baseline.jsonc} (100%) diff --git a/internal/fourslash/tests/codeLensFunctionExpressions01_test.go b/internal/fourslash/tests/codeLensFunctionExpressions01_test.go index 4ba6ebccfd..b395051c90 100644 --- a/internal/fourslash/tests/codeLensFunctionExpressions01_test.go +++ b/internal/fourslash/tests/codeLensFunctionExpressions01_test.go @@ -8,7 +8,7 @@ import ( "github.com/microsoft/typescript-go/internal/testutil" ) -func TestCodeLensFunctionsExpressions01(t *testing.T) { +func TestCodeLensFunctionExpressions01(t *testing.T) { t.Parallel() defer testutil.RecoverAndFail(t, "Panic on fourslash test") diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionExpressions01.baseline.jsonc similarity index 100% rename from testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionsExpressions01.baseline.jsonc rename to testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionExpressions01.baseline.jsonc From d202d83c3adf501db501749e8edb40c01ca6241a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 23:00:24 +0000 Subject: [PATCH 28/46] Add an actual usage inside/outside the function expression to show which references are being found. --- .../tests/codeLensFunctionExpressions01_test.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/fourslash/tests/codeLensFunctionExpressions01_test.go b/internal/fourslash/tests/codeLensFunctionExpressions01_test.go index b395051c90..92768014ad 100644 --- a/internal/fourslash/tests/codeLensFunctionExpressions01_test.go +++ b/internal/fourslash/tests/codeLensFunctionExpressions01_test.go @@ -28,11 +28,18 @@ let arrowFn3 = () => {}; const arrowFn4 = () => {}; // @filename: namedFunctions.ts -export let namedFn1 = function namedFn1() {} -export const namedFn2 = function namedFn2() {} +export let namedFn1 = function namedFn1() { + namedFn1(); +} +namedFn1(); + +export const namedFn2 = function namedFn2() { + namedFn2(); +} +namedFn2(); -let namedFn3 = function namedFn3() {} -const namedFn4 = function namedFn4() {} +let namedFn3 = function namedFn3() {}; +const namedFn4 = function namedFn4() {}; ` f := fourslash.NewFourslash(t, nil /*capabilities*/, content) f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ From 0b91cbbf7050fa7fd44320bfd6b631a1789ca985 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 25 Nov 2025 23:02:13 +0000 Subject: [PATCH 29/46] Update baselines. --- ...deLensFunctionExpressions01.baseline.jsonc | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionExpressions01.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionExpressions01.baseline.jsonc index 781e30b22e..5b8911c10b 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionExpressions01.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensFunctionExpressions01.baseline.jsonc @@ -44,20 +44,29 @@ // === Code Lenses === // === /namedFunctions.ts === -// export let /*CODELENS: 0 references*/namedFn1 = function namedFn1() {} -// export const namedFn2 = function namedFn2() {} -// -// let namedFn3 = function namedFn3() {} -// const namedFn4 = function namedFn4() {} +// export let /*CODELENS: 1 reference*/namedFn1 = function namedFn1() { +// namedFn1(); +// } +// [|namedFn1|](); // +// export const namedFn2 = function namedFn2() { +// namedFn2(); +// --- (line: 8) skipped --- // === Code Lenses === // === /namedFunctions.ts === -// export let namedFn1 = function namedFn1() {} -// export const /*CODELENS: 0 references*/namedFn2 = function namedFn2() {} +// export let namedFn1 = function namedFn1() { +// namedFn1(); +// } +// namedFn1(); +// +// export const /*CODELENS: 1 reference*/namedFn2 = function namedFn2() { +// namedFn2(); +// } +// [|namedFn2|](); // -// let namedFn3 = function namedFn3() {} -// const namedFn4 = function namedFn4() {} +// let namedFn3 = function namedFn3() {}; +// const namedFn4 = function namedFn4() {}; // \ No newline at end of file From d05080409a6c84916dc0c733df15fa1d71b9880e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:05:43 +0000 Subject: [PATCH 30/46] Add explicit test for toggling `showOnAllFunctions` for references code lens. --- .../tests/codeLensShowOnAllFunctions_test.go | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 internal/fourslash/tests/codeLensShowOnAllFunctions_test.go diff --git a/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go b/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go new file mode 100644 index 0000000000..3d690c79e8 --- /dev/null +++ b/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go @@ -0,0 +1,40 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func runCodeLensShowOnAllFunctions(t *testing.T, showOnAllFunctions bool) { + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +export function f1(): void {} + +function f2(): void {} + +export const f3 = () => {}; + +const f4 = () => {}; + +const f5 = function() {}; +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ReferencesCodeLensEnabled: true, + ReferencesCodeLensShowOnAllFunctions: showOnAllFunctions, + }) +} + +func TestCodeLensReferencesShowOnAllFunctionsTrue(t *testing.T) { + t.Parallel() + runCodeLensShowOnAllFunctions(t, true) +} + +func TestCodeLensReferencesShowOnAllFunctionsFalse(t *testing.T) { + t.Parallel() + runCodeLensShowOnAllFunctions(t, false) +} From 37b63d8b00d23f30c01295a340de773b0e20e947 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:05:49 +0000 Subject: [PATCH 31/46] Update baselines. --- ...ncesShowOnAllFunctionsFalse.baseline.jsonc | 22 ++++++++++++ ...encesShowOnAllFunctionsTrue.baseline.jsonc | 34 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc new file mode 100644 index 0000000000..34aa15c244 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc @@ -0,0 +1,22 @@ +// === Code Lenses === +// === /codeLensReferencesShowOnAllFunctionsFalse.ts === +// export function /*CODELENS: 0 references*/f1(): void {} +// +// function f2(): void {} +// +// --- (line: 5) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllFunctionsFalse.ts === +// export function f1(): void {} +// +// function f2(): void {} +// +// export const /*CODELENS: 0 references*/f3 = () => {}; +// +// const f4 = () => {}; +// +// const f5 = function() {}; +// \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc new file mode 100644 index 0000000000..8442d50711 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc @@ -0,0 +1,34 @@ +// === Code Lenses === +// === /codeLensReferencesShowOnAllFunctionsTrue.ts === +// export function /*CODELENS: 0 references*/f1(): void {} +// +// function f2(): void {} +// +// --- (line: 5) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllFunctionsTrue.ts === +// export function f1(): void {} +// +// function /*CODELENS: 0 references*/f2(): void {} +// +// export const f3 = () => {}; +// +// --- (line: 7) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllFunctionsTrue.ts === +// export function f1(): void {} +// +// function f2(): void {} +// +// export const /*CODELENS: 0 references*/f3 = () => {}; +// +// const f4 = () => {}; +// +// const f5 = function() {}; +// \ No newline at end of file From 959b5dbd4c716583703b84c1ca9849f1dc9ce6a4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:16:59 +0000 Subject: [PATCH 32/46] Add test for `showOnInterfaceMethods`. --- .../codeLensShowOnInterfaceMethods_test.go | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go diff --git a/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go b/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go new file mode 100644 index 0000000000..706ab5967f --- /dev/null +++ b/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go @@ -0,0 +1,54 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func runCodeLensShowOnInterfaceMethods(t *testing.T, showOnInterfaceMethods bool) { + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +export interface I { + methodA(): void; +} +export interface I { + methodB(): void; +} + +interface J extends I { + methodB(): void; + methodC(): void; +} + +class C implements J { + methodA(): void {} + methodB(): void {} + methodC(): void {} +} + +class AbstractC implements J { + abstract methodA(): void; + methodB(): void {} + abstract methodC(): void; +} +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnInterfaceMethods: showOnInterfaceMethods, + }) +} + +func TestCodeLensReferencesShowOnInterfaceMethodsTrue(t *testing.T) { + t.Parallel() + runCodeLensShowOnInterfaceMethods(t, true) +} + +func TestCodeLensReferencesShowOnInterfaceMethodsFalse(t *testing.T) { + t.Parallel() + runCodeLensShowOnInterfaceMethods(t, false) +} From 73d11c45d738b1b557b4ce7fb69bd7a0163ddc60 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:17:05 +0000 Subject: [PATCH 33/46] Update baselines. --- ...ShowOnInterfaceMethodsFalse.baseline.jsonc | 78 ++++++++ ...sShowOnInterfaceMethodsTrue.baseline.jsonc | 173 ++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc new file mode 100644 index 0000000000..cb9cc607cd --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc @@ -0,0 +1,78 @@ +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// export interface /*CODELENS: 3 implementations*/I { +// methodA(): void; +// } +// export interface I { +// methodB(): void; +// } +// +// interface [|J|] extends I { +// methodB(): void; +// methodC(): void; +// } +// +// class [|C|] implements J { +// methodA(): void {} +// methodB(): void {} +// methodC(): void {} +// } +// +// class [|AbstractC|] implements J { +// abstract methodA(): void; +// methodB(): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// --- (line: 4) skipped --- +// methodB(): void; +// } +// +// interface /*CODELENS: 2 implementations*/J extends I { +// methodB(): void; +// methodC(): void; +// } +// +// class [|C|] implements J { +// methodA(): void {} +// methodB(): void {} +// methodC(): void {} +// } +// +// class [|AbstractC|] implements J { +// abstract methodA(): void; +// methodB(): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// --- (line: 16) skipped --- +// } +// +// class AbstractC implements J { +// abstract /*CODELENS: 0 implementations*/methodA(): void; +// methodB(): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// --- (line: 18) skipped --- +// class AbstractC implements J { +// abstract methodA(): void; +// methodB(): void {} +// abstract /*CODELENS: 0 implementations*/methodC(): void; +// } +// \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc new file mode 100644 index 0000000000..942a402d19 --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc @@ -0,0 +1,173 @@ +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// export interface /*CODELENS: 3 implementations*/I { +// methodA(): void; +// } +// export interface I { +// methodB(): void; +// } +// +// interface [|J|] extends I { +// methodB(): void; +// methodC(): void; +// } +// +// class [|C|] implements J { +// methodA(): void {} +// methodB(): void {} +// methodC(): void {} +// } +// +// class [|AbstractC|] implements J { +// abstract methodA(): void; +// methodB(): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// export interface I { +// /*CODELENS: 1 implementation*/methodA(): void; +// } +// export interface I { +// methodB(): void; +// --- (line: 6) skipped --- + +// --- (line: 10) skipped --- +// } +// +// class C implements J { +// [|methodA|](): void {} +// methodB(): void {} +// methodC(): void {} +// } +// --- (line: 18) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// export interface I { +// methodA(): void; +// } +// export interface I { +// /*CODELENS: 2 implementations*/methodB(): void; +// } +// +// interface J extends I { +// methodB(): void; +// methodC(): void; +// } +// +// class C implements J { +// methodA(): void {} +// [|methodB|](): void {} +// methodC(): void {} +// } +// +// class AbstractC implements J { +// abstract methodA(): void; +// [|methodB|](): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// --- (line: 4) skipped --- +// methodB(): void; +// } +// +// interface /*CODELENS: 2 implementations*/J extends I { +// methodB(): void; +// methodC(): void; +// } +// +// class [|C|] implements J { +// methodA(): void {} +// methodB(): void {} +// methodC(): void {} +// } +// +// class [|AbstractC|] implements J { +// abstract methodA(): void; +// methodB(): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// --- (line: 5) skipped --- +// } +// +// interface J extends I { +// /*CODELENS: 2 implementations*/methodB(): void; +// methodC(): void; +// } +// +// class C implements J { +// methodA(): void {} +// [|methodB|](): void {} +// methodC(): void {} +// } +// +// class AbstractC implements J { +// abstract methodA(): void; +// [|methodB|](): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// --- (line: 6) skipped --- +// +// interface J extends I { +// methodB(): void; +// /*CODELENS: 1 implementation*/methodC(): void; +// } +// +// class C implements J { +// methodA(): void {} +// methodB(): void {} +// [|methodC|](): void {} +// } +// +// class AbstractC implements J { +// --- (line: 20) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// --- (line: 16) skipped --- +// } +// +// class AbstractC implements J { +// abstract /*CODELENS: 0 implementations*/methodA(): void; +// methodB(): void {} +// abstract methodC(): void; +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// --- (line: 18) skipped --- +// class AbstractC implements J { +// abstract methodA(): void; +// methodB(): void {} +// abstract /*CODELENS: 0 implementations*/methodC(): void; +// } +// \ No newline at end of file From e2ff436b9e93b0831c0c64d53c6aaca560f0205b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:45:30 +0000 Subject: [PATCH 34/46] Switch towards using sub-tests. --- .../tests/codeLensShowOnAllFunctions_test.go | 34 +++++++++---------- .../codeLensShowOnInterfaceMethods_test.go | 34 +++++++++---------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go b/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go index 3d690c79e8..8d26e6e985 100644 --- a/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go +++ b/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go @@ -1,6 +1,7 @@ package fourslash_test import ( + "fmt" "testing" "github.com/microsoft/typescript-go/internal/fourslash" @@ -8,10 +9,15 @@ import ( "github.com/microsoft/typescript-go/internal/testutil" ) -func runCodeLensShowOnAllFunctions(t *testing.T, showOnAllFunctions bool) { - defer testutil.RecoverAndFail(t, "Panic on fourslash test") +func TestCodeLensReferencesShowOnAllFunctions(t *testing.T) { + t.Parallel() + + containingTestName := t.Name() + for _, value := range []bool{true, false} { + t.Run(fmt.Sprintf("%s=%v", containingTestName, value), func(t *testing.T) { + defer testutil.RecoverAndFail(t, "Panic on fourslash test") - const content = ` + const content = ` export function f1(): void {} function f2(): void {} @@ -22,19 +28,11 @@ const f4 = () => {}; const f5 = function() {}; ` - f := fourslash.NewFourslash(t, nil /*capabilities*/, content) - f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ - ReferencesCodeLensEnabled: true, - ReferencesCodeLensShowOnAllFunctions: showOnAllFunctions, - }) -} - -func TestCodeLensReferencesShowOnAllFunctionsTrue(t *testing.T) { - t.Parallel() - runCodeLensShowOnAllFunctions(t, true) -} - -func TestCodeLensReferencesShowOnAllFunctionsFalse(t *testing.T) { - t.Parallel() - runCodeLensShowOnAllFunctions(t, false) + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ReferencesCodeLensEnabled: true, + ReferencesCodeLensShowOnAllFunctions: value, + }) + }) + } } diff --git a/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go b/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go index 706ab5967f..04c37dd80b 100644 --- a/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go +++ b/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go @@ -1,6 +1,7 @@ package fourslash_test import ( + "fmt" "testing" "github.com/microsoft/typescript-go/internal/fourslash" @@ -8,10 +9,15 @@ import ( "github.com/microsoft/typescript-go/internal/testutil" ) -func runCodeLensShowOnInterfaceMethods(t *testing.T, showOnInterfaceMethods bool) { - defer testutil.RecoverAndFail(t, "Panic on fourslash test") +func TestCodeLensReferencesShowOnInterfaceMethods(t *testing.T) { + t.Parallel() + + containingTestName := t.Name() + for _, value := range []bool{true, false} { + t.Run(fmt.Sprintf("%s=%v", containingTestName, value), func(t *testing.T) { + defer testutil.RecoverAndFail(t, "Panic on fourslash test") - const content = ` + const content = ` export interface I { methodA(): void; } @@ -36,19 +42,11 @@ class AbstractC implements J { abstract methodC(): void; } ` - f := fourslash.NewFourslash(t, nil /*capabilities*/, content) - f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ - ImplementationsCodeLensEnabled: true, - ImplementationsCodeLensShowOnInterfaceMethods: showOnInterfaceMethods, - }) -} - -func TestCodeLensReferencesShowOnInterfaceMethodsTrue(t *testing.T) { - t.Parallel() - runCodeLensShowOnInterfaceMethods(t, true) -} - -func TestCodeLensReferencesShowOnInterfaceMethodsFalse(t *testing.T) { - t.Parallel() - runCodeLensShowOnInterfaceMethods(t, false) + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnInterfaceMethods: value, + }) + }) + } } From c5045445cf6aa30d5d528981086987ab4206e603 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:46:53 +0000 Subject: [PATCH 35/46] Update baselines. --- ...encesShowOnAllFunctions=false.baseline.jsonc} | 4 ++-- ...rencesShowOnAllFunctions=true.baseline.jsonc} | 6 +++--- ...sShowOnInterfaceMethods=false.baseline.jsonc} | 8 ++++---- ...esShowOnInterfaceMethods=true.baseline.jsonc} | 16 ++++++++-------- 4 files changed, 17 insertions(+), 17 deletions(-) rename testdata/baselines/reference/fourslash/codeLenses/{codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc => codeLensReferencesShowOnAllFunctions=false.baseline.jsonc} (75%) rename testdata/baselines/reference/fourslash/codeLenses/{codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc => codeLensReferencesShowOnAllFunctions=true.baseline.jsonc} (76%) rename testdata/baselines/reference/fourslash/codeLenses/{codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc => codeLensReferencesShowOnInterfaceMethods=false.baseline.jsonc} (84%) rename testdata/baselines/reference/fourslash/codeLenses/{codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc => codeLensReferencesShowOnInterfaceMethods=true.baseline.jsonc} (85%) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctions=false.baseline.jsonc similarity index 75% rename from testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc rename to testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctions=false.baseline.jsonc index 34aa15c244..7bb4a5657d 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsFalse.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctions=false.baseline.jsonc @@ -1,5 +1,5 @@ // === Code Lenses === -// === /codeLensReferencesShowOnAllFunctionsFalse.ts === +// === /codeLensReferencesShowOnAllFunctions=false.ts === // export function /*CODELENS: 0 references*/f1(): void {} // // function f2(): void {} @@ -9,7 +9,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnAllFunctionsFalse.ts === +// === /codeLensReferencesShowOnAllFunctions=false.ts === // export function f1(): void {} // // function f2(): void {} diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctions=true.baseline.jsonc similarity index 76% rename from testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc rename to testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctions=true.baseline.jsonc index 8442d50711..b890c7f5c1 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctionsTrue.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllFunctions=true.baseline.jsonc @@ -1,5 +1,5 @@ // === Code Lenses === -// === /codeLensReferencesShowOnAllFunctionsTrue.ts === +// === /codeLensReferencesShowOnAllFunctions=true.ts === // export function /*CODELENS: 0 references*/f1(): void {} // // function f2(): void {} @@ -9,7 +9,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnAllFunctionsTrue.ts === +// === /codeLensReferencesShowOnAllFunctions=true.ts === // export function f1(): void {} // // function /*CODELENS: 0 references*/f2(): void {} @@ -21,7 +21,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnAllFunctionsTrue.ts === +// === /codeLensReferencesShowOnAllFunctions=true.ts === // export function f1(): void {} // // function f2(): void {} diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethods=false.baseline.jsonc similarity index 84% rename from testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc rename to testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethods=false.baseline.jsonc index cb9cc607cd..5f9918a03c 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsFalse.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethods=false.baseline.jsonc @@ -1,5 +1,5 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// === /codeLensReferencesShowOnInterfaceMethods=false.ts === // export interface /*CODELENS: 3 implementations*/I { // methodA(): void; // } @@ -28,7 +28,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// === /codeLensReferencesShowOnInterfaceMethods=false.ts === // --- (line: 4) skipped --- // methodB(): void; // } @@ -54,7 +54,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// === /codeLensReferencesShowOnInterfaceMethods=false.ts === // --- (line: 16) skipped --- // } // @@ -68,7 +68,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsFalse.ts === +// === /codeLensReferencesShowOnInterfaceMethods=false.ts === // --- (line: 18) skipped --- // class AbstractC implements J { // abstract methodA(): void; diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethods=true.baseline.jsonc similarity index 85% rename from testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc rename to testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethods=true.baseline.jsonc index 942a402d19..cf498182d5 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethodsTrue.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnInterfaceMethods=true.baseline.jsonc @@ -1,5 +1,5 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // export interface /*CODELENS: 3 implementations*/I { // methodA(): void; // } @@ -28,7 +28,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // export interface I { // /*CODELENS: 1 implementation*/methodA(): void; // } @@ -49,7 +49,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // export interface I { // methodA(): void; // } @@ -78,7 +78,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // --- (line: 4) skipped --- // methodB(): void; // } @@ -104,7 +104,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // --- (line: 5) skipped --- // } // @@ -129,7 +129,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // --- (line: 6) skipped --- // // interface J extends I { @@ -149,7 +149,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // --- (line: 16) skipped --- // } // @@ -163,7 +163,7 @@ // === Code Lenses === -// === /codeLensReferencesShowOnInterfaceMethodsTrue.ts === +// === /codeLensReferencesShowOnInterfaceMethods=true.ts === // --- (line: 18) skipped --- // class AbstractC implements J { // abstract methodA(): void; From 46164b39e262102a774b168464f51702a8b93034 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:53:40 +0000 Subject: [PATCH 36/46] Add test for `showOnAllClassMethods`. --- .../codeLensShowOnAllClassMethods_test.go | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go diff --git a/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go b/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go new file mode 100644 index 0000000000..be79384526 --- /dev/null +++ b/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go @@ -0,0 +1,43 @@ +package fourslash_test + +import ( + "fmt" + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/ls/lsutil" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestCodeLensReferencesShowOnAllClassMethods(t *testing.T) { + t.Parallel() + + containingTestName := t.Name() + for _, value := range []bool{true, false} { + t.Run(fmt.Sprintf("%s=%v", containingTestName, value), func(t *testing.T) { + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + + const content = ` +export abstract class ABC { + abstract methodA(): void; + methodB(): void {} + #methodC(): void {} + protected methodD(): void {} + private methodE(): void {} + protected abstract methodG(): void; + public methodH(): void {} + + static methodStaticA(): void {} + protected static methodStaticB(): void {} + private static methodStaticC(): void {} + static #methodStaticD(): void {} +} +` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{ + ImplementationsCodeLensEnabled: true, + ImplementationsCodeLensShowOnAllClassMethods: value, + }) + }) + } +} From 3a58afc556cc8446ec6ac57db3999a8f0f4beb9d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 19:53:44 +0000 Subject: [PATCH 37/46] Update baselines. --- ...ShowOnAllClassMethods=false.baseline.jsonc | 32 ++++++ ...sShowOnAllClassMethods=true.baseline.jsonc | 101 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc create mode 100644 testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc new file mode 100644 index 0000000000..99e12a763f --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc @@ -0,0 +1,32 @@ +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=false.ts === +// export abstract class /*CODELENS: 0 implementations*/ABC { +// abstract methodA(): void; +// methodB(): void {} +// #methodC(): void {} +// --- (line: 5) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=false.ts === +// export abstract class ABC { +// abstract /*CODELENS: 0 implementations*/methodA(): void; +// methodB(): void {} +// #methodC(): void {} +// protected methodD(): void {} +// --- (line: 6) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=false.ts === +// --- (line: 3) skipped --- +// #methodC(): void {} +// protected methodD(): void {} +// private methodE(): void {} +// abstract protected /*CODELENS: 0 implementations*/methodG(): void; +// public methodH(): void {} +// +// static methodStaticA(): void {} +// --- (line: 11) skipped --- \ No newline at end of file diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc new file mode 100644 index 0000000000..946acc63ed --- /dev/null +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc @@ -0,0 +1,101 @@ +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// export abstract class /*CODELENS: 0 implementations*/ABC { +// abstract methodA(): void; +// methodB(): void {} +// #methodC(): void {} +// --- (line: 5) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// export abstract class ABC { +// abstract /*CODELENS: 0 implementations*/methodA(): void; +// methodB(): void {} +// #methodC(): void {} +// protected methodD(): void {} +// --- (line: 6) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// export abstract class ABC { +// abstract methodA(): void; +// /*CODELENS: 0 implementations*/methodB(): void {} +// #methodC(): void {} +// protected methodD(): void {} +// private methodE(): void {} +// --- (line: 7) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// export abstract class ABC { +// abstract methodA(): void; +// methodB(): void {} +// #methodC(): void {} +// protected /*CODELENS: 0 implementations*/methodD(): void {} +// private methodE(): void {} +// abstract protected methodG(): void; +// public methodH(): void {} +// --- (line: 9) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// --- (line: 3) skipped --- +// #methodC(): void {} +// protected methodD(): void {} +// private methodE(): void {} +// abstract protected /*CODELENS: 0 implementations*/methodG(): void; +// public methodH(): void {} +// +// static methodStaticA(): void {} +// --- (line: 11) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// --- (line: 4) skipped --- +// protected methodD(): void {} +// private methodE(): void {} +// abstract protected methodG(): void; +// public /*CODELENS: 0 implementations*/methodH(): void {} +// +// static methodStaticA(): void {} +// protected static methodStaticB(): void {} +// --- (line: 12) skipped --- + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// --- (line: 6) skipped --- +// abstract protected methodG(): void; +// public methodH(): void {} +// +// static /*CODELENS: 0 implementations*/methodStaticA(): void {} +// protected static methodStaticB(): void {} +// private static methodStaticC(): void {} +// static #methodStaticD(): void {} +// } +// + + + +// === Code Lenses === +// === /codeLensReferencesShowOnAllClassMethods=true.ts === +// --- (line: 7) skipped --- +// public methodH(): void {} +// +// static methodStaticA(): void {} +// protected static /*CODELENS: 0 implementations*/methodStaticB(): void {} +// private static methodStaticC(): void {} +// static #methodStaticD(): void {} +// } +// \ No newline at end of file From 4357078cad5b9c0d30a638173cd8e5106603ead0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 20:05:59 +0000 Subject: [PATCH 38/46] Clarify comment. --- internal/fourslash/fourslash.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index fa4204bb43..a598578862 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1350,8 +1350,9 @@ func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil var locations []lsproto.Location // commandArgs: (DocumentUri, Position, Location[]) if commandArgs := resolvedCodeLens.Command.Arguments; commandArgs != nil { - // TODO: inevitably this would fail if we were actually going over the wire - // since the type info will be lost in that `any`. + // TODO: inevitably this would fail if we round-tripped the data over the wire. + // While an ordinary client can support this, we can't rehydrate to `Location`s because + // the type info will be lost in that `any`. untypedLocs := (*commandArgs)[2] if locs, ok := untypedLocs.([]lsproto.Location); ok { locations = locs From 73af385e4445032d1b510b628e50716cd09077c2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 23:47:23 +0000 Subject: [PATCH 39/46] Update stale baselines from before test was modified --- ...nsReferencesShowOnAllClassMethods=false.baseline.jsonc | 2 +- ...ensReferencesShowOnAllClassMethods=true.baseline.jsonc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc index 99e12a763f..09d45e997c 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=false.baseline.jsonc @@ -25,7 +25,7 @@ // #methodC(): void {} // protected methodD(): void {} // private methodE(): void {} -// abstract protected /*CODELENS: 0 implementations*/methodG(): void; +// protected abstract /*CODELENS: 0 implementations*/methodG(): void; // public methodH(): void {} // // static methodStaticA(): void {} diff --git a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc index 946acc63ed..7da1d95f5d 100644 --- a/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/codeLenses/codeLensReferencesShowOnAllClassMethods=true.baseline.jsonc @@ -39,7 +39,7 @@ // #methodC(): void {} // protected /*CODELENS: 0 implementations*/methodD(): void {} // private methodE(): void {} -// abstract protected methodG(): void; +// protected abstract methodG(): void; // public methodH(): void {} // --- (line: 9) skipped --- @@ -51,7 +51,7 @@ // #methodC(): void {} // protected methodD(): void {} // private methodE(): void {} -// abstract protected /*CODELENS: 0 implementations*/methodG(): void; +// protected abstract /*CODELENS: 0 implementations*/methodG(): void; // public methodH(): void {} // // static methodStaticA(): void {} @@ -64,7 +64,7 @@ // --- (line: 4) skipped --- // protected methodD(): void {} // private methodE(): void {} -// abstract protected methodG(): void; +// protected abstract methodG(): void; // public /*CODELENS: 0 implementations*/methodH(): void {} // // static methodStaticA(): void {} @@ -76,7 +76,7 @@ // === Code Lenses === // === /codeLensReferencesShowOnAllClassMethods=true.ts === // --- (line: 6) skipped --- -// abstract protected methodG(): void; +// protected abstract methodG(): void; // public methodH(): void {} // // static /*CODELENS: 0 implementations*/methodStaticA(): void {} From 01136653c40efc1d9a6324b960c23430e7257824 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 26 Nov 2025 23:58:08 +0000 Subject: [PATCH 40/46] Drive-by fix. --- internal/fourslash/fourslash.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index a598578862..d73f343db8 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -114,8 +114,8 @@ func (w *lspWriter) Write(msg *lsproto.Message) error { return nil } -func (r *lspWriter) Close() { - close(r.c) +func (w *lspWriter) Close() { + close(w.c) } var ( From 580a3d03a6da62f6fe7be54af43acfc4ccf6931a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 27 Nov 2025 00:06:24 +0000 Subject: [PATCH 41/46] Use the JSON-round-tripping trick for code lens arguments in tests. --- internal/fourslash/fourslash.go | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go index d73f343db8..2289b678e4 100644 --- a/internal/fourslash/fourslash.go +++ b/internal/fourslash/fourslash.go @@ -1350,15 +1350,11 @@ func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil var locations []lsproto.Location // commandArgs: (DocumentUri, Position, Location[]) if commandArgs := resolvedCodeLens.Command.Arguments; commandArgs != nil { - // TODO: inevitably this would fail if we round-tripped the data over the wire. - // While an ordinary client can support this, we can't rehydrate to `Location`s because - // the type info will be lost in that `any`. - untypedLocs := (*commandArgs)[2] - if locs, ok := untypedLocs.([]lsproto.Location); ok { - locations = locs - } else { - t.Fatalf("Expected code lens command arguments to contain a list of locations, but got %T", untypedLocs) + locs, err := roundtripThroughJson[[]lsproto.Location]((*commandArgs)[2]) + if err != nil { + t.Fatalf("failed to re-encode code lens locations: %v", err) } + locations = locs } f.addResultToBaseline(t, codeLensesCmd, f.getBaselineForLocationsWithFileContents(locations, baselineFourslashLocationsOptions{ @@ -1889,6 +1885,25 @@ func ptrTo[T any](v T) *T { return &v } +// This function is intended for spots where a complex +// value needs to be reinterpreted following some prior JSON deserialization. +// The default deserializer for `any` properties will give us a map at runtime, +// but we want to validate against, and use, the types as returned from the the language service. +// +// Use this function sparingly. You can treat it as a "map-to-struct" converter, +// but updating the original types is probably better in most cases. +func roundtripThroughJson[T any](value any) (T, error) { + var result T + bytes, err := json.Marshal(value) + if err != nil { + return result, fmt.Errorf("failed to marshal value to JSON: %w", err) + } + if err := json.Unmarshal(bytes, &result); err != nil { + return result, fmt.Errorf("failed to unmarshal value from JSON: %w", err) + } + return result, nil +} + // Insert text at the current caret position. func (f *FourslashTest) Insert(t *testing.T, text string) { f.typeText(t, text) From 727957b27e6249615d4d16dbccb2d2fb9e8e7434 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2025 18:55:40 +0000 Subject: [PATCH 42/46] Fix lint issues. --- internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go | 2 +- internal/fourslash/tests/codeLensShowOnAllFunctions_test.go | 2 +- internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go b/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go index be79384526..9683168764 100644 --- a/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go +++ b/internal/fourslash/tests/codeLensShowOnAllClassMethods_test.go @@ -11,10 +11,10 @@ import ( func TestCodeLensReferencesShowOnAllClassMethods(t *testing.T) { t.Parallel() - containingTestName := t.Name() for _, value := range []bool{true, false} { t.Run(fmt.Sprintf("%s=%v", containingTestName, value), func(t *testing.T) { + t.Parallel() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = ` diff --git a/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go b/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go index 8d26e6e985..a394b59ad9 100644 --- a/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go +++ b/internal/fourslash/tests/codeLensShowOnAllFunctions_test.go @@ -11,10 +11,10 @@ import ( func TestCodeLensReferencesShowOnAllFunctions(t *testing.T) { t.Parallel() - containingTestName := t.Name() for _, value := range []bool{true, false} { t.Run(fmt.Sprintf("%s=%v", containingTestName, value), func(t *testing.T) { + t.Parallel() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = ` diff --git a/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go b/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go index 04c37dd80b..289456a6e4 100644 --- a/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go +++ b/internal/fourslash/tests/codeLensShowOnInterfaceMethods_test.go @@ -11,10 +11,10 @@ import ( func TestCodeLensReferencesShowOnInterfaceMethods(t *testing.T) { t.Parallel() - containingTestName := t.Name() for _, value := range []bool{true, false} { t.Run(fmt.Sprintf("%s=%v", containingTestName, value), func(t *testing.T) { + t.Parallel() defer testutil.RecoverAndFail(t, "Panic on fourslash test") const content = ` From d6396a1bd4bdb686aa5c289b60eac6ca6a80f9e7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2025 20:31:25 +0000 Subject: [PATCH 43/46] Add early bailout for stale `codeLens/resolve`s. --- internal/ls/codelens.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index 0b38016b3d..98543f2728 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -56,11 +56,23 @@ func (l *LanguageService) ProvideCodeLenses(ctx context.Context, documentURI lsp func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto.CodeLens, showLocationsCommandName *string) (*lsproto.CodeLens, error) { uri := codeLens.Data.Uri + _, sourceFile := l.tryGetProgramAndFile(uri.FileName()) + if sourceFile == nil || + l.converters.PositionToLineAndCharacter(sourceFile, core.TextPos(sourceFile.End())).Line < codeLens.Range.Start.Line { + // This can happen if a codeLens/resolve request comes in after a program change. + // While it's true that handlers should latch onto a specific snapshot + // while processing requests, we just set `Data.Uri` based on + // some older snapshot's contents. The content could have been modified, + // or the file itself could have been removed from the session entirely. + // Note this won't bail out on every change, but will prevent crashing + // based on non-existent files and line maps from shortened files. + return codeLens, lsproto.ErrContentModified + } + textDoc := lsproto.TextDocumentIdentifier{ Uri: uri, } locale := locale.FromContext(ctx) - var locs []lsproto.Location var lensTitle string switch codeLens.Data.Kind { From ff9d7fb58984c7a38872278ce7d7aca003784143 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2025 20:32:01 +0000 Subject: [PATCH 44/46] Fix comment and document follow-up. --- internal/ls/findallreferences.go | 1 + internal/lsp/lsproto/baseproto.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go index 110df241ca..b5f281adf9 100644 --- a/internal/ls/findallreferences.go +++ b/internal/ls/findallreferences.go @@ -731,6 +731,7 @@ func (l *LanguageService) getTextForRename(originalNode *ast.Node, entry *Refere func (l *LanguageService) convertSymbolAndEntriesToLocations(s *SymbolAndEntries, includeDeclarations bool) []lsproto.Location { references := s.references + // !!! includeDeclarations if !includeDeclarations && s.definition != nil { references = core.Filter(references, func(entry *ReferenceEntry) bool { return !isDeclarationOfSymbol(entry.node, s.definition.symbol) diff --git a/internal/lsp/lsproto/baseproto.go b/internal/lsp/lsproto/baseproto.go index a954c93287..e0c1fbce99 100644 --- a/internal/lsp/lsproto/baseproto.go +++ b/internal/lsp/lsproto/baseproto.go @@ -127,7 +127,7 @@ var ( // The server detected that the content of a document got // modified outside normal conditions. A server should // NOT send this error code if it detects a content change - // in it unprocessed messages. The result even computed + // in its unprocessed messages. The result even computed // on an older state might still be useful for the client. // // If a client decides that a result is not of any use anymore From 00436de73963b6d38e9f742534458b22b3bf57b0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2025 21:14:09 +0000 Subject: [PATCH 45/46] Back out change to avoid issues with upcoming PR. --- internal/lsp/lsproto/baseproto.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/lsp/lsproto/baseproto.go b/internal/lsp/lsproto/baseproto.go index e0c1fbce99..a954c93287 100644 --- a/internal/lsp/lsproto/baseproto.go +++ b/internal/lsp/lsproto/baseproto.go @@ -127,7 +127,7 @@ var ( // The server detected that the content of a document got // modified outside normal conditions. A server should // NOT send this error code if it detects a content change - // in its unprocessed messages. The result even computed + // in it unprocessed messages. The result even computed // on an older state might still be useful for the client. // // If a client decides that a result is not of any use anymore From 766a5b496b65e3336af744d206da2dcc53e93a15 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2025 22:42:15 +0000 Subject: [PATCH 46/46] Update const name. --- internal/ls/codelens.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ls/codelens.go b/internal/ls/codelens.go index 98543f2728..83d81d8da1 100644 --- a/internal/ls/codelens.go +++ b/internal/ls/codelens.go @@ -66,7 +66,7 @@ func (l *LanguageService) ResolveCodeLens(ctx context.Context, codeLens *lsproto // or the file itself could have been removed from the session entirely. // Note this won't bail out on every change, but will prevent crashing // based on non-existent files and line maps from shortened files. - return codeLens, lsproto.ErrContentModified + return codeLens, lsproto.ErrorCodeContentModified } textDoc := lsproto.TextDocumentIdentifier{