From bd701142e25e8824a33204bedd80fea538758350 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Mon, 6 Mar 2023 10:49:31 -0700 Subject: [PATCH 1/3] fixed some issues with declaration vs references --- .gitignore | 4 +- Makefile | 8 +- lib/src/scip_visitor.dart | 102 ++++++++++++------- lib/src/symbol.dart | 11 +- snapshots/input/basic-project/lib/more.dart | 4 +- snapshots/input/staging-project/README.md | 3 + snapshots/input/staging-project/pubspec.lock | 5 + snapshots/input/staging-project/pubspec.yaml | 5 + snapshots/output/basic-project/lib/more.dart | 8 +- 9 files changed, 103 insertions(+), 47 deletions(-) create mode 100644 snapshots/input/staging-project/README.md create mode 100644 snapshots/input/staging-project/pubspec.lock create mode 100644 snapshots/input/staging-project/pubspec.yaml diff --git a/.gitignore b/.gitignore index 26d2551..79e5818 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .dart_tool .DS_Store -index.scip \ No newline at end of file +index.scip +snapshots/input/staging-project/lib/** +snapshots/output/staging-project/lib/** diff --git a/Makefile b/Makefile index 1ce64fa..d34d184 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,12 @@ +regen-snaps: + dart run scip_dart ./snapshots/input/basic-project --verbose + scip snapshot --to ./snapshots/output/basic-project + run: - dart bin/main.dart ./snapshots/input/basic-project --verbose + dart run scip_dart ./snapshots/input/staging-project --verbose snap: - scip snapshot --to ./snapshots/output/basic-project + scip snapshot --to ./snapshots/output/staging-project lint: scip lint ./index.scip diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index cedaf03..234f0df 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -44,6 +44,7 @@ class ScipVisitor extends GeneralizingAstVisitor { @override void visitNode(AstNode node) { + // print(':: $node ${node.runtimeType}'); if (node is Comment) { // For now, don't parse anything within comments (this was broken for // local references). Later update to support this @@ -55,8 +56,8 @@ class ScipVisitor extends GeneralizingAstVisitor { // to correctly parse all [Declaration] ast nodes. if (node is Declaration) { _visitDeclaration(node); - } else if (node is SimpleFormalParameter) { - _visitSimpleFormalParameter(node); + } else if (node is NormalFormalParameter) { + _visitNormalFormalParameter(node); } else if (node is SimpleIdentifier) { _visitSimpleIdentifier(node); } @@ -68,38 +69,26 @@ class ScipVisitor extends GeneralizingAstVisitor { if (node.declaredElement == null) return; final element = node.declaredElement!; - - final symbol = _symbolGenerator.symbolFor(element); - if (symbol != null) { - _registerSymbol(symbol, element); - - occurrences.add(Occurrence( - range: _lineInfo.getRange(element.nameOffset, element.nameLength), - symbol: symbol, - symbolRoles: SymbolRole.Definition.value, - )); - } + _registerAsDefinition(element); } - void _visitSimpleFormalParameter(SimpleFormalParameter node) { - if (node.declaredElement == null) return; - - final element = node.declaredElement!; - - final symbol = _symbolGenerator.symbolFor(element); - if (symbol != null) { - _registerSymbol(symbol, element); - - occurrences.add(Occurrence( - range: _lineInfo.getRange(element.nameOffset, element.nameLength), - symbol: symbol, - symbolRoles: SymbolRole.Definition.value, - )); + void _visitNormalFormalParameter(NormalFormalParameter node) { + final element = node.declaredElement; + if (element == null) return; + + // FieldFormalParameters reference a field instead of define a declaration + // register them as such + if (element is FieldFormalParameterElement) { + _registerAsReference( + element.field!, + offset: node.name!.offset, + length: node.name!.length, + ); + } else { + _registerAsDefinition(element); } } - // references to a type, String, int, SomeClass... anything that can be GoTo'ed - // This will be utilized for defining `Occurrences` void _visitSimpleIdentifier(SimpleIdentifier node) { final element = node.staticElement; @@ -108,16 +97,40 @@ class ScipVisitor extends GeneralizingAstVisitor { // EX: `color(path, front: Styles.YELLOW);` where `color` comes from the chalk-dart package if (element == null || element.source == null) return; + if (node.inDeclarationContext()) { + _registerAsDefinition(element); + } else { + _registerAsReference( + element, + offset: node.offset, + length: node.name.length, + ); + } + } + + /// Registers the provided [element] as a reference to an existing definition + /// + /// [node] refers to the ast node where the reference exists, [element] + /// is the resolved element of the downstream element. + /// + /// If [element] exists outside of the projects source, it will be added to the + /// [globalExternalSymbols]. + void _registerAsReference( + Element element, { + required int offset, + required int length, + }) { final symbol = _symbolGenerator.symbolFor(element); if (symbol != null) { occurrences.add(Occurrence( - range: _lineInfo.getRange(node.offset, node.name.length), + range: _lineInfo.getRange(offset, length), symbol: symbol, )); if (!element.source!.fullName.startsWith(_projectRoot)) { - if (globalExternalSymbols - .every((symbolInfo) => symbolInfo.symbol != symbol)) { + if (!globalExternalSymbols.any( + (symbolInfo) => symbolInfo.symbol == symbol, + )) { final meta = getSymbolMetadata(element); globalExternalSymbols.add(SymbolInformation( symbol: symbol, @@ -128,11 +141,24 @@ class ScipVisitor extends GeneralizingAstVisitor { } } - void _registerSymbol(String symbol, Element ele) { - final meta = getSymbolMetadata(ele); - symbols.add(SymbolInformation( - symbol: symbol, - documentation: meta.documentation, - )); + /// Registers a provided [element] as a definition + /// + /// This adds both a symbol, and an occurrence for the element and it's + /// name + void _registerAsDefinition(Element element) { + final symbol = _symbolGenerator.symbolFor(element); + if (symbol != null) { + final meta = getSymbolMetadata(element); + symbols.add(SymbolInformation( + symbol: symbol, + documentation: meta.documentation, + )); + + occurrences.add(Occurrence( + range: _lineInfo.getRange(element.nameOffset, element.nameLength), + symbol: symbol, + symbolRoles: SymbolRole.Definition.value, + )); + } } } diff --git a/lib/src/symbol.dart b/lib/src/symbol.dart index 118bcaf..29d5ccc 100644 --- a/lib/src/symbol.dart +++ b/lib/src/symbol.dart @@ -35,9 +35,12 @@ class SymbolGenerator { return _localSymbolFor(element); } - // named parameters can be "goto'd" on the consuming symbol, and are not "local" - if (element is ParameterElement && !element.isNamed) { - return _localSymbolFor(element); + // most parameters are local only, treat them as such except for the edge cases + if (element is ParameterElement) { + // named parameters and fieldFormalParameters can be goto'd + if (!element.isNamed && element is! FieldFormalParameterElement) { + return _localSymbolFor(element); + } } // for some reason, LibraryImportElement is considered to be "private" @@ -203,7 +206,7 @@ class SymbolGenerator { } // only generate symbols for named parameters, all others are 'local x' - if (element is ParameterElement && element.isNamed) { + if (element is ParameterElement) { final encEle = element.enclosingElement; if (encEle == null) { display('Parameter element has null enclosingElement "$element"'); diff --git a/snapshots/input/basic-project/lib/more.dart b/snapshots/input/basic-project/lib/more.dart index 3efeba0..3a590dd 100644 --- a/snapshots/input/basic-project/lib/more.dart +++ b/snapshots/input/basic-project/lib/more.dart @@ -1,4 +1,4 @@ -import 'dart:math'; +import 'dart:math' as math; enum AnimalType { cat, @@ -65,4 +65,6 @@ void main() { print(cat); print(dog); print('The sum of $numbers is $sum'); + + print(math.Rectangle(1,2,3,4)); } diff --git a/snapshots/input/staging-project/README.md b/snapshots/input/staging-project/README.md new file mode 100644 index 0000000..ebe838d --- /dev/null +++ b/snapshots/input/staging-project/README.md @@ -0,0 +1,3 @@ +# snapshots/staging-project + +This project is designed to be used as a place to test/stage small implementations of dart source. No changes within `lib/` are committed \ No newline at end of file diff --git a/snapshots/input/staging-project/pubspec.lock b/snapshots/input/staging-project/pubspec.lock new file mode 100644 index 0000000..89b205e --- /dev/null +++ b/snapshots/input/staging-project/pubspec.lock @@ -0,0 +1,5 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: {} +sdks: + dart: ">=2.18.0 <3.0.0" diff --git a/snapshots/input/staging-project/pubspec.yaml b/snapshots/input/staging-project/pubspec.yaml new file mode 100644 index 0000000..0137232 --- /dev/null +++ b/snapshots/input/staging-project/pubspec.yaml @@ -0,0 +1,5 @@ +name: dart_test +version: 1.0.0 + +environment: + sdk: ">=2.18.0 <3.0.0" diff --git a/snapshots/output/basic-project/lib/more.dart b/snapshots/output/basic-project/lib/more.dart index b842197..c6a5bd4 100755 --- a/snapshots/output/basic-project/lib/more.dart +++ b/snapshots/output/basic-project/lib/more.dart @@ -1,5 +1,6 @@ - import 'dart:math'; + import 'dart:math' as math; // definition scip-dart pub dart_test 1.0.0 lib/more.dart/ +// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/math. enum AnimalType { // ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType# @@ -169,5 +170,10 @@ // ^^^^^ reference scip-dart pub dart:core 2.18.0 lib/core/print.dart/print(). // ^^^^^^^ reference local 3 // ^^^ reference local 4 + + print(math.Rectangle(1,2,3,4)); +// ^^^^^ reference scip-dart pub dart:core 2.18.0 lib/core/print.dart/print(). +// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/math. +// ^^^^^^^^^ reference scip-dart pub dart:math 2.18.0 lib/math/rectangle.dart/Rectangle# } From 67be4d5afaef01dd287ed4761067d0a094536cb3 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Mon, 6 Mar 2023 11:00:40 -0700 Subject: [PATCH 2/3] regen-snaps --- Makefile | 2 +- snapshots/output/basic-project/lib/more.dart | 5 ++++- snapshots/output/basic-project/lib/other.dart | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d34d184..5ee2a9b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -regen-snaps: +regen-snapshots: dart run scip_dart ./snapshots/input/basic-project --verbose scip snapshot --to ./snapshots/output/basic-project diff --git a/snapshots/output/basic-project/lib/more.dart b/snapshots/output/basic-project/lib/more.dart index c6a5bd4..83f1967 100755 --- a/snapshots/output/basic-project/lib/more.dart +++ b/snapshots/output/basic-project/lib/more.dart @@ -1,6 +1,7 @@ import 'dart:math' as math; // definition scip-dart pub dart_test 1.0.0 lib/more.dart/ -// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/math. +// ^^^^ definition scip-dart pub dart_test 1.0.0 lib/more.dart/math. +// documentation ```dart enum AnimalType { // ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType# @@ -52,6 +53,8 @@ // ^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#(). // documentation ```dart // ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal# +// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#name. +// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#type. switch (type) { // ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#type. case AnimalType.cat: diff --git a/snapshots/output/basic-project/lib/other.dart b/snapshots/output/basic-project/lib/other.dart index f7f4392..b5373a0 100755 --- a/snapshots/output/basic-project/lib/other.dart +++ b/snapshots/output/basic-project/lib/other.dart @@ -10,5 +10,6 @@ // ^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#(). // documentation ```dart // ^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo# +// ^^^^ reference local 0 } From 175bdd55b1e70847017d2677fdcbc18d3d22f280 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Mon, 6 Mar 2023 11:07:12 -0700 Subject: [PATCH 3/3] removed old approach --- lib/src/symbol.dart | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/src/symbol.dart b/lib/src/symbol.dart index 29d5ccc..118bcaf 100644 --- a/lib/src/symbol.dart +++ b/lib/src/symbol.dart @@ -35,12 +35,9 @@ class SymbolGenerator { return _localSymbolFor(element); } - // most parameters are local only, treat them as such except for the edge cases - if (element is ParameterElement) { - // named parameters and fieldFormalParameters can be goto'd - if (!element.isNamed && element is! FieldFormalParameterElement) { - return _localSymbolFor(element); - } + // named parameters can be "goto'd" on the consuming symbol, and are not "local" + if (element is ParameterElement && !element.isNamed) { + return _localSymbolFor(element); } // for some reason, LibraryImportElement is considered to be "private" @@ -206,7 +203,7 @@ class SymbolGenerator { } // only generate symbols for named parameters, all others are 'local x' - if (element is ParameterElement) { + if (element is ParameterElement && element.isNamed) { final encEle = element.enclosingElement; if (encEle == null) { display('Parameter element has null enclosingElement "$element"');