Skip to content

Commit 0c8895b

Browse files
authored
Fix unused identifier diags, LSP tag diags (#2007)
1 parent 2ba0e47 commit 0c8895b

File tree

4 files changed

+76
-15
lines changed

4 files changed

+76
-15
lines changed

internal/checker/checker.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6781,10 +6781,26 @@ func (c *Checker) reportUnusedVariable(location *ast.Node, diagnostic *ast.Diagn
67816781
}
67826782

67836783
func (c *Checker) reportUnused(location *ast.Node, kind UnusedKind, diagnostic *ast.Diagnostic) {
6784-
if location.Flags&(ast.NodeFlagsAmbient|ast.NodeFlagsThisNodeOrAnySubNodesHasError) == 0 &&
6785-
(kind == UnusedKindLocal && c.compilerOptions.NoUnusedLocals.IsTrue() ||
6786-
(kind == UnusedKindParameter && c.compilerOptions.NoUnusedParameters.IsTrue())) {
6787-
c.diagnostics.Add(diagnostic)
6784+
if location.Flags&(ast.NodeFlagsAmbient|ast.NodeFlagsThisNodeOrAnySubNodesHasError) == 0 {
6785+
isError := c.unusedIsError(kind)
6786+
if isError {
6787+
c.diagnostics.Add(diagnostic)
6788+
} else {
6789+
suggestion := *diagnostic
6790+
suggestion.SetCategory(diagnostics.CategorySuggestion)
6791+
c.suggestionDiagnostics.Add(&suggestion)
6792+
}
6793+
}
6794+
}
6795+
6796+
func (c *Checker) unusedIsError(kind UnusedKind) bool {
6797+
switch kind {
6798+
case UnusedKindLocal:
6799+
return c.compilerOptions.NoUnusedLocals.IsTrue()
6800+
case UnusedKindParameter:
6801+
return c.compilerOptions.NoUnusedParameters.IsTrue()
6802+
default:
6803+
panic("Unhandled case in unusedIsError")
67886804
}
67896805
}
67906806

@@ -13401,18 +13417,30 @@ func (c *Checker) GetSuggestionDiagnostics(ctx context.Context, sourceFile *ast.
1340113417

1340213418
func (c *Checker) getDiagnostics(ctx context.Context, sourceFile *ast.SourceFile, collection *ast.DiagnosticsCollection) []*ast.Diagnostic {
1340313419
c.checkNotCanceled()
13420+
isSuggestionDiagnostics := collection == &c.suggestionDiagnostics
13421+
13422+
files := c.files
1340413423
if sourceFile != nil {
13405-
c.CheckSourceFile(ctx, sourceFile)
13406-
if c.wasCanceled {
13407-
return nil
13408-
}
13409-
return collection.GetDiagnosticsForFile(sourceFile.FileName())
13424+
files = []*ast.SourceFile{sourceFile}
1341013425
}
13411-
for _, file := range c.files {
13426+
13427+
for _, file := range files {
1341213428
c.CheckSourceFile(ctx, file)
1341313429
if c.wasCanceled {
1341413430
return nil
1341513431
}
13432+
13433+
// Check unused identifiers as suggestions if we're collecting suggestion diagnostics
13434+
// and they are not configured as errors
13435+
if isSuggestionDiagnostics && !file.IsDeclarationFile &&
13436+
!(c.compilerOptions.NoUnusedLocals.IsTrue() || c.compilerOptions.NoUnusedParameters.IsTrue()) {
13437+
links := c.sourceFileLinks.Get(file)
13438+
c.checkUnusedIdentifiers(links.identifierCheckNodes)
13439+
}
13440+
}
13441+
13442+
if sourceFile != nil {
13443+
return collection.GetDiagnosticsForFile(sourceFile.FileName())
1341613444
}
1341713445
return collection.GetDiagnostics()
1341813446
}

internal/fourslash/fourslash.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ func getCapabilitiesWithDefaults(capabilities *lsproto.ClientCapabilities) *lspr
282282
},
283283
}
284284
}
285+
if capabilitiesWithDefaults.TextDocument.PublishDiagnostics == nil {
286+
capabilitiesWithDefaults.TextDocument.PublishDiagnostics = &lsproto.PublishDiagnosticsClientCapabilities{
287+
RelatedInformation: ptrTrue,
288+
TagSupport: &lsproto.ClientDiagnosticsTagOptions{
289+
ValueSet: []lsproto.DiagnosticTag{
290+
lsproto.DiagnosticTagUnnecessary,
291+
lsproto.DiagnosticTagDeprecated,
292+
},
293+
},
294+
}
295+
}
285296
if capabilitiesWithDefaults.Workspace == nil {
286297
capabilitiesWithDefaults.Workspace = &lsproto.WorkspaceClientCapabilities{}
287298
}

internal/ls/diagnostics.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func (l *LanguageService) ProvideDiagnostics(ctx context.Context, uri lsproto.Do
2020
diagnostics = append(diagnostics, program.GetSemanticDiagnostics(ctx, file))
2121
// !!! user preference for suggestion diagnostics; keep only unnecessary/deprecated?
2222
// See: https://github.com/microsoft/vscode/blob/3dbc74129aaae102e5cb485b958fa5360e8d3e7a/extensions/typescript-language-features/src/languageFeatures/diagnostics.ts#L114
23+
// TODO: also implement reportStyleCheckAsWarnings to rewrite diags with Warning severity
2324
diagnostics = append(diagnostics, program.GetSuggestionDiagnostics(ctx, file))
2425
if program.Options().GetEmitDeclarations() {
2526
diagnostics = append(diagnostics, program.GetDeclarationDiagnostics(ctx, file))

internal/lsp/server.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -800,11 +800,7 @@ func (s *Server) handleSetTrace(ctx context.Context, params *lsproto.SetTracePar
800800
}
801801

802802
func (s *Server) handleDocumentDiagnostic(ctx context.Context, ls *ls.LanguageService, params *lsproto.DocumentDiagnosticParams) (lsproto.DocumentDiagnosticResponse, error) {
803-
var diagnosticClientCapabilities *lsproto.DiagnosticClientCapabilities
804-
if s.initializeParams != nil && s.initializeParams.Capabilities != nil && s.initializeParams.Capabilities.TextDocument != nil {
805-
diagnosticClientCapabilities = s.initializeParams.Capabilities.TextDocument.Diagnostic
806-
}
807-
return ls.ProvideDiagnostics(ctx, params.TextDocument.Uri, diagnosticClientCapabilities)
803+
return ls.ProvideDiagnostics(ctx, params.TextDocument.Uri, getDiagnosticClientCapabilities(s.initializeParams))
808804
}
809805

810806
func (s *Server) handleHover(ctx context.Context, ls *ls.LanguageService, params *lsproto.HoverParams) (lsproto.HoverResponse, error) {
@@ -1037,3 +1033,28 @@ func getSignatureHelpDocumentationFormat(params *lsproto.InitializeParams) lspro
10371033
// Return the first (most preferred) format
10381034
return formats[0]
10391035
}
1036+
1037+
func getDiagnosticClientCapabilities(params *lsproto.InitializeParams) *lsproto.DiagnosticClientCapabilities {
1038+
if params == nil || params.Capabilities == nil || params.Capabilities.TextDocument == nil {
1039+
return nil
1040+
}
1041+
1042+
var caps lsproto.DiagnosticClientCapabilities
1043+
if params.Capabilities.TextDocument.Diagnostic != nil {
1044+
caps = *params.Capabilities.TextDocument.Diagnostic
1045+
}
1046+
1047+
// Some clients claim that push and pull diagnostics have different capabilities,
1048+
// including vscode-languageclient v9. Work around this by defaulting any missing
1049+
// pull diagnostic caps with the pull diagnostic equivalents.
1050+
//
1051+
// TODO: remove when we upgrade to vscode-languageclient v10, which fixes this issue.
1052+
if publish := params.Capabilities.TextDocument.PublishDiagnostics; publish != nil {
1053+
caps.RelatedInformation = core.Coalesce(caps.RelatedInformation, publish.RelatedInformation)
1054+
caps.TagSupport = core.Coalesce(caps.TagSupport, publish.TagSupport)
1055+
caps.CodeDescriptionSupport = core.Coalesce(caps.CodeDescriptionSupport, publish.CodeDescriptionSupport)
1056+
caps.DataSupport = core.Coalesce(caps.DataSupport, publish.DataSupport)
1057+
}
1058+
1059+
return &caps
1060+
}

0 commit comments

Comments
 (0)