Initial @tool annotation support in the Dart Analysis Server
There is still required IntelliJ work to have this work end to end
Change-Id: I44cea5baee24e0b1c641d329b3d19eb7733f2003
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222840
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Jaime Wren <jwren@google.com>
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 8d5106f..5ad2871 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -253,6 +253,52 @@
}
@override
+ void visitComment(Comment node) {
+ for (var commentReference in node.references) {
+ commentReference.accept(this);
+ }
+
+ var inToolAnnotation = false;
+ for (var token in node.tokens) {
+ if (token.isEof) {
+ break;
+ }
+ var strValue = token.toString();
+ if (strValue.isEmpty) {
+ continue;
+ }
+
+ if (inToolAnnotation) {
+ if (strValue.contains('{@end-tool}')) {
+ inToolAnnotation = false;
+ } else if (strValue.contains('** See code in ')) {
+ var startIndex = strValue.indexOf('** See code in ') + 15;
+ var endIndex = strValue.indexOf('.dart') + 5;
+ var pathSnippet = strValue.substring(startIndex, endIndex);
+ var parentPath =
+ _computeParentWithExamplesAPI(node, resourceProvider);
+ if (parentPath != null) {
+ computer.collector.addRegion(
+ token.offset + startIndex,
+ token.offset + endIndex,
+ protocol.ElementKind.LIBRARY,
+ protocol.Location(
+ resourceProvider.pathContext.join(parentPath, pathSnippet),
+ 0,
+ 0,
+ 0,
+ 0,
+ endLine: 0,
+ endColumn: 0));
+ }
+ }
+ } else if (strValue.contains('{@tool ')) {
+ inToolAnnotation = true;
+ }
+ }
+ }
+
+ @override
void visitCompilationUnit(CompilationUnit unit) {
// prepare top-level nodes sorted by their offsets
var nodes = <AstNode>[];
@@ -476,4 +522,31 @@
}
}
}
+
+ /// Given some [Comment], compute and return the parent directory absolute
+ /// path which contains the directories 'examples/api/'. Null is returned if
+ /// such directories are not found.
+ String? _computeParentWithExamplesAPI(
+ Comment node, ResourceProvider resourceProvider) {
+ var source =
+ node.thisOrAncestorOfType<CompilationUnit>()?.declaredElement?.source;
+ if (source == null) {
+ return null;
+ }
+
+ var file = resourceProvider.getFile(source.fullName);
+ if (!file.exists) {
+ return null;
+ }
+ var parent = file.parent2;
+ while (parent != parent.parent2) {
+ var examplesFolder = parent.getChildAssumingFolder('examples');
+ if (examplesFolder.exists &&
+ examplesFolder.getChildAssumingFolder('api').exists) {
+ return parent.path;
+ }
+ parent = parent.parent2;
+ }
+ return null;
+ }
}