Version 2.10.0-78.0.dev
Merge commit '88b77feb73a8269ab6f6fb2b8ae7102e0292af88' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e6332c..817279d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,12 @@
### Tools
+#### dartfmt
+
+* Don't crash when non-ASCII whitespace is trimmed.
+* Split all conditional expressions (`?:`) when they are nested.
+* Handle `external` and `abstract` fields and variables.
+
#### Linter
Updated the Linter to `0.1.118`, which includes:
diff --git a/DEPS b/DEPS
index 79c9692..94c47ce 100644
--- a/DEPS
+++ b/DEPS
@@ -94,7 +94,7 @@
# and land the review.
#
# For more details, see https://github.com/dart-lang/sdk/issues/30164
- "dart_style_tag": "1.3.6", # Please see the note above before updating.
+ "dart_style_tag": "1.3.7", # Please see the note above before updating.
"chromedriver_tag": "83.0.4103.39",
"dartdoc_rev" : "291ebc50072746bc59ccab59115a298915218428",
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 637b99b1..0ae3509 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -1409,6 +1409,7 @@
var getter = typeReference.getGetter(propertyName.name);
if (getter != null) {
propertyName.staticElement = getter;
+ _resolver.setWriteElement(node, getter);
// The error will be reported in ErrorVerifier.
} else {
_errorReporter.reportErrorForNode(
@@ -1570,6 +1571,7 @@
} else {
var getter = result.getter;
propertyName.staticElement = getter;
+ _resolver.setWriteElement(node, getter);
// A more specific error will be reported in ErrorVerifier.
}
} else if (result.isNone) {
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index 8bd22e9..843a040 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -5,7 +5,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
@@ -22,38 +21,6 @@
with AssignmentDriverResolutionTestCases {}
mixin AssignmentDriverResolutionTestCases on PubPackageResolutionTest {
- test_compound_indexExpression() async {
- await resolveTestCode(r'''
-main() {
- var x = <num>[1, 2, 3];
- x[0] += 4;
-}
-''');
- AssignmentExpression assignment = findNode.assignment('+= 4');
- assertElement(
- assignment,
- elementMatcher(
- numElement.getMethod('+'),
- isLegacy: isNullSafetySdkAndLegacyLibrary,
- ),
- );
- assertType(assignment, 'num'); // num + int = num
-
- IndexExpression indexed = assignment.leftHandSide;
- assertMember(indexed, listElement.getMethod('[]='), {'E': 'num'});
- assertType(indexed, 'num');
-
- SimpleIdentifier xRef = indexed.target;
- assertElement(xRef, findElement.localVar('x'));
- assertType(xRef, 'List<num>');
-
- IntegerLiteral index = indexed.index;
- assertType(index, 'int');
-
- Expression right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
test_compound_plus_int_context_int() async {
await assertNoErrorsInCode('''
T f<T>() => throw Error();
@@ -62,8 +29,10 @@
}
''');
- assertTypeArgumentTypes(findNode.methodInvocation('f()'),
- [typeToStringWithNullability ? 'int' : 'num']);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('f()'),
+ [typeStringByNullability(nullable: 'int', legacy: 'num')],
+ );
}
test_compound_plus_int_context_int_complex() async {
@@ -74,8 +43,10 @@
}
''');
- assertTypeArgumentTypes(findNode.methodInvocation('f()'),
- [typeToStringWithNullability ? 'int' : 'num']);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('f()'),
+ [typeStringByNullability(nullable: 'int', legacy: 'num')],
+ );
}
test_compound_plus_int_context_int_promoted() async {
@@ -88,8 +59,10 @@
}
''');
- assertTypeArgumentTypes(findNode.methodInvocation('f()'),
- [typeToStringWithNullability ? 'int' : 'num']);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('f()'),
+ [typeStringByNullability(nullable: 'int', legacy: 'num')],
+ );
}
test_compound_plus_int_context_int_promoted_with_subsequent_demotion() async {
@@ -103,105 +76,38 @@
}
''');
- assertTypeArgumentTypes(findNode.methodInvocation('f()'),
- [typeToStringWithNullability ? 'int' : 'num']);
+ assertTypeArgumentTypes(
+ findNode.methodInvocation('f()'),
+ [typeStringByNullability(nullable: 'int', legacy: 'num')],
+ );
+
assertType(findNode.simple('a);').staticType, 'num');
}
- test_compound_prefixedIdentifier() async {
- await resolveTestCode(r'''
-main() {
- var c = new C();
- c.f += 2;
+ test_indexExpression_cascade_compound() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int operator[](int index) => 0;
+ operator[]=(int index, num _) {}
}
-class C {
- num f;
+
+void f(A a) {
+ a..[0] += 2;
}
''');
- var assignment = findNode.assignment('c.f += 2');
- assertElement(
- assignment,
- elementMatcher(
+
+ assertAssignment(
+ findNode.assignment('[0] += 2'),
+ readElement: findElement.method('[]'),
+ readType: 'int',
+ writeElement: findElement.method('[]='),
+ writeType: 'num',
+ operatorElement: elementMatcher(
numElement.getMethod('+'),
isLegacy: isNullSafetySdkAndLegacyLibrary,
),
+ type: 'int',
);
- assertType(assignment, 'num'); // num + int = num
-
- PrefixedIdentifier left = assignment.leftHandSide;
- assertType(left, 'num');
-
- var cRef = left.prefix;
- assertElement(cRef, findElement.localVar('c'));
- assertType(cRef, 'C');
-
- var fRef = left.identifier;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_compound_propertyAccess() async {
- await resolveTestCode(r'''
-main() {
- new C().f += 2;
-}
-class C {
- num f;
-}
-''');
- var assignment = findNode.assignment('f += 2');
- assertElement(
- assignment,
- elementMatcher(
- numElement.getMethod('+'),
- isLegacy: isNullSafetySdkAndLegacyLibrary,
- ),
- );
- assertType(assignment, 'num'); // num + int = num
-
- PropertyAccess left = assignment.leftHandSide;
- assertType(left, 'num');
-
- InstanceCreationExpression creation = left.target;
- assertElement(creation, findElement.unnamedConstructor('C'));
- assertType(creation, 'C');
-
- var fRef = left.propertyName;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_indexExpression_cascade() async {
- await resolveTestCode(r'''
-main() {
- <int, double>{}..[1] = 2.0;
-}
-''');
- var cascade = findNode.cascade('<int, double>');
- assertType(cascade, 'Map<int, double>');
-
- SetOrMapLiteral map = cascade.target;
- assertType(map, 'Map<int, double>');
- assertTypeName(map.typeArguments.arguments[0], intElement, 'int');
- assertTypeName(map.typeArguments.arguments[1], doubleElement, 'double');
-
- AssignmentExpression assignment = cascade.cascadeSections[0];
- assertElementNull(assignment);
- assertType(assignment, 'double');
-
- IndexExpression indexed = assignment.leftHandSide;
- assertMember(
- indexed,
- mapElement.getMethod('[]='),
- {'K': 'int', 'V': 'double'},
- );
- assertType(indexed, 'double');
}
test_indexExpression_instance_compound() async {
@@ -230,6 +136,28 @@
);
}
+ test_indexExpression_instance_simple() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ operator[]=(int index, num _) {}
+}
+
+void f(A a) {
+ a[0] = 2;
+}
+''');
+
+ assertAssignment(
+ findNode.assignment('[0] = 2'),
+ readElement: null,
+ readType: null,
+ writeElement: findElement.method('[]='),
+ writeType: 'num',
+ operatorElement: null,
+ type: 'int',
+ );
+ }
+
test_indexExpression_super_compound() async {
await assertNoErrorsInCode(r'''
class A {
@@ -239,7 +167,7 @@
class B extends A {
void f(A a) {
- this[0] += 2;
+ super[0] += 2;
}
}
''');
@@ -264,7 +192,7 @@
int operator[](int index) => 0;
operator[]=(int index, num _) {}
- void f(A a) {
+ void f() {
this[0] += 2;
}
}
@@ -284,6 +212,168 @@
);
}
+ test_indexExpression_unresolved1_simple() async {
+ await assertErrorsInCode(r'''
+void f(int c) {
+ a[b] = c;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 18, 1),
+ error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 20, 1),
+ ]);
+
+ var assignment = findNode.assignment('a[b] = c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('a['),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('b]'),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ assignment.rightHandSide,
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_indexExpression_unresolved2_simple() async {
+ await assertErrorsInCode(r'''
+void f(int a, int c) {
+ a[b] = c;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 26, 3),
+ error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 27, 1),
+ ]);
+
+ var assignment = findNode.assignment('a[b] = c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('a['),
+ readElement: findElement.parameter('a'),
+ writeElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('b]'),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ assignment.rightHandSide,
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_indexExpression_unresolved3_simple() async {
+ await assertErrorsInCode(r'''
+class A {
+ operator[]=(int index, num _) {}
+}
+
+void f(A a, int c) {
+ a[b] = c;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 73, 1),
+ ]);
+
+ var assignment = findNode.assignment('a[b] = c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.method('[]='),
+ writeType: 'num',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('a['),
+ readElement: findElement.parameter('a'),
+ writeElement: null,
+ type: 'A',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('b]'),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ assignment.rightHandSide,
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_binaryExpression_compound() async {
+ await assertErrorsInCode(r'''
+void f(int a, int b, double c) {
+ a + b += c;
+}
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 35, 5),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 35, 5),
+ error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 44, 1),
+ ]);
+
+ var assignment = findNode.assignment('= c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'double',
+ );
+
+ assertElement(findNode.simple('a +'), findElement.parameter('a'));
+ assertElement(findNode.simple('b +'), findElement.parameter('b'));
+ assertElement(findNode.simple('c;'), findElement.parameter('c'));
+ }
+
test_notLValue_parenthesized_compound() async {
await assertErrorsInCode(r'''
void f(int a, int b, double c) {
@@ -355,6 +445,265 @@
);
}
+ test_notLValue_postfixIncrement_compound() async {
+ await assertErrorsInCode('''
+void f(num x, int y) {
+ x++ += y;
+}
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]);
+
+ assertAssignment(
+ findNode.assignment('= y'),
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'num',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('y;'),
+ readElement: findElement.parameter('y'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_postfixIncrement_compound_ifNull() async {
+ await assertErrorsInCode(
+ '''
+void f(num x, int y) {
+ x++ ??= y;
+}
+''',
+ expectedErrorsByNullability(nullable: [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 33, 1),
+ ], legacy: [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]),
+ );
+
+ assertAssignment(
+ findNode.assignment('= y'),
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'num',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('y;'),
+ readElement: findElement.parameter('y'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_postfixIncrement_simple() async {
+ await assertErrorsInCode('''
+void f(num x, int y) {
+ x++ = y;
+}
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]);
+
+ assertAssignment(
+ findNode.assignment('= y'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('y;'),
+ readElement: findElement.parameter('y'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_prefixIncrement_compound() async {
+ await assertErrorsInCode('''
+void f(num x, int y) {
+ ++x += y;
+}
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]);
+
+ assertAssignment(
+ findNode.assignment('= y'),
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'num',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('y;'),
+ readElement: findElement.parameter('y'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_prefixIncrement_compound_ifNull() async {
+ await assertErrorsInCode(
+ '''
+void f(num x, int y) {
+ ++x ??= y;
+}
+''',
+ expectedErrorsByNullability(nullable: [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 33, 1),
+ ], legacy: [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]),
+ );
+
+ assertAssignment(
+ findNode.assignment('= y'),
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'num',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('y;'),
+ readElement: findElement.parameter('y'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_prefixIncrement_simple() async {
+ await assertErrorsInCode('''
+void f(num x, int y) {
+ ++x = y;
+}
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]);
+
+ assertAssignment(
+ findNode.assignment('= y'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('y;'),
+ readElement: findElement.parameter('y'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_notLValue_typeLiteral_class_ambiguous_simple() async {
+ newFile('$testPackageLibPath/a.dart', content: 'class C {}');
+ newFile('$testPackageLibPath/b.dart', content: 'class C {}');
+ await assertErrorsInCode('''
+import 'a.dart';
+import 'b.dart';
+void f() {
+ C = 0;
+}
+''', [
+ error(CompileTimeErrorCode.AMBIGUOUS_IMPORT, 47, 1),
+ ]);
+
+ var matcherC = multiplyDefinedElementMatcher([
+ findElement.importFind('package:test/a.dart').class_('C'),
+ findElement.importFind('package:test/b.dart').class_('C'),
+ ]);
+
+ var assignment = findNode.assignment('C = 0');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: matcherC,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ assignment.leftHandSide,
+ readElement: null,
+ writeElement: matcherC,
+ type: null,
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
+ test_notLValue_typeLiteral_class_simple() async {
+ await assertErrorsInCode('''
+class C {}
+
+void f() {
+ C = 0;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, 25, 1),
+ ]);
+
+ var assignment = findNode.assignment('C = 0');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.class_('C'),
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ assignment.leftHandSide,
+ readElement: null,
+ writeElement: findElement.class_('C'),
+ type: null,
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
test_nullAware_context() async {
var question = typeToStringWithNullability ? '?' : '';
await assertNoErrorsInCode('''
@@ -404,6 +753,142 @@
assertType(assignment.rightHandSide, 'int');
}
+ test_prefixedIdentifier_instance_simple() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ set x(num _) {}
+}
+
+void f(A a) {
+ a.x = 2;
+}
+''');
+
+ var assignment = findNode.assignment('x = 2');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.setter('x'),
+ writeType: 'num',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ var prefixed = assignment.leftHandSide as PrefixedIdentifier;
+ assertSimpleIdentifier(
+ prefixed.identifier,
+ readElement: null,
+ writeElement: findElement.setter('x'),
+ type: 'num',
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
+ test_prefixedIdentifier_instanceGetter_simple() async {
+ await assertErrorsInCode(r'''
+class A {
+ int get x => 0;
+}
+
+void f(A a) {
+ a.x = 2;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 49, 1),
+ ]);
+
+ var assignment = findNode.assignment('x = 2');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.getter('x'),
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ var prefixed = assignment.leftHandSide as PrefixedIdentifier;
+ assertSimpleIdentifier(
+ prefixed.identifier,
+ readElement: null,
+ writeElement: findElement.getter('x'),
+ type: 'dynamic',
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
+ test_prefixedIdentifier_static_simple() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ static set x(num _) {}
+}
+
+void f() {
+ A.x = 2;
+}
+''');
+
+ var assignment = findNode.assignment('x = 2');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.setter('x'),
+ writeType: 'num',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ var prefixed = assignment.leftHandSide as PrefixedIdentifier;
+ assertSimpleIdentifier(
+ prefixed.identifier,
+ readElement: null,
+ writeElement: findElement.setter('x'),
+ type: 'num',
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
+ test_prefixedIdentifier_staticGetter_simple() async {
+ await assertErrorsInCode(r'''
+class A {
+ static int get x => 0;
+}
+
+void f() {
+ A.x = 2;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 53, 1),
+ ]);
+
+ var assignment = findNode.assignment('x = 2');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.getter('x'),
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ var prefixed = assignment.leftHandSide as PrefixedIdentifier;
+ assertSimpleIdentifier(
+ prefixed.identifier,
+ readElement: null,
+ writeElement: findElement.getter('x'),
+ type: 'dynamic',
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
test_prefixedIdentifier_topLevel_compound() async {
newFile('$testPackageLibPath/a.dart', content: r'''
int get x => 0;
@@ -446,6 +931,91 @@
assertType(assignment.rightHandSide, 'int');
}
+ test_prefixedIdentifier_unresolved1_simple() async {
+ await assertErrorsInCode(r'''
+void f(int c) {
+ a.b = c;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 18, 1),
+ ]);
+
+ var assignment = findNode.assignment('a.b = c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('a.'),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('b ='),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ assignment.rightHandSide,
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_prefixedIdentifier_unresolved2_compound() async {
+ await assertErrorsInCode(r'''
+void f(int a, int c) {
+ a.b += c;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_GETTER, 27, 1),
+ error(CompileTimeErrorCode.UNDEFINED_SETTER, 27, 1),
+ ]);
+
+ var assignment = findNode.assignment('a.b += c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('a.'),
+ readElement: findElement.parameter('a'),
+ writeElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('b +='),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ assignment.rightHandSide,
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
test_propertyAccess_cascade_compound() async {
await assertNoErrorsInCode(r'''
class A {
@@ -522,8 +1092,8 @@
set x(num _) {}
}
-void f() {
- A().x += 2;
+void f(A a) {
+ (a).x += 2;
}
''');
@@ -552,6 +1122,39 @@
assertType(assignment.rightHandSide, 'int');
}
+ test_propertyAccess_instance_simple() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ set x(num _) {}
+}
+
+void f(A a) {
+ (a).x = 2;
+}
+''');
+
+ var assignment = findNode.assignment('x = 2');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: findElement.setter('x'),
+ writeType: 'num',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ var propertyAccess = assignment.leftHandSide as PropertyAccess;
+ assertSimpleIdentifier(
+ propertyAccess.propertyName,
+ readElement: null,
+ writeElement: findElement.setter('x'),
+ type: 'num',
+ );
+
+ assertType(assignment.rightHandSide, 'int');
+ }
+
test_propertyAccess_super_compound() async {
await assertNoErrorsInCode(r'''
class A {
@@ -632,215 +1235,88 @@
assertType(assignment.rightHandSide, 'int');
}
- test_simple_indexExpression() async {
- await resolveTestCode(r'''
-main() {
- var x = <int>[1, 2, 3];
- x[0] = 4;
-}
-''');
- AssignmentExpression assignment = findNode.assignment('= 4');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- IndexExpression indexed = assignment.leftHandSide;
- assertMember(indexed, listElement.getMethod('[]='), {'E': 'int'});
- assertType(indexed, 'int');
-
- var xRef = indexed.target;
- assertElement(xRef, findElement.localVar('x'));
- assertType(xRef, 'List<int>');
-
- IntegerLiteral index = indexed.index;
- assertType(index, 'int');
-
- Expression right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_simple_prefixedIdentifier() async {
- await resolveTestCode(r'''
-main() {
- var c = new C();
- c.f = 2;
-}
-class C {
- num f;
-}
-''');
- var assignment = findNode.assignment('c.f = 2');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PrefixedIdentifier left = assignment.leftHandSide;
- assertType(left, 'num');
-
- var cRef = left.prefix;
- assertElement(cRef, findElement.localVar('c'));
- assertType(cRef, 'C');
-
- var fRef = left.identifier;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_simple_prefixedIdentifier_staticField() async {
- await resolveTestCode(r'''
-main() {
- C.f = 2;
-}
-class C {
- static num f;
-}
-''');
-
- var assignment = findNode.assignment('C.f = 2');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PrefixedIdentifier left = assignment.leftHandSide;
- assertType(left, 'num');
-
- var cRef = left.prefix;
- assertElement(cRef, findElement.class_('C'));
- assertTypeNull(cRef);
-
- var fRef = left.identifier;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_simple_propertyAccess() async {
- await resolveTestCode(r'''
-main() {
- new C().f = 2;
-}
-class C {
- num f;
-}
-''');
- var assignment = findNode.assignment('f = 2');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PropertyAccess left = assignment.leftHandSide;
- assertType(left, 'num');
-
- InstanceCreationExpression creation = left.target;
- assertElement(creation, findElement.unnamedConstructor('C'));
- assertType(creation, 'C');
-
- var fRef = left.propertyName;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_simple_propertyAccess_chained() async {
- await resolveTestCode(r'''
-main() {
- var a = new A();
- a.b.f = 2;
-}
-class A {
- B b;
-}
-class B {
- num f;
-}
-''');
- var assignment = findNode.assignment('a.b.f = 2');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PropertyAccess left = assignment.leftHandSide;
- assertType(left, 'num');
-
- PrefixedIdentifier ab = left.target;
- assertType(ab, 'B');
-
- var aRef = ab.prefix;
- assertElement(aRef, findElement.localVar('a'));
- assertType(aRef, 'A');
-
- var bRef = ab.identifier;
- assertElement(bRef, findElement.getter('b'));
- assertType(bRef, 'B');
-
- var fRef = left.propertyName;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_simple_propertyAccess_setter() async {
- await resolveTestCode(r'''
-main() {
- new C().f = 2;
-}
-class C {
- void set f(num _) {}
-}
-''');
- var assignment = findNode.assignment('f = 2');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PropertyAccess left = assignment.leftHandSide;
- assertType(left, 'num');
-
- InstanceCreationExpression creation = left.target;
- assertElement(creation, findElement.unnamedConstructor('C'));
- assertType(creation, 'C');
-
- var fRef = left.propertyName;
- assertElement(fRef, findElement.setter('f'));
- assertType(fRef, 'num');
-
- var right = assignment.rightHandSide;
- assertType(right, 'int');
- }
-
- test_simpleIdentifier_class_simple() async {
- await assertErrorsInCode('''
-class C {}
-
-void f() {
- C = 0;
+ test_propertyAccess_unresolved1_simple() async {
+ await assertErrorsInCode(r'''
+void f(int c) {
+ (a).b = c;
}
''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, 25, 1),
+ error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 19, 1),
]);
- var assignment = findNode.assignment('C = 0');
+ var assignment = findNode.assignment('(a).b = c');
assertAssignment(
assignment,
readElement: null,
readType: null,
- writeElement: findElement.class_('C'),
+ writeElement: null,
writeType: 'dynamic',
operatorElement: null,
type: 'int',
);
assertSimpleIdentifier(
- assignment.leftHandSide,
+ findNode.simple('a)'),
readElement: null,
- writeElement: findElement.class_('C'),
- type: null,
+ writeElement: null,
+ type: 'dynamic',
);
- assertType(assignment.rightHandSide, 'int');
+ assertSimpleIdentifier(
+ findNode.simple('b ='),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('c;'),
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
+ }
+
+ test_propertyAccess_unresolved2_simple() async {
+ await assertErrorsInCode(r'''
+void f(int a, int c) {
+ (a).b = c;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_SETTER, 29, 1),
+ ]);
+
+ var assignment = findNode.assignment('(a).b = c');
+ assertAssignment(
+ assignment,
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: 'dynamic',
+ operatorElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('a)'),
+ readElement: findElement.parameter('a'),
+ writeElement: null,
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('b ='),
+ readElement: null,
+ writeElement: null,
+ type: 'dynamic',
+ );
+
+ assertSimpleIdentifier(
+ findNode.simple('c;'),
+ readElement: findElement.parameter('c'),
+ writeElement: null,
+ type: 'int',
+ );
}
test_simpleIdentifier_fieldInstance_simple() async {
@@ -1717,474 +2193,6 @@
type: 'int',
);
}
-
- test_to_class_ambiguous() async {
- newFile('/test/lib/a.dart', content: 'class C {}');
- newFile('/test/lib/b.dart', content: 'class C {}');
- await resolveTestCode('''
-import 'a.dart';
-import 'b.dart';
-void f(int x) {
- C = x;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x;');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'int');
- }
-
- test_to_getter_instance_direct() async {
- await resolveTestCode('''
-class C {
- int get x => 0;
-}
-f(C c) {
- c.x += 2;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x +=');
- assertElement(xRef, findElement.getter('x'));
- assertType(xRef, 'int');
- }
-
- test_to_getter_static_direct() async {
- await resolveTestCode('''
-class C {
- static int get x => 0;
-}
-main() {
- C.x += 2;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x +=');
- assertElement(xRef, findElement.getter('x'));
- assertType(xRef, 'int');
- }
-
- test_to_non_lvalue() async {
- await resolveTestCode('''
-void f(int x, double y, String z) {
- x + y = z;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x +');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'int');
-
- var yRef = findNode.simple('y =');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'double');
-
- var zRef = findNode.simple('z;');
- assertElement(zRef, findElement.parameter('z'));
- assertType(zRef, 'String');
- }
-
- test_to_postfix_increment() async {
- await resolveTestCode('''
-void f(num x, int y) {
- x++ = y;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x++');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'num');
-
- var yRef = findNode.simple('y;');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'int');
- }
-
- test_to_postfix_increment_compound() async {
- await resolveTestCode('''
-void f(num x, int y) {
- x++ += y;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x++');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'num');
-
- var yRef = findNode.simple('y;');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'int');
- }
-
- test_to_postfix_increment_null_aware() async {
- await resolveTestCode('''
-void f(num x, int y) {
- x++ ??= y;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x++');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'num');
-
- var yRef = findNode.simple('y;');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'int');
- }
-
- test_to_prefix_increment() async {
- await resolveTestCode('''
-void f(num x, int y) {
- ++x = y;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x =');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'num');
-
- var yRef = findNode.simple('y;');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'int');
- }
-
- test_to_prefix_increment_compound() async {
- await resolveTestCode('''
-void f(num x, int y) {
- ++x += y;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x +=');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'num');
-
- var yRef = findNode.simple('y;');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'int');
- }
-
- test_to_prefix_increment_null_aware() async {
- await resolveTestCode('''
-void f(num x, int y) {
- ++x ??= y;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var xRef = findNode.simple('x ??=');
- assertElement(xRef, findElement.parameter('x'));
- assertType(xRef, 'num');
-
- var yRef = findNode.simple('y;');
- assertElement(yRef, findElement.parameter('y'));
- assertType(yRef, 'int');
- }
-
- test_unresolved_left_identifier_compound() async {
- await resolveTestCode(r'''
-int b;
-main() {
- a += b;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a += b');
- assertElementNull(assignment);
- assertTypeDynamic(assignment);
-
- assertElementNull(assignment.leftHandSide);
- assertTypeDynamic(assignment.leftHandSide);
-
- assertElement(assignment.rightHandSide, findElement.topGet('b'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_indexed1_simple() async {
- await resolveTestCode(r'''
-int c;
-main() {
- a[b] = c;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a[b] = c');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- IndexExpression indexed = assignment.leftHandSide;
- assertElementNull(indexed);
- assertTypeDynamic(indexed);
-
- assertElementNull(indexed.target);
- assertTypeDynamic(indexed.target);
-
- assertElementNull(indexed.index);
- assertTypeDynamic(indexed.index);
-
- assertElement(assignment.rightHandSide, findElement.topGet('c'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_indexed2_simple() async {
- await resolveTestCode(r'''
-A a;
-int c;
-main() {
- a[b] = c;
-}
-class A {}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a[b] = c');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- IndexExpression indexed = assignment.leftHandSide;
- assertElementNull(indexed);
- assertTypeDynamic(indexed);
-
- assertElement(indexed.target, findElement.topGet('a'));
- assertType(indexed.target, 'A');
-
- assertElementNull(indexed.index);
- assertTypeDynamic(indexed.index);
-
- assertElement(assignment.rightHandSide, findElement.topGet('c'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_indexed3_simple() async {
- await resolveTestCode(r'''
-A a;
-int c;
-main() {
- a[b] = c;
-}
-class A {
- operator[]=(double b) {}
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a[b] = c');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- IndexExpression indexed = assignment.leftHandSide;
- assertElement(indexed, findElement.method('[]='));
- assertTypeDynamic(indexed);
-
- assertElement(indexed.target, findElement.topGet('a'));
- assertType(indexed.target, 'A');
-
- assertElementNull(indexed.index);
- assertTypeDynamic(indexed.index);
-
- assertElement(assignment.rightHandSide, findElement.topGet('c'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_indexed4_simple() async {
- await resolveTestCode(r'''
-double b;
-int c;
-main() {
- a[b] = c;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a[b] = c');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- IndexExpression indexed = assignment.leftHandSide;
- assertElementNull(indexed);
- assertTypeDynamic(indexed);
-
- assertElementNull(indexed.target);
- assertTypeDynamic(indexed.target);
-
- assertElement(indexed.index, findElement.topGet('b'));
- assertType(indexed.index, 'double');
-
- assertElement(assignment.rightHandSide, findElement.topGet('c'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_prefixed1_simple() async {
- await resolveTestCode(r'''
-int c;
-main() {
- a.b = c;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a.b = c');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PrefixedIdentifier prefixed = assignment.leftHandSide;
- assertElementNull(prefixed);
- assertTypeDynamic(prefixed);
-
- assertElementNull(prefixed.prefix);
- assertTypeDynamic(prefixed.prefix);
-
- assertElementNull(prefixed.identifier);
- assertTypeDynamic(prefixed.identifier);
-
- assertElement(assignment.rightHandSide, findElement.topGet('c'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_prefixed2_simple() async {
- await resolveTestCode(r'''
-class A {}
-A a;
-int c;
-main() {
- a.b = c;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a.b = c');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PrefixedIdentifier prefixed = assignment.leftHandSide;
- assertElementNull(prefixed);
- assertTypeDynamic(prefixed);
-
- assertElement(prefixed.prefix, findElement.topGet('a'));
- assertType(prefixed.prefix, 'A');
-
- assertElementNull(prefixed.identifier);
- assertTypeDynamic(prefixed.identifier);
-
- assertElement(assignment.rightHandSide, findElement.topGet('c'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_property1_simple() async {
- await resolveTestCode(r'''
-int d;
-main() {
- a.b.c = d;
-}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a.b.c = d');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PropertyAccess access = assignment.leftHandSide;
- assertTypeDynamic(access);
-
- PrefixedIdentifier prefixed = access.target;
- assertElementNull(prefixed);
- assertTypeDynamic(prefixed);
-
- assertElementNull(prefixed.prefix);
- assertTypeDynamic(prefixed.prefix);
-
- assertElementNull(prefixed.identifier);
- assertTypeDynamic(prefixed.identifier);
-
- assertElementNull(access.propertyName);
- assertTypeDynamic(access.propertyName);
-
- assertElement(assignment.rightHandSide, findElement.topGet('d'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_property2_simple() async {
- await resolveTestCode(r'''
-A a;
-int d;
-main() {
- a.b.c = d;
-}
-class A {}
-''');
- expect(result.errors, isNotEmpty);
-
- var assignment = findNode.assignment('a.b.c = d');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PropertyAccess access = assignment.leftHandSide;
- assertTypeDynamic(access);
-
- PrefixedIdentifier prefixed = access.target;
- assertElementNull(prefixed);
- assertTypeDynamic(prefixed);
-
- assertElement(prefixed.prefix, findElement.topGet('a'));
- assertType(prefixed.prefix, 'A');
-
- assertElementNull(prefixed.identifier);
- assertTypeDynamic(prefixed.identifier);
-
- assertElementNull(access.propertyName);
- assertTypeDynamic(access.propertyName);
-
- assertElement(assignment.rightHandSide, findElement.topGet('d'));
- assertType(assignment.rightHandSide, 'int');
- }
-
- test_unresolved_left_property3_simple() async {
- await resolveTestCode(r'''
-A a;
-int d;
-main() {
- a.b.c = d;
-}
-class A { B b; }
-class B {}
-''');
- expect(result.errors, isNotEmpty);
- var bElement = findElement.field('b');
-
- var assignment = findNode.assignment('a.b.c = d');
- assertElementNull(assignment);
- assertType(assignment, 'int');
-
- PropertyAccess access = assignment.leftHandSide;
- assertTypeDynamic(access);
-
- PrefixedIdentifier prefixed = access.target;
- assertElement(prefixed, bElement.getter);
- assertType(prefixed, 'B');
-
- assertElement(prefixed.prefix, findElement.topGet('a'));
- assertType(prefixed.prefix, 'A');
-
- assertElement(prefixed.identifier, bElement.getter);
- assertType(prefixed.identifier, 'B');
-
- assertElementNull(access.propertyName);
- assertTypeDynamic(access.propertyName);
-
- assertElement(assignment.rightHandSide, findElement.topGet('d'));
- assertType(assignment.rightHandSide, 'int');
- }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index be1327b..1368e36 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -862,6 +862,10 @@
ExpectedContextMessage message(String filePath, int offset, int length) =>
ExpectedContextMessage(convertPath(filePath), offset, length);
+ Matcher multiplyDefinedElementMatcher(List<Element> elements) {
+ return _MultiplyDefinedElementMatcher(elements);
+ }
+
Future<ResolvedUnitResult> resolveFile(String path);
/// Resolve the file with the [path] into [result].
@@ -974,3 +978,24 @@
return false;
}
}
+
+class _MultiplyDefinedElementMatcher extends Matcher {
+ final Iterable<Element> elements;
+
+ _MultiplyDefinedElementMatcher(this.elements);
+
+ @override
+ Description describe(Description description) {
+ return description.add('elements: $elements\n');
+ }
+
+ @override
+ bool matches(element, Map matchState) {
+ if (element is MultiplyDefinedElementImpl) {
+ var actualSet = element.conflictingElements.toSet();
+ actualSet.removeAll(elements);
+ return actualSet.isEmpty;
+ }
+ return false;
+ }
+}
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
index 1045907..93d417d 100644
--- a/pkg/dartdev/test/commands/format_test.dart
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -22,7 +22,7 @@
var result = p.runSync('format', ['--help']);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
- expect(result.stdout, contains('Idiomatically formats Dart source code.'));
+ expect(result.stdout, contains('Idiomatically format Dart source code.'));
expect(result.stdout,
contains('Usage: dart format [options...] <files or directories...>'));
});
diff --git a/pkg/front_end/testcases/nnbd/abstract_fields.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/abstract_fields.dart.textual_outline.expect
index 77a9bf9..9d9f076 100644
--- a/pkg/front_end/testcases/nnbd/abstract_fields.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/abstract_fields.dart.textual_outline.expect
@@ -3,6 +3,7 @@
abstract final int finalInstanceField;
abstract covariant num covariantInstanceField;
}
+
mixin B {
abstract int instanceField;
abstract final int finalInstanceField;
diff --git a/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline.expect
index 88348e2..21d3bce 100644
--- a/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline.expect
@@ -6,4 +6,5 @@
abstract covariant num cn;
abstract covariant var cx;
}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed54c1d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/abstract_fields_spec.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+abstract class A {
+ abstract covariant num cn;
+ abstract covariant var cx;
+ abstract final fx;
+ abstract final int fi;
+ abstract int i1, i2;
+ abstract var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline.expect
index 90d1b87..7b56a7c 100644
--- a/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline.expect
@@ -1,9 +1,11 @@
external int s1;
external final fx;
+
class A {
external int i1;
external covariant var cx;
external static int s1;
external static final fx;
}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..12143c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/external_fields_spec.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A {
+ external covariant var cx;
+ external int i1;
+ external static final fx;
+ external static int s1;
+}
+
+external final fx;
+external int s1;
+main() {}
diff --git a/tools/VERSION b/tools/VERSION
index 0adee07..8359e44 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 77
+PRERELEASE 78
PRERELEASE_PATCH 0
\ No newline at end of file