Fix resolution for IndexExpression in cascade.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: I3f5f8dba51bfcda440c37438a0d2463b9829da43
Reviewed-on: https://dart-review.googlesource.com/63302
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index 3a33ceb3..39bf30a 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -350,9 +350,9 @@
@override
void visitIndexExpression(IndexExpression node) {
- node.target.accept(this);
+ node.target?.accept(this);
- DartType targetType = node.target.staticType;
+ DartType targetType = node.realTarget.staticType;
var data = _get(node.leftBracket);
MethodElement element = data.reference;
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 883c655..cc12389 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -40,9 +40,13 @@
FindNode findNode;
FindElement findElement;
- DartType get doubleType => typeProvider.doubleType;
+ InterfaceType get doubleType => typeProvider.doubleType;
- DartType get intType => typeProvider.intType;
+ InterfaceType get intType => typeProvider.intType;
+
+ ClassElement get mapElement => typeProvider.mapType.element;
+
+ InterfaceType get mapType => typeProvider.mapType;
TypeProvider get typeProvider => result.unit.element.context.typeProvider;
@@ -56,11 +60,27 @@
expect(actual, isNull);
}
+ void assertMember(
+ Expression node, String expectedDefiningType, Element expectedBase) {
+ Member actual = getNodeElement(node);
+ expect(actual.definingType.toString(), expectedDefiningType);
+ expect(actual.baseElement, same(expectedBase));
+ }
+
void assertType(Expression expression, String expected) {
DartType actual = expression.staticType;
expect(actual?.toString(), expected);
}
+ /// Test that [argumentList] has exactly two type items `int` and `double`.
+ void assertTypeArguments(
+ TypeArgumentList argumentList, List<DartType> expectedTypes) {
+ expect(argumentList.arguments, hasLength(expectedTypes.length));
+ for (int i = 0; i < expectedTypes.length; i++) {
+ _assertTypeNameSimple(argumentList.arguments[i], expectedTypes[i]);
+ }
+ }
+
void assertTypeDynamic(Expression expression) {
DartType actual = expression.staticType;
expect(actual, isDynamicType);
@@ -2222,6 +2242,30 @@
expect(actualElement.parameters[0].type, intType);
}
+ test_indexExpression_cascade_assign() async {
+ addTestFile(r'''
+main() {
+ <int, int>{}..[1] = 10;
+}
+''');
+ await resolveTestFile();
+
+ var cascade = findNode.cascade('<int, int>');
+ assertType(cascade, 'Map<int, int>');
+
+ MapLiteral map = cascade.target;
+ assertType(map, 'Map<int, int>');
+ assertTypeArguments(map.typeArguments, [intType, intType]);
+
+ AssignmentExpression assignment = cascade.cascadeSections[0];
+ assertElementNull(assignment);
+ assertType(assignment, 'int');
+
+ IndexExpression indexed = assignment.leftHandSide;
+ assertMember(indexed, 'Map<int, int>', mapElement.getMethod('[]='));
+ assertType(indexed, 'int');
+ }
+
test_instanceCreation_factory() async {
String content = r'''
class C {
@@ -6454,8 +6498,7 @@
expect(typeIdentifier.staticType, isDynamicType);
}
- _assertInvocationTypeArguments(
- typeName.typeArguments, [intType, doubleType]);
+ assertTypeArguments(typeName.typeArguments, [intType, doubleType]);
_assertInvocationArguments(creation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6504,8 +6547,7 @@
expect(typePrefix.staticType, isDynamicType);
}
- _assertInvocationTypeArguments(
- typeName.typeArguments, [intType, doubleType]);
+ assertTypeArguments(typeName.typeArguments, [intType, doubleType]);
_assertInvocationArguments(creation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6556,8 +6598,7 @@
expect(typePrefix.staticType, isDynamicType);
}
- _assertInvocationTypeArguments(
- typeName.typeArguments, [intType, doubleType]);
+ assertTypeArguments(typeName.typeArguments, [intType, doubleType]);
_assertInvocationArguments(creation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6610,8 +6651,7 @@
expect(constructorName.name.staticType, isDynamicType);
}
- _assertInvocationTypeArguments(
- typeName.typeArguments, [intType, doubleType]);
+ assertTypeArguments(typeName.typeArguments, [intType, doubleType]);
_assertInvocationArguments(creation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6665,8 +6705,7 @@
expect(constructorName.name.staticElement, isNull);
expect(constructorName.name.staticType, isNull);
- _assertInvocationTypeArguments(
- typeName.typeArguments, [intType, doubleType]);
+ assertTypeArguments(typeName.typeArguments, [intType, doubleType]);
_assertInvocationArguments(creation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6717,8 +6756,7 @@
expect(constructorName.name.staticElement, isNull);
expect(constructorName.name.staticType, isNull);
- _assertInvocationTypeArguments(
- typeName.typeArguments, [intType, doubleType]);
+ assertTypeArguments(typeName.typeArguments, [intType, doubleType]);
_assertInvocationArguments(creation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6745,8 +6783,7 @@
expect(name.staticElement, isNull);
expect(name.staticType, isDynamicType);
- _assertInvocationTypeArguments(
- invocation.typeArguments, [intType, doubleType]);
+ assertTypeArguments(invocation.typeArguments, [intType, doubleType]);
_assertInvocationArguments(invocation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6789,8 +6826,7 @@
expect(name.staticType, isDynamicType);
}
- _assertInvocationTypeArguments(
- invocation.typeArguments, [intType, doubleType]);
+ assertTypeArguments(invocation.typeArguments, [intType, doubleType]);
_assertInvocationArguments(invocation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -6820,8 +6856,7 @@
expect(name.staticElement, isNull);
expect(name.staticType, isDynamicType);
- _assertInvocationTypeArguments(
- invocation.typeArguments, [intType, doubleType]);
+ assertTypeArguments(invocation.typeArguments, [intType, doubleType]);
_assertInvocationArguments(invocation.argumentList,
[checkTopVarRef('arg1'), checkTopVarUndefinedNamedRef('arg2')]);
}
@@ -7070,15 +7105,6 @@
}
}
- /// Test that [argumentList] has exactly two type items `int` and `double`.
- void _assertInvocationTypeArguments(
- TypeArgumentList argumentList, List<DartType> expectedTypes) {
- expect(argumentList.arguments, hasLength(expectedTypes.length));
- for (int i = 0; i < expectedTypes.length; i++) {
- _assertTypeNameSimple(argumentList.arguments[i], expectedTypes[i]);
- }
- }
-
void _assertParameterElement(ParameterElement element,
{String name, int offset, ParameterKind kind, DartType type}) {
expect(element, isNotNull);
@@ -7208,6 +7234,10 @@
return _node(search).getAncestor((n) => n is AssignmentExpression);
}
+ CascadeExpression cascade(String search) {
+ return _node(search).getAncestor((n) => n is CascadeExpression);
+ }
+
SimpleIdentifier simple(String search) {
return _node(search);
}