From 6d68d5cc7707eca3f135577b60f926824660f9b4 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Thu, 30 Mar 2023 21:06:10 -0500 Subject: [PATCH 1/4] different take on directive imports --- lib/src/scip_visitor.dart | 37 ++++++++++++++++++++++++++++++++++++- lib/src/symbol.dart | 29 ++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index 699ac91..5ebe9a2 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -32,7 +32,7 @@ class ScipVisitor extends GeneralizingAstVisitor { _projectRoot, pubspec, ) { - final fileSymbol = _symbolGenerator.fileSymbolFor(_relativePath); + final fileSymbol = _symbolGenerator.fileSymbolForPath(_relativePath); occurrences.add(Occurrence( symbol: fileSymbol, range: [0, 0, 0], @@ -60,6 +60,8 @@ class ScipVisitor extends GeneralizingAstVisitor { _visitNormalFormalParameter(node); } else if (node is SimpleIdentifier) { _visitSimpleIdentifier(node); + } else if (node is Directive) { + _visitDirective(node); } super.visitNode(node); @@ -107,6 +109,39 @@ 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; + } + + // uri is a non-relative, package (or dart sdk) uri: + // Eg: `package:/.dart`, `dart:` + + // 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; + // } + + _symbolGenerator.symbolFor(element!); + + // _symbolGenerator.fileSymbolForUri(uri); + } + /// 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.dart b/lib/src/symbol.dart index f2e7414..287437b 100644 --- a/lib/src/symbol.dart +++ b/lib/src/symbol.dart @@ -56,7 +56,7 @@ class SymbolGenerator { ].join(' '); } - String fileSymbolFor(String path) { + String fileSymbolForPath(String path) { return [ 'scip-dart', 'pub ${_pubspec.name} ${_pubspec.version}', @@ -219,6 +219,33 @@ class SymbolGenerator { return '${_getDescriptor(encEle)}${element.name}.'; } + if ( + element is LibraryImportElement || + element is LibraryExportElement || + element is PartElement + ) { + DirectiveUriWithSource directiveUri; + if (element is LibraryImportElement) { + directiveUri = element.uri as DirectiveUriWithSource; + } else if (element is LibraryExportElement) { + directiveUri = element.uri as DirectiveUriWithSource; + } else if (element is PartElement) { + directiveUri = element.uri as DirectiveUriWithSource; + } else { + return null; + } + + final config = _packageConfig.packageOf(Uri.file(sourcePath)); + if (config == null) { + throw Exception('Could not find package for $sourcePath. Have you run pub get?'); + } + + return _escapeNamespacePath( + sourcePath.substring(config.root.toFilePath().length), + ); + } + + display('\n' 'Received unknown type (${element.runtimeType})\n' '\tname: ${element.name}\n' From a100d0c599c91c34d4c4e3344be3566901511040 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Mon, 3 Apr 2023 17:51:12 -0600 Subject: [PATCH 2/4] s --- lib/src/scip_visitor.dart | 2 +- lib/src/symbol.dart | 15 +++++++++++---- snapshots/input/staging-project/pubspec.lock | 9 ++++++++- snapshots/input/staging-project/pubspec.yaml | 3 +++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index 5ebe9a2..a2b42b1 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -32,7 +32,7 @@ class ScipVisitor extends GeneralizingAstVisitor { _projectRoot, pubspec, ) { - final fileSymbol = _symbolGenerator.fileSymbolForPath(_relativePath); + final fileSymbol = _symbolGenerator.symbolForFile(_relativePath); occurrences.add(Occurrence( symbol: fileSymbol, range: [0, 0, 0], diff --git a/lib/src/symbol.dart b/lib/src/symbol.dart index 287437b..2cf1f79 100644 --- a/lib/src/symbol.dart +++ b/lib/src/symbol.dart @@ -55,8 +55,8 @@ class SymbolGenerator { _getDescriptor(element), ].join(' '); } - - String fileSymbolForPath(String path) { + + String symbolForFile(String path) { return [ 'scip-dart', 'pub ${_pubspec.name} ${_pubspec.version}', @@ -78,9 +78,10 @@ class SymbolGenerator { if (_isInSdk(element)) { return _sdkPackageSymbolFor(element); - } else if (_isInCurrentPackage(element)) { - return _currentPackageSymbolFor(element); } + // } else if (_isInCurrentPackage(element)) { + // return _currentPackageSymbolFor(element); + // } return _externalPackageSymbolFor(element); } @@ -106,6 +107,12 @@ class SymbolGenerator { throw Exception('Unable to find package within packageConfig'); } + // print(element.library?.); + // final pk = element.metadata.firstWhere( + // (e) => e.computeConstantValue()?.type?.n == 'Package', + // orElse: () => null, + // ).computeConstantValue()?.toMap(); + final packageName = package.name; final rootPath = p.basename(package.root.toString()); 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 From 49415ab7bbd077a4cccd1e2813eff5d5c5907d24 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Sun, 9 Apr 2023 23:52:49 -0600 Subject: [PATCH 3/4] semi working implementation --- lib/src/scip_visitor.dart | 34 +++++++++----------------- lib/src/symbol.dart | 51 ++++++++++++++++++++++++++++++++++++--- lib/src/utils.dart | 9 +++++++ 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index 4e76fe9..0cae10d 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -8,6 +8,7 @@ import 'package:scip_dart/src/metadata.dart'; import 'package:scip_dart/src/gen/scip.pb.dart'; import 'package:scip_dart/src/symbol.dart'; import 'package:scip_dart/src/utils.dart'; +import 'package:path/path.dart' as p; List globalExternalSymbols = []; @@ -15,6 +16,7 @@ class ScipVisitor extends GeneralizingAstVisitor { final String _relativePath; final String _projectRoot; final LineInfo _lineInfo; + final PackageConfig _packageConfig; final SymbolGenerator _symbolGenerator; @@ -25,10 +27,10 @@ class ScipVisitor extends GeneralizingAstVisitor { this._relativePath, this._projectRoot, this._lineInfo, - PackageConfig packageConfig, + this._packageConfig, Pubspec pubspec, ) : _symbolGenerator = SymbolGenerator( - packageConfig, + _packageConfig, _projectRoot, pubspec, ) { @@ -103,7 +105,7 @@ class ScipVisitor extends GeneralizingAstVisitor { } void _visitDirective(Directive node) { - final element = node.element; + final element = node.element!; StringLiteral uriLiteral; if (node is UriBasedDirective) { @@ -114,25 +116,13 @@ class ScipVisitor extends GeneralizingAstVisitor { return; } - // uri is a non-relative, package (or dart sdk) uri: - // Eg: `package:/.dart`, `dart:` - - // 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; - // } - - _symbolGenerator.symbolFor(element!); - - // _symbolGenerator.fileSymbolForUri(uri); + 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 diff --git a/lib/src/symbol.dart b/lib/src/symbol.dart index 736738f..d229497 100644 --- a/lib/src/symbol.dart +++ b/lib/src/symbol.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'; @@ -64,6 +65,52 @@ 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')) { + return [ + _getPackage(element), + _escapeNamespacePath(_pathForSdkElement(element)) + '/' + ].join(' '); + } else { + + } + + 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]. /// /// ::= ' ' ' ' @@ -84,9 +131,6 @@ class SymbolGenerator { element.library!.languageVersion.package.toString(); return 'pub $packageName $packageVersion'; } - // } else if (_isInCurrentPackage(element)) { - // return _currentPackageSymbolFor(element); - // } final package = _packageConfig.packageOf(Uri.file(element.source!.fullName)); @@ -233,7 +277,6 @@ class SymbolGenerator { ); } - display( '\n' 'Received unknown type (${element.runtimeType})\n' diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 159f7ef..825814d 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -29,3 +29,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 From f42284a2ebd355552fe1bc168d2c285205874c11 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Wed, 7 Feb 2024 16:02:05 -0700 Subject: [PATCH 4/4] more work on symbol generation --- lib/src/symbol_generator.dart | 34 +++---------------- .../basic-project/lib/nested/directives.dart | 7 ++++ .../lib/nested/directives_part.dart | 1 + snapshots/output/basic-project/lib/main.dart | 1 + snapshots/output/basic-project/lib/more.dart | 1 + .../basic-project/lib/nested/directives.dart | 16 +++++++++ .../lib/nested/directives_part.dart | 3 ++ snapshots/output/basic-project/lib/other.dart | 1 + .../output/basic-project/test/basic_test.dart | 1 + 9 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 snapshots/input/basic-project/lib/nested/directives.dart create mode 100644 snapshots/input/basic-project/lib/nested/directives_part.dart create mode 100755 snapshots/output/basic-project/lib/nested/directives.dart create mode 100755 snapshots/output/basic-project/lib/nested/directives_part.dart diff --git a/lib/src/symbol_generator.dart b/lib/src/symbol_generator.dart index 5bc5f4c..96bf289 100644 --- a/lib/src/symbol_generator.dart +++ b/lib/src/symbol_generator.dart @@ -51,7 +51,7 @@ class SymbolGenerator { _getDescriptor(element), ].join(' '); } - + String symbolForFile(String path) { return [ 'scip-dart', @@ -75,12 +75,14 @@ class SymbolGenerator { } if (uri.toString().startsWith('dart')) { + final packageVersion = + element.library!.languageVersion.package.toString(); return [ + 'scip-dart', + 'pub $uri $packageVersion', _getPackage(element), _escapeNamespacePath(_pathForSdkElement(element)) + '/' ].join(' '); - } else { - } if (uri.toString().startsWith('package')) { @@ -246,32 +248,6 @@ class SymbolGenerator { return '${_getDescriptor(encEle)}${element.name}.'; } - if ( - element is LibraryImportElement || - element is LibraryExportElement || - element is PartElement - ) { - DirectiveUriWithSource directiveUri; - if (element is LibraryImportElement) { - directiveUri = element.uri as DirectiveUriWithSource; - } else if (element is LibraryExportElement) { - directiveUri = element.uri as DirectiveUriWithSource; - } else if (element is PartElement) { - directiveUri = element.uri as DirectiveUriWithSource; - } else { - return null; - } - - final config = _packageConfig.packageOf(Uri.file(sourcePath)); - if (config == null) { - throw Exception('Could not find package for $sourcePath. Have you run pub get?'); - } - - return _escapeNamespacePath( - sourcePath.substring(config.root.toFilePath().length), - ); - } - display( '\n' 'Received unknown type (${element.runtimeType})\n' 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/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().