Skip to content

Commit 8a4f583

Browse files
DanTupcommit-bot@chromium.org
authored andcommitted
Support Deprecated + Unnecessary diagnostic tags for LSP
Change-Id: I3915c2658e090caae40d126f6faff38620518950 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154468 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Danny Tuppeny <[email protected]>
1 parent 0f14f0e commit 8a4f583

File tree

5 files changed

+128
-10
lines changed

5 files changed

+128
-10
lines changed

pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,21 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
4545
return success(const []);
4646
}
4747

48-
final capabilities = server?.clientCapabilities?.textDocument?.codeAction;
48+
final capabilities = server?.clientCapabilities?.textDocument;
4949

5050
final clientSupportsWorkspaceApplyEdit =
5151
server?.clientCapabilities?.workspace?.applyEdit == true;
5252

5353
final clientSupportsLiteralCodeActions =
54-
capabilities?.codeActionLiteralSupport != null;
54+
capabilities?.codeAction?.codeActionLiteralSupport != null;
5555

5656
final clientSupportedCodeActionKinds = HashSet<CodeActionKind>.of(
57-
capabilities?.codeActionLiteralSupport?.codeActionKind?.valueSet ?? []);
57+
capabilities?.codeAction?.codeActionLiteralSupport?.codeActionKind
58+
?.valueSet ??
59+
[]);
60+
61+
final clientSupportedDiagnosticTags = HashSet<DiagnosticTag>.of(
62+
capabilities?.publishDiagnostics?.tagSupport?.valueSet ?? []);
5863

5964
final path = pathOfDoc(params.textDocument);
6065
final unit = await path.mapResult(requireResolvedUnit);
@@ -70,6 +75,7 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
7075
clientSupportedCodeActionKinds,
7176
clientSupportsLiteralCodeActions,
7277
clientSupportsWorkspaceApplyEdit,
78+
clientSupportedDiagnosticTags,
7379
path.result,
7480
params.range,
7581
offset,
@@ -185,6 +191,7 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
185191
HashSet<CodeActionKind> kinds,
186192
bool supportsLiterals,
187193
bool supportsWorkspaceApplyEdit,
194+
HashSet<DiagnosticTag> supportedDiagnosticTags,
188195
String path,
189196
Range range,
190197
int offset,
@@ -196,7 +203,8 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
196203
kinds, supportsLiterals, supportsWorkspaceApplyEdit, path),
197204
_getAssistActions(kinds, supportsLiterals, offset, length, unit),
198205
_getRefactorActions(kinds, supportsLiterals, path, offset, length, unit),
199-
_getFixActions(kinds, supportsLiterals, range, unit),
206+
_getFixActions(
207+
kinds, supportsLiterals, supportedDiagnosticTags, range, unit),
200208
]);
201209
final flatResults = results.expand((x) => x).toList();
202210

@@ -206,6 +214,7 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
206214
Future<List<Either2<Command, CodeAction>>> _getFixActions(
207215
HashSet<CodeActionKind> clientSupportedCodeActionKinds,
208216
bool clientSupportsLiteralCodeActions,
217+
HashSet<DiagnosticTag> supportedDiagnosticTags,
209218
Range range,
210219
ResolvedUnitResult unit,
211220
) async {
@@ -237,7 +246,11 @@ class CodeActionHandler extends MessageHandler<CodeActionParams,
237246
if (fixes.isNotEmpty) {
238247
fixes.sort(Fix.SORT_BY_RELEVANCE);
239248

240-
final diagnostic = toDiagnostic(unit, error);
249+
final diagnostic = toDiagnostic(
250+
unit,
251+
error,
252+
supportedTags: supportedDiagnosticTags,
253+
);
241254
codeActions.addAll(
242255
fixes.map((fix) => _createFixAction(fix, diagnostic)),
243256
);

pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,11 @@ class LspServerContextManagerCallbacks extends ContextManagerCallbacks {
660660
Folder folder, ContextRoot contextRoot, AnalysisOptions options) {
661661
var builder = createContextBuilder(folder, options);
662662
var analysisDriver = builder.buildDriver(contextRoot);
663+
final textDocumentCapabilities =
664+
analysisServer.clientCapabilities?.textDocument;
665+
final supportedDiagnosticTags = HashSet<DiagnosticTag>.of(
666+
textDocumentCapabilities?.publishDiagnostics?.tagSupport?.valueSet ??
667+
[]);
663668
analysisDriver.results.listen((result) {
664669
var path = result.path;
665670
if (analysisServer.shouldSendErrorsNotificationFor(path)) {
@@ -668,7 +673,12 @@ class LspServerContextManagerCallbacks extends ContextManagerCallbacks {
668673
result.errors
669674
.where((e) => e.errorCode.type != ErrorType.TODO)
670675
.toList(),
671-
toDiagnostic);
676+
(result, error, [severity]) => toDiagnostic(
677+
result,
678+
error,
679+
supportedTags: supportedDiagnosticTags,
680+
errorSeverity: severity,
681+
));
672682

673683
analysisServer.publishDiagnostics(result.path, serverErrors);
674684
}

pkg/analysis_server/lib/src/lsp/mapping.dart

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,25 @@ import 'package:analyzer/dart/analysis/results.dart' as server;
2828
import 'package:analyzer/diagnostic/diagnostic.dart' as analyzer;
2929
import 'package:analyzer/error/error.dart' as server;
3030
import 'package:analyzer/source/line_info.dart' as server;
31+
import 'package:analyzer/src/error/codes.dart';
3132
import 'package:analyzer/src/generated/source.dart' as server;
3233
import 'package:analyzer/src/services/available_declarations.dart';
3334
import 'package:analyzer/src/services/available_declarations.dart' as dec;
3435
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
3536
import 'package:analyzer_plugin/utilities/fixes/fixes.dart' as server;
37+
import 'package:meta/meta.dart';
38+
39+
const diagnosticTagsForErrorCode = <server.ErrorCode, List<lsp.DiagnosticTag>>{
40+
HintCode.DEAD_CODE: [lsp.DiagnosticTag.Unnecessary],
41+
HintCode.DEPRECATED_MEMBER_USE: [lsp.DiagnosticTag.Deprecated],
42+
HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE: [
43+
lsp.DiagnosticTag.Deprecated
44+
],
45+
HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE: [
46+
lsp.DiagnosticTag.Deprecated
47+
],
48+
HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE: [lsp.DiagnosticTag.Deprecated],
49+
};
3650

3751
const languageSourceName = 'dart';
3852

@@ -508,6 +522,19 @@ String getDeclarationCompletionDetail(
508522
}
509523
}
510524

525+
List<lsp.DiagnosticTag> getDiagnosticTags(
526+
HashSet<lsp.DiagnosticTag> supportedTags, server.AnalysisError error) {
527+
if (supportedTags == null) {
528+
return null;
529+
}
530+
531+
final tags = diagnosticTagsForErrorCode[error.errorCode]
532+
?.where(supportedTags.contains)
533+
?.toList();
534+
535+
return tags != null && tags.isNotEmpty ? tags : null;
536+
}
537+
511538
bool isDartDocument(lsp.TextDocumentIdentifier doc) =>
512539
doc?.uri?.endsWith('.dart');
513540

@@ -583,7 +610,6 @@ lsp.Diagnostic pluginToDiagnostic(
583610
code: error.code,
584611
source: languageSourceName,
585612
message: message,
586-
tags: null, // TODO(dantup): DiagnosticTags
587613
relatedInformation: relatedInformation,
588614
);
589615
}
@@ -799,8 +825,11 @@ lsp.CompletionItem toCompletionItem(
799825
}
800826

801827
lsp.Diagnostic toDiagnostic(
802-
server.ResolvedUnitResult result, server.AnalysisError error,
803-
[server.ErrorSeverity errorSeverity]) {
828+
server.ResolvedUnitResult result,
829+
server.AnalysisError error, {
830+
@required HashSet<lsp.DiagnosticTag> supportedTags,
831+
server.ErrorSeverity errorSeverity,
832+
}) {
804833
var errorCode = error.errorCode;
805834

806835
// Default to the error's severity if none is specified.
@@ -824,7 +853,7 @@ lsp.Diagnostic toDiagnostic(
824853
code: errorCode.name.toLowerCase(),
825854
source: languageSourceName,
826855
message: message,
827-
tags: null, // TODO(dantup): DiagnosticTags
856+
tags: getDiagnosticTags(supportedTags, error),
828857
relatedInformation: relatedInformation,
829858
);
830859
}

pkg/analysis_server/test/lsp/diagnostic_test.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,61 @@ void f() {
127127
expect(updatedDiagnostics, hasLength(0));
128128
}
129129

130+
Future<void> test_diagnosticTag_deprecated() async {
131+
newFile(mainFilePath, content: '''
132+
@deprecated
133+
int dep;
134+
135+
void main() => print(dep);
136+
''');
137+
138+
final diagnosticsUpdate = waitForDiagnostics(mainFileUri);
139+
await initialize(
140+
textDocumentCapabilities: withDiagnosticTagSupport(
141+
emptyTextDocumentClientCapabilities, [DiagnosticTag.Deprecated]));
142+
final diagnostics = await diagnosticsUpdate;
143+
expect(diagnostics, hasLength(1));
144+
final diagnostic = diagnostics.first;
145+
expect(diagnostic.code, equals('deprecated_member_use_from_same_package'));
146+
expect(diagnostic.tags, contains(DiagnosticTag.Deprecated));
147+
}
148+
149+
Future<void> test_diagnosticTag_notSupported() async {
150+
newFile(mainFilePath, content: '''
151+
@deprecated
152+
int dep;
153+
154+
void main() => print(dep);
155+
''');
156+
157+
final diagnosticsUpdate = waitForDiagnostics(mainFileUri);
158+
await initialize();
159+
final diagnostics = await diagnosticsUpdate;
160+
expect(diagnostics, hasLength(1));
161+
final diagnostic = diagnostics.first;
162+
expect(diagnostic.code, equals('deprecated_member_use_from_same_package'));
163+
expect(diagnostic.tags, isNull);
164+
}
165+
166+
Future<void> test_diagnosticTag_unnecessary() async {
167+
newFile(mainFilePath, content: '''
168+
void main() {
169+
return;
170+
print('unreachable');
171+
}
172+
''');
173+
174+
final diagnosticsUpdate = waitForDiagnostics(mainFileUri);
175+
await initialize(
176+
textDocumentCapabilities: withDiagnosticTagSupport(
177+
emptyTextDocumentClientCapabilities, [DiagnosticTag.Unnecessary]));
178+
final diagnostics = await diagnosticsUpdate;
179+
expect(diagnostics, hasLength(1));
180+
final diagnostic = diagnostics.first;
181+
expect(diagnostic.code, equals('dead_code'));
182+
expect(diagnostic.tags, contains(DiagnosticTag.Unnecessary));
183+
}
184+
130185
Future<void> test_dotFilesExcluded() async {
131186
var dotFolderFilePath =
132187
join(projectFolderPath, '.dart_tool', 'tool_file.dart');

pkg/analysis_server/test/lsp/server_abstract.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,17 @@ mixin ClientCapabilitiesHelperMixin {
279279
return extendWorkspaceCapabilities(source, {'configuration': true});
280280
}
281281

282+
TextDocumentClientCapabilities withDiagnosticTagSupport(
283+
TextDocumentClientCapabilities source,
284+
List<DiagnosticTag> tags,
285+
) {
286+
return extendTextDocumentCapabilities(source, {
287+
'publishDiagnostics': {
288+
'tagSupport': {'valueSet': tags.map((k) => k.toJson()).toList()}
289+
}
290+
});
291+
}
292+
282293
ClientCapabilitiesWorkspace withDidChangeConfigurationDynamicRegistration(
283294
ClientCapabilitiesWorkspace source,
284295
) {

0 commit comments

Comments
 (0)