Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEA-2496: Fixed Cascade Indexing #84

Merged
merged 9 commits into from
Sep 12, 2023
Merged
9 changes: 6 additions & 3 deletions lib/src/scip_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,12 @@ class ScipVisitor extends GeneralizingAstVisitor {
// 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;
if (element == null) {
final assignmentExpr =
node.thisOrAncestorOfType<CompoundAssignmentExpression>();
if (assignmentExpr == null) return;

element = assignmentExpr.readElement ?? assignmentExpr.writeElement;
}
Comment on lines -118 to 124
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the following dart code:

Foo()..value = 1;

This is what the generated ast results in

Foo()..value = 1; (ExpressionStatement)
        Foo()..value = 1 (CascadeExpression)
                Foo() (MethodInvocation)
                        Foo (SimpleIdentifier)
                        () (ArgumentList)
                ..value = 1 (AssignmentExpression) <----- (extends from CompoundAssignmentExpression)
                        ..value (PropertyAccess)
                                value (SimpleIdentifier)
                        1 (IntegerLiteral)

Given the above code, value (SimpleIdentifier) is the case that makes it to this conditional. If we refer to the ast, the parent of this element is PropertyAccess, not CompoundAssignmentExpression, which tells us this expression can occur at multiple depths, not just the parent

We can solve this by just searching for the closest node of the specific type, and treat that as the assignment expression we care about


// When the identifier is a field, the analyzer creates synthetic getters/
Expand Down
11 changes: 11 additions & 0 deletions snapshots/input/basic-project/lib/other.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import 'more.dart' deferred as more;

class Foo {
int _far;
bool value;
String value2;
double value3;
Foo(this._far);
}

Expand All @@ -19,4 +22,12 @@ void main() {
more.loadLibrary().then((_) => {
Bar('a').someMethod.call()
});

Foo()..value = false;

final someStr = 'someStr';
Foo()
..value = true
..value2 = someStr
..value3 = 2.15
}
29 changes: 29 additions & 0 deletions snapshots/output/basic-project/lib/other.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@
// ^^^ reference scip-dart pub dart:core 2.18.0 dart:core/int.dart/int#
// ^^^^ definition local 0
// documentation ```dart
bool value;
// ^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/bool.dart/bool#
// ^^^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value.
// documentation ```dart
String value2;
// ^^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/string.dart/String#
// ^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value2.
// documentation ```dart
double value3;
// ^^^^^^ reference scip-dart pub dart:core 2.18.0 dart:core/double.dart/double#
// ^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value3.
// documentation ```dart
Foo(this._far);
// ^^^ definition scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#<constructor>().
// documentation ```dart
Expand Down Expand Up @@ -57,4 +69,21 @@
// ^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Bar#
// ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Bar#someMethod().
});

Foo()..value = false;
// ^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#
// ^^^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value.

final someStr = 'someStr';
// ^^^^^^^ definition local 5
// documentation ```dart
Foo()
// ^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#
..value = true
// ^^^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value.
..value2 = someStr
// ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value2.
// ^^^^^^^ reference local 5
..value3 = 2.15
// ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/other.dart/Foo#value3.
}
Loading