diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index 8d0fb2e..b883e01 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -35,7 +35,7 @@ class ScipVisitor extends GeneralizingAstVisitor { packageConfig, pubspec, ) { - final fileSymbol = _symbolGenerator.fileSymbolFor(_relativePath); + final fileSymbol = _symbolGenerator.symbolForFile(_relativePath); occurrences.add(Occurrence( symbol: fileSymbol, range: [0, 0, 0], @@ -56,6 +56,8 @@ class ScipVisitor extends GeneralizingAstVisitor { _visitNormalFormalParameter(node); } else if (node is SimpleIdentifier) { _visitSimpleIdentifier(node); + } else if (node is Directive) { + _visitDirective(node); } super.visitNode(node); @@ -148,6 +150,27 @@ class ScipVisitor extends GeneralizingAstVisitor { } } + void _visitDirective(Directive node) { + final element = node.element!; + + StringLiteral uriLiteral; + if (node is UriBasedDirective) { + uriLiteral = node.uri; + } else if (node is PartOfDirective && node.uri != null) { + uriLiteral = node.uri!; + } else { + return; + } + + final symbol = _symbolGenerator.symbolForDirective(node, element); + if (symbol != null) { + occurrences.add(Occurrence( + range: _lineInfo.getRange(uriLiteral.offset, uriLiteral.length), + symbol: symbol, + )); + } + } + /// Registers the provided [element] as a reference to an existing definition /// /// [node] refers to the ast node where the reference exists, [element] diff --git a/lib/src/symbol_generator.dart b/lib/src/symbol_generator.dart index a57f4b3..96bf289 100644 --- a/lib/src/symbol_generator.dart +++ b/lib/src/symbol_generator.dart @@ -1,3 +1,4 @@ +import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:package_config/package_config.dart'; @@ -51,7 +52,7 @@ class SymbolGenerator { ].join(' '); } - String fileSymbolFor(String path) { + String symbolForFile(String path) { return [ 'scip-dart', 'pub ${_pubspec.name} ${_pubspec.version}', @@ -59,6 +60,54 @@ class SymbolGenerator { ].join(' '); } + String? symbolForDirective(Directive node, Element element) { + Uri uri; + if (element is LibraryImportElement) { + uri = (element.uri as DirectiveUriWithSource).source.uri; + } else if (element is LibraryExportElement) { + uri = (element.uri as DirectiveUriWithSource).source.uri; + } else if (element is PartElement) { + uri = (element.uri as DirectiveUriWithSource).source.uri; + } else if (node is PartOfDirective && element is LibraryElement) { + uri = element.source.uri; + } else { + return null; + } + + if (uri.toString().startsWith('dart')) { + final packageVersion = + element.library!.languageVersion.package.toString(); + return [ + 'scip-dart', + 'pub $uri $packageVersion', + _getPackage(element), + _escapeNamespacePath(_pathForSdkElement(element)) + '/' + ].join(' '); + } + + if (uri.toString().startsWith('package')) { + final resolvedUri = _packageConfig.resolve(uri); + if (resolvedUri == null) return null; + uri = resolvedUri; + } + + final config = _packageConfig.packageOf(uri); + if (config == null) return null; + + final relativePath = _escapeNamespacePath( + uri.toFilePath().substring(config.root.toFilePath().length), + ); + + final packageName = config.name; + final version = PackageVersionCache.versionFor(config.root.toFilePath()); + + return [ + 'scip-dart', + 'pub $packageName $version', + '$relativePath/', + ].join(' '); + } + /// Returns a scip package symbol for a provided [Element]. /// /// ::= ' ' ' ' diff --git a/lib/src/utils.dart b/lib/src/utils.dart index e4d1971..c0e97af 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -41,3 +41,12 @@ extension LineInfoExtension on LineInfo { ]; } } + +/// Removes single or double quotes from a string if they exist +String stripQuotes(String input) { + // check if input is wrapped in quotes. If it is, remove them + if (input.startsWith('"') && input.endsWith('"') || input.startsWith("'") && input.endsWith("'")) { + return input.substring(1, input.length -1); + } + return input; +} \ No newline at end of file diff --git a/snapshots/input/basic-project/lib/nested/directives.dart b/snapshots/input/basic-project/lib/nested/directives.dart new file mode 100644 index 0000000..4645cc2 --- /dev/null +++ b/snapshots/input/basic-project/lib/nested/directives.dart @@ -0,0 +1,7 @@ +import 'dart:math' as math; +import 'dart:collection'; +import 'package:dart_test/main.dart'; +import 'package:test/fake.dart'; +import '../other.dart'; +export '../relationships.dart'; +part 'directives_part.dart'; \ No newline at end of file diff --git a/snapshots/input/basic-project/lib/nested/directives_part.dart b/snapshots/input/basic-project/lib/nested/directives_part.dart new file mode 100644 index 0000000..ae41a94 --- /dev/null +++ b/snapshots/input/basic-project/lib/nested/directives_part.dart @@ -0,0 +1 @@ +part of 'directives.dart'; \ No newline at end of file diff --git a/snapshots/input/staging-project/pubspec.lock b/snapshots/input/staging-project/pubspec.lock index 89b205e..da077bb 100644 --- a/snapshots/input/staging-project/pubspec.lock +++ b/snapshots/input/staging-project/pubspec.lock @@ -1,5 +1,12 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile -packages: {} +packages: + collection: + dependency: "direct main" + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.17.1" sdks: dart: ">=2.18.0 <3.0.0" diff --git a/snapshots/input/staging-project/pubspec.yaml b/snapshots/input/staging-project/pubspec.yaml index 0137232..6481b13 100644 --- a/snapshots/input/staging-project/pubspec.yaml +++ b/snapshots/input/staging-project/pubspec.yaml @@ -3,3 +3,6 @@ version: 1.0.0 environment: sdk: ">=2.18.0 <3.0.0" + +dependencies: + collection: ^1.17.1 \ No newline at end of file diff --git a/snapshots/output/basic-project/lib/main.dart b/snapshots/output/basic-project/lib/main.dart index 37fd565..f07bb10 100755 --- a/snapshots/output/basic-project/lib/main.dart +++ b/snapshots/output/basic-project/lib/main.dart @@ -1,5 +1,6 @@ import 'package:dart_test/other.dart'; // definition scip-dart pub dart_test 1.0.0 lib/`main.dart`/ +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`other.dart`/ /// This is a fib function /// diff --git a/snapshots/output/basic-project/lib/more.dart b/snapshots/output/basic-project/lib/more.dart index 4b8c889..37ea4b9 100755 --- a/snapshots/output/basic-project/lib/more.dart +++ b/snapshots/output/basic-project/lib/more.dart @@ -1,5 +1,6 @@ import 'dart:math' as math; // definition scip-dart pub dart_test 1.0.0 lib/`more.dart`/ +// ^^^^^^^^^^^ reference scip-dart pub dart:math 2.18.0 pub dart_test 1.0.0 package:dart_test/`more.dart`/ // ^^^^ definition scip-dart pub dart_test 1.0.0 lib/`more.dart`/math. enum AnimalType { diff --git a/snapshots/output/basic-project/lib/nested/directives.dart b/snapshots/output/basic-project/lib/nested/directives.dart new file mode 100755 index 0000000..81c8b74 --- /dev/null +++ b/snapshots/output/basic-project/lib/nested/directives.dart @@ -0,0 +1,16 @@ + import 'dart:math' as math; +// definition scip-dart pub dart_test 1.0.0 lib/nested/`directives.dart`/ +// ^^^^^^^^^^^ reference scip-dart pub dart:math 2.18.0 pub dart_test 1.0.0 package:dart_test/nested/`directives.dart`/ +// ^^^^ definition scip-dart pub dart_test 1.0.0 lib/nested/`directives.dart`/math. + import 'dart:collection'; +// ^^^^^^^^^^^^^^^^^ reference scip-dart pub dart:collection 2.18.0 pub dart_test 1.0.0 package:dart_test/nested/`directives.dart`/ + import 'package:dart_test/main.dart'; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`main.dart`/ + import 'package:test/fake.dart'; +// ^^^^^^^^^^^^^^^^^^^^^^^^ reference scip-dart pub test 1.24.3 lib/`fake.dart`/ + import '../other.dart'; +// ^^^^^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`other.dart`/ + export '../relationships.dart'; +// ^^^^^^^^^^^^^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/ + part 'directives_part.dart'; +// ^^^^^^^^^^^^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/nested/`directives_part.dart`/ diff --git a/snapshots/output/basic-project/lib/nested/directives_part.dart b/snapshots/output/basic-project/lib/nested/directives_part.dart new file mode 100755 index 0000000..e3417e3 --- /dev/null +++ b/snapshots/output/basic-project/lib/nested/directives_part.dart @@ -0,0 +1,3 @@ + part of 'directives.dart'; +// definition scip-dart pub dart_test 1.0.0 lib/nested/`directives_part.dart`/ +// ^^^^^^^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/nested/`directives.dart`/ diff --git a/snapshots/output/basic-project/lib/other.dart b/snapshots/output/basic-project/lib/other.dart index 8bd2eef..84ce04b 100755 --- a/snapshots/output/basic-project/lib/other.dart +++ b/snapshots/output/basic-project/lib/other.dart @@ -1,5 +1,6 @@ import 'more.dart' deferred as more; // definition scip-dart pub dart_test 1.0.0 lib/`other.dart`/ +// ^^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`more.dart`/ // ^^^^ definition scip-dart pub dart_test 1.0.0 lib/`other.dart`/more. class Foo { diff --git a/snapshots/output/basic-project/test/basic_test.dart b/snapshots/output/basic-project/test/basic_test.dart index 3ed3773..d871c18 100755 --- a/snapshots/output/basic-project/test/basic_test.dart +++ b/snapshots/output/basic-project/test/basic_test.dart @@ -1,5 +1,6 @@ import 'package:test/test.dart'; // definition scip-dart pub dart_test 1.0.0 test/`basic_test.dart`/ +// ^^^^^^^^^^^^^^^^^^^^^^^^ reference scip-dart pub test 1.24.3 lib/`test.dart`/ void main() { // ^^^^ definition scip-dart pub dart_test 1.0.0 test/`basic_test.dart`/main().