Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/src/indexer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Future<Index> indexPackage(
relativePath,
dirPath,
resUnit.lineInfo,
resUnit.errors,
packageConfig,
pubspec,
);
Expand Down
57 changes: 55 additions & 2 deletions lib/src/metadata.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:scip_dart/src/gen/scip.pb.dart' as proto;

/// The collection of AnalysisHint codes that should be considered "Unused".
/// Annoyingly dart does not export their AnalysisHint, if this ever changes
/// these should directly reference the instances within:
/// https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/lib/src/error/codes.g.dart
const _unusedHintCodes = {
'UNUSED_CATCH_CLAUSE',
'UNUSED_CATCH_STACK',
'UNUSED_ELEMENT',
'UNUSED_ELEMENT_PARAMETER',
'UNUSED_FIELD',
'UNUSED_IMPORT',
'UNUSED_LABEL',
'UNUSED_RESULT',
'UNUSED_SHOWN_NAME',
};

/// Refers to any additional metadata attached to a `SymbolInformation`
/// struct on the protobuf spec.
Expand All @@ -8,14 +28,20 @@ import 'package:analyzer/dart/element/element.dart';
class SymbolMetadata {
List<String> documentation;

SymbolMetadata({required this.documentation});
List<proto.Diagnostic>? diagnostics;

SymbolMetadata({required this.documentation, this.diagnostics});
}

/// Returns a [SymbolMetadata] object for a provided [Element] type.
///
/// This information is used to embellish `SymbolInformation` struct's
/// within the protobuf schema for scip
SymbolMetadata getSymbolMetadata(Element element) {
SymbolMetadata getSymbolMetadata(
Element element,
AstNode node,
List<AnalysisError> analysisErrors,
) {
final displayString = element.getDisplayString(
withNullability: false,
multiline: true,
Expand All @@ -26,10 +52,37 @@ SymbolMetadata getSymbolMetadata(Element element) {
'',
);

final diagnostics = analysisErrors
.where((error) => error.offset == node.offset)
.map((error) => proto.Diagnostic(
code: error.errorCode.name,
message: error.message,
severity: error.severity.toProto(),
tags: [
if (element.hasDeprecated) proto.DiagnosticTag.Deprecated,
if (_unusedHintCodes.contains(error.errorCode.uniqueName))
proto.DiagnosticTag.Unnecessary,
]))
.toList();

return SymbolMetadata(
documentation: [
'```dart\n$displayString\n```',
if (docComment != null) docComment
],
diagnostics: diagnostics.isNotEmpty ? diagnostics : null,
);
}

extension _SeverityConverter on Severity {
proto.Severity toProto() {
switch (this) {
case Severity.error:
return proto.Severity.Error;
case Severity.warning:
return proto.Severity.Warning;
case Severity.info:
return proto.Severity.Information;
}
}
}
23 changes: 17 additions & 6 deletions lib/src/scip_visitor.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:package_config/package_config.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
Expand All @@ -17,6 +18,7 @@ class ScipVisitor extends GeneralizingAstVisitor {
final String _relativePath;
final String _projectRoot;
final LineInfo _lineInfo;
final List<AnalysisError> _analysisErrors;

final SymbolGenerator _symbolGenerator;

Expand All @@ -27,6 +29,7 @@ class ScipVisitor extends GeneralizingAstVisitor {
this._relativePath,
this._projectRoot,
this._lineInfo,
this._analysisErrors,
PackageConfig packageConfig,
Pubspec pubspec,
) : _symbolGenerator = SymbolGenerator(
Expand Down Expand Up @@ -71,6 +74,7 @@ class ScipVisitor extends GeneralizingAstVisitor {

_registerAsDefinition(
element,
node,
relationships: relationships,
);
}
Expand All @@ -91,12 +95,13 @@ class ScipVisitor extends GeneralizingAstVisitor {
final fieldElement = (element as FieldFormalParameterElement).field;
_registerAsReference(
fieldElement!,
node,
offset: node.thisKeyword.offset,
length: node.thisKeyword.length,
);
}

_registerAsDefinition(element);
_registerAsDefinition(element, node);
}

void _visitSimpleIdentifier(SimpleIdentifier node) {
Expand Down Expand Up @@ -135,10 +140,11 @@ class ScipVisitor extends GeneralizingAstVisitor {
if (element == null || element.source == null) return;

if (node.inDeclarationContext()) {
_registerAsDefinition(element);
_registerAsDefinition(element, node);
} else {
_registerAsReference(
element,
node,
offset: node.offset,
length: node.name.length,
);
Expand All @@ -153,22 +159,25 @@ class ScipVisitor extends GeneralizingAstVisitor {
/// If [element] exists outside of the projects source, it will be added to the
/// [globalExternalSymbols].
void _registerAsReference(
Element element, {
Element element,
AstNode node, {
required int offset,
required int length,
}) {
final symbol = _symbolGenerator.symbolFor(element);
if (symbol != null) {
final meta = getSymbolMetadata(element, node, _analysisErrors);
occurrences.add(Occurrence(
range: _lineInfo.getRange(offset, length),
symbol: symbol,
diagnostics: meta.diagnostics,
));

if (!element.source!.fullName.startsWith(_projectRoot)) {
if (!globalExternalSymbols.any(
(symbolInfo) => symbolInfo.symbol == symbol,
)) {
final meta = getSymbolMetadata(element);
final meta = getSymbolMetadata(element, node, _analysisErrors);
globalExternalSymbols.add(SymbolInformation(
symbol: symbol,
documentation: meta.documentation,
Expand All @@ -183,12 +192,13 @@ class ScipVisitor extends GeneralizingAstVisitor {
/// This adds both a symbol, and an occurrence for the element and it's
/// name
void _registerAsDefinition(
Element element, {
Element element,
AstNode node, {
List<Relationship>? relationships,
}) {
final symbol = _symbolGenerator.symbolFor(element);
if (symbol != null) {
final meta = getSymbolMetadata(element);
final meta = getSymbolMetadata(element, node, _analysisErrors);
symbols.add(SymbolInformation(
symbol: symbol,
documentation: meta.documentation,
Expand All @@ -199,6 +209,7 @@ class ScipVisitor extends GeneralizingAstVisitor {
range: _lineInfo.getRange(element.nameOffset, element.nameLength),
symbol: symbol,
symbolRoles: SymbolRole.Definition.value,
diagnostics: meta.diagnostics,
));
}
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.17.2"
version: "1.18.0"
convert:
dependency: transitive
description:
Expand Down