From 8d865b766a3b887c7bd3a9fba46514d5475795b7 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Thu, 13 Apr 2023 09:48:45 -0600 Subject: [PATCH 1/4] index fields --- lib/src/scip_visitor.dart | 18 +++++++++++++++++- snapshots/output/basic-project/lib/more.dart | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index eb65dff..fc870fb 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -44,6 +44,8 @@ class ScipVisitor extends GeneralizingAstVisitor { @override void visitNode(AstNode node) { + // print('$node :: ${node.runtimeType}'); + // [visitDeclaration] on the [GeneralizingAstVisitor] does not match parameters // even though the parameter node extends [Declaration]. This is a workaround // to correctly parse all [Declaration] ast nodes. @@ -82,7 +84,21 @@ class ScipVisitor extends GeneralizingAstVisitor { } void _visitSimpleIdentifier(SimpleIdentifier node) { - final element = node.staticElement; + var element = node.staticElement; + + if (node.parent is CompoundAssignmentExpression) { + final assignmentNode = node.parent as CompoundAssignmentExpression; + element = assignmentNode.readElement ?? assignmentNode.writeElement!; + } else if (node.parent?.parent is AssignmentExpression) { + final assignment = node.parent!.parent as AssignmentExpression; + element = assignment.readElement ?? assignment.writeElement!; + } + + // When the identifier is a field, the analyzer creates synthetic getters/ + // setters for it. We need to get the backing field. + if (element?.isSynthetic == true && element is PropertyAccessorElement) { + element = element.variable; + } // element is null if there's nothing really to do for this node. Example: `void` // TODO: One weird issue found: named parameters of external symbols were element.source diff --git a/snapshots/output/basic-project/lib/more.dart b/snapshots/output/basic-project/lib/more.dart index 7d67319..94af943 100755 --- a/snapshots/output/basic-project/lib/more.dart +++ b/snapshots/output/basic-project/lib/more.dart @@ -65,22 +65,26 @@ // ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType# // ^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType#cat. soundMaker = () => print('Meow!'); +// ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#soundMaker. // ^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/print.dart/print(). break; case AnimalType.dog: // ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType# // ^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType#dog. soundMaker = () => print('Woof!'); +// ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#soundMaker. // ^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/print.dart/print(). break; case AnimalType.bird: // ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType# // ^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/AnimalType#bird. soundMaker = () => print('Chirp!'); +// ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#soundMaker. // ^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/print.dart/print(). break; default: soundMaker = () => print('Unknown animal type'); +// ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/more.dart/Animal#soundMaker. // ^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/print.dart/print(). } } From 1eeae5ba313fb2ce1c0cdd41d828f70890761128 Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Thu, 13 Apr 2023 09:51:32 -0600 Subject: [PATCH 2/4] minor null check change --- lib/src/scip_visitor.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index fc870fb..ceb6acf 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -44,8 +44,6 @@ class ScipVisitor extends GeneralizingAstVisitor { @override void visitNode(AstNode node) { - // print('$node :: ${node.runtimeType}'); - // [visitDeclaration] on the [GeneralizingAstVisitor] does not match parameters // even though the parameter node extends [Declaration]. This is a workaround // to correctly parse all [Declaration] ast nodes. @@ -88,10 +86,10 @@ class ScipVisitor extends GeneralizingAstVisitor { if (node.parent is CompoundAssignmentExpression) { final assignmentNode = node.parent as CompoundAssignmentExpression; - element = assignmentNode.readElement ?? assignmentNode.writeElement!; + element = assignmentNode.readElement ?? assignmentNode.writeElement; } else if (node.parent?.parent is AssignmentExpression) { final assignment = node.parent!.parent as AssignmentExpression; - element = assignment.readElement ?? assignment.writeElement!; + element = assignment.readElement ?? assignment.writeElement; } // When the identifier is a field, the analyzer creates synthetic getters/ From 88f559ea13b2858980a3b6a96d5e68414054fdfb Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Thu, 13 Apr 2023 09:54:46 -0600 Subject: [PATCH 3/4] added field accessors --- snapshots/input/basic-project/lib/other.dart | 10 ++++++++ snapshots/output/basic-project/lib/other.dart | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/snapshots/input/basic-project/lib/other.dart b/snapshots/input/basic-project/lib/other.dart index f25236b..d7acee0 100644 --- a/snapshots/input/basic-project/lib/other.dart +++ b/snapshots/input/basic-project/lib/other.dart @@ -2,3 +2,13 @@ class Foo { int _far; Foo(this._far); } + +class Bar { + String _someValue; + Bar(this._someValue); + + void someMethod() { + _someValue = 'asdf'; + print(_someValue); + } +} \ No newline at end of file diff --git a/snapshots/output/basic-project/lib/other.dart b/snapshots/output/basic-project/lib/other.dart index bc000eb..08522d3 100755 --- a/snapshots/output/basic-project/lib/other.dart +++ b/snapshots/output/basic-project/lib/other.dart @@ -15,3 +15,28 @@ // documentation ```dart } + class Bar { +// ^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Bar# +// documentation ```dart + String _someValue; +// ^^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/string.dart/String# +// ^^^^^^^^^^ definition local 2 +// documentation ```dart + Bar(this._someValue); +// ^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Bar#(). +// documentation ```dart +// ^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Bar# +// ^^^^ reference local 2 +// ^^^^^^^^^^ definition local 3 +// documentation ```dart + + void someMethod() { +// ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Bar#someMethod(). +// documentation ```dart + _someValue = 'asdf'; +// ^^^^^^^^^^ reference local 2 + print(_someValue); +// ^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/print.dart/print(). +// ^^^^^^^^^^ reference local 2 + } + } From 55b7bccb49bc259691684dc96fea836c2133e72a Mon Sep 17 00:00:00 2001 From: Matthew Nitschke Date: Thu, 13 Apr 2023 16:31:55 -0600 Subject: [PATCH 4/4] cleaned up ast --- lib/src/scip_visitor.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/scip_visitor.dart b/lib/src/scip_visitor.dart index ceb6acf..97df531 100644 --- a/lib/src/scip_visitor.dart +++ b/lib/src/scip_visitor.dart @@ -84,12 +84,13 @@ class ScipVisitor extends GeneralizingAstVisitor { void _visitSimpleIdentifier(SimpleIdentifier node) { var element = node.staticElement; + // [element] for assignment fields is null. If the parent node + // is a `CompoundAssignmentExpression`, we know this node is referring + // to an assignment line. In that case, use the read/write element attached + // to this node instead of the [node]'s element if (node.parent is CompoundAssignmentExpression) { final assignmentNode = node.parent as CompoundAssignmentExpression; element = assignmentNode.readElement ?? assignmentNode.writeElement; - } else if (node.parent?.parent is AssignmentExpression) { - final assignment = node.parent!.parent as AssignmentExpression; - element = assignment.readElement ?? assignment.writeElement; } // When the identifier is a field, the analyzer creates synthetic getters/