Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: pkg/analyzer/test/generated/resolver_test.dart

Issue 725473005: During resolution, record the target of break/continue statements. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/test/generated/resolver_test.dart
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 5096323b8a196b1bd9ffd29e381242549810e5cd..6827d805df87b7c3bce9e1799ffd60300c393ead 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -697,31 +697,31 @@ var v = const A(null);''');
verify([source]);
}
- void test_fieldFormalParameterAssignableToField_typeSubstitution() {
+ void test_fieldFormalParameterAssignableToField_typedef() {
// foo has the runtime type dynamic -> dynamic, so it should be assignable
// to A.f.
Source source = addSource(r'''
-class A<T> {
- final T x;
- const A(this.x);
+typedef String Int2String(int x);
+class A {
+ final Int2String f;
+ const A(this.f);
}
-var v = const A<int>(3);''');
+foo(x) => 1;
+var v = const A(foo);''');
resolve(source);
assertNoErrors(source);
verify([source]);
}
- void test_fieldFormalParameterAssignableToField_typedef() {
+ void test_fieldFormalParameterAssignableToField_typeSubstitution() {
// foo has the runtime type dynamic -> dynamic, so it should be assignable
// to A.f.
Source source = addSource(r'''
-typedef String Int2String(int x);
-class A {
- final Int2String f;
- const A(this.f);
+class A<T> {
+ final T x;
+ const A(this.x);
}
-foo(x) => 1;
-var v = const A(foo);''');
+var v = const A<int>(3);''');
resolve(source);
assertNoErrors(source);
verify([source]);
@@ -1347,17 +1347,26 @@ class ElementResolverTest extends EngineTestCase {
}
void test_visitBreakStatement_withLabel() {
+ // loop: while (true) {
+ // break loop;
+ // }
String label = "loop";
LabelElementImpl labelElement =
new LabelElementImpl(AstFactory.identifier3(label), false, false);
- BreakStatement statement = AstFactory.breakStatement2(label);
- expect(_resolveBreak(statement, labelElement), same(labelElement));
+ BreakStatement breakStatement = AstFactory.breakStatement2(label);
+ Expression condition = AstFactory.booleanLiteral(true);
+ WhileStatement whileStatement =
+ AstFactory.whileStatement(condition, breakStatement);
+ expect(
+ _resolveBreak(breakStatement, labelElement, whileStatement),
+ same(labelElement));
+ expect(breakStatement.target, same(whileStatement));
_listener.assertNoErrors();
}
void test_visitBreakStatement_withoutLabel() {
BreakStatement statement = AstFactory.breakStatement();
- _resolveStatement(statement, null);
+ _resolveStatement(statement, null, null);
_listener.assertNoErrors();
}
@@ -1388,17 +1397,26 @@ class ElementResolverTest extends EngineTestCase {
}
void test_visitContinueStatement_withLabel() {
+ // loop: while (true) {
+ // continue loop;
+ // }
String label = "loop";
LabelElementImpl labelElement =
new LabelElementImpl(AstFactory.identifier3(label), false, false);
- ContinueStatement statement = AstFactory.continueStatement(label);
- expect(_resolveContinue(statement, labelElement), same(labelElement));
+ ContinueStatement continueStatement = AstFactory.continueStatement(label);
+ Expression condition = AstFactory.booleanLiteral(true);
+ WhileStatement whileStatement =
+ AstFactory.whileStatement(condition, continueStatement);
+ expect(
+ _resolveContinue(continueStatement, labelElement, whileStatement),
+ same(labelElement));
+ expect(continueStatement.target, same(whileStatement));
_listener.assertNoErrors();
}
void test_visitContinueStatement_withoutLabel() {
ContinueStatement statement = AstFactory.continueStatement();
- _resolveStatement(statement, null);
+ _resolveStatement(statement, null, null);
_listener.assertNoErrors();
}
@@ -1610,17 +1628,6 @@ class ElementResolverTest extends EngineTestCase {
_listener.assertNoErrors();
}
- void test_visitPrefixExpression() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier operand = AstFactory.identifier3("i");
- operand.staticType = numType;
- PrefixExpression expression =
- AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
void test_visitPrefixedIdentifier_dynamic() {
DartType dynamicType = _typeProvider.dynamicType;
SimpleIdentifier target = AstFactory.identifier3("a");
@@ -1731,6 +1738,17 @@ class ElementResolverTest extends EngineTestCase {
_listener.assertNoErrors();
}
+ void test_visitPrefixExpression() {
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier operand = AstFactory.identifier3("i");
+ operand.staticType = numType;
+ PrefixExpression expression =
+ AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
+ _resolveNode(expression);
+ expect(expression.staticElement, getMethod(numType, "+"));
+ _listener.assertNoErrors();
+ }
+
void test_visitPropertyAccess_getter_identifier() {
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "b";
@@ -1909,30 +1927,30 @@ class ElementResolverTest extends EngineTestCase {
}
/**
- * Return the element associated with the label of the given statement after the resolver has
- * resolved the statement.
- *
- * @param statement the statement to be resolved
- * @param labelElement the label element to be defined in the statement's label scope
- * @return the element to which the statement's label was resolved
+ * Return the element associated with the label of [statement] after the
+ * resolver has resolved it. [labelElement] is the label element to be
+ * defined in the statement's label scope, and [labelTarget] is the statement
+ * the label resolves to.
*/
- Element _resolveBreak(BreakStatement statement,
- LabelElementImpl labelElement) {
- _resolveStatement(statement, labelElement);
+ Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
+ Statement labelTarget) {
+ _resolveStatement(statement, labelElement, labelTarget);
return statement.label.staticElement;
}
/**
- * Return the element associated with the label of the given statement after the resolver has
- * resolved the statement.
+ * Return the element associated with the label [statement] after the
+ * resolver has resolved it. [labelElement] is the label element to be
+ * defined in the statement's label scope, and [labelTarget] is the AST node
+ * the label resolves to.
*
* @param statement the statement to be resolved
* @param labelElement the label element to be defined in the statement's label scope
* @return the element to which the statement's label was resolved
*/
Element _resolveContinue(ContinueStatement statement,
- LabelElementImpl labelElement) {
- _resolveStatement(statement, labelElement);
+ LabelElementImpl labelElement, AstNode labelTarget) {
+ _resolveStatement(statement, labelElement, labelTarget);
return statement.label.staticElement;
}
@@ -2029,16 +2047,17 @@ class ElementResolverTest extends EngineTestCase {
* @param labelElement the label element to be defined in the statement's label scope
* @return the element to which the statement's label was resolved
*/
- void _resolveStatement(Statement statement, LabelElementImpl labelElement) {
+ void _resolveStatement(Statement statement, LabelElementImpl labelElement,
+ AstNode labelTarget) {
try {
LabelScope outerScope = _visitor.labelScope_J2DAccessor as LabelScope;
try {
LabelScope innerScope;
if (labelElement == null) {
- innerScope = new LabelScope.con1(outerScope, false, false);
+ innerScope = outerScope;
} else {
innerScope =
- new LabelScope.con2(outerScope, labelElement.name, labelElement);
+ new LabelScope(outerScope, labelElement.name, labelTarget, labelElement);
}
_visitor.labelScope_J2DAccessor = innerScope;
statement.accept(_resolver);
@@ -2661,27 +2680,27 @@ f() {
verify([source]);
}
- void test_deprecatedAnnotationUse_Deprecated() {
+ void test_deprecatedAnnotationUse_assignment() {
Source source = addSource(r'''
class A {
- @Deprecated('0.9')
- m() {}
- n() {m();}
+ @deprecated
+ A operator+(A a) { return a; }
+}
+f(A a) {
+ A b;
+ a += b;
}''');
resolve(source);
assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
verify([source]);
}
- void test_deprecatedAnnotationUse_assignment() {
+ void test_deprecatedAnnotationUse_Deprecated() {
Source source = addSource(r'''
class A {
- @deprecated
- A operator+(A a) { return a; }
-}
-f(A a) {
- A b;
- a += b;
+ @Deprecated('0.9')
+ m() {}
+ n() {m();}
}''');
resolve(source);
assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
@@ -3605,29 +3624,28 @@ main() {
verify([source]);
}
- void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
+ void test_unusedElement_getter_isUsed_invocation_implicitThis() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
get _g => null;
-}
-main(A a) {
- var v = a._g;
-}
-''');
+ useGetter() {
+ var v = _g;
+ }
+}''');
resolve(source);
assertNoErrors(source);
verify([source]);
}
- void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
+ void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
get _g => null;
}
-main() {
- var v = new A()._g;
+main(A a) {
+ var v = a._g;
}
''');
resolve(source);
@@ -3635,15 +3653,16 @@ main() {
verify([source]);
}
- void test_unusedElement_getter_isUsed_invocation_implicitThis() {
+ void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
get _g => null;
- useGetter() {
- var v = _g;
- }
-}''');
+}
+main() {
+ var v = new A()._g;
+}
+''');
resolve(source);
assertNoErrors(source);
verify([source]);
@@ -3673,35 +3692,23 @@ class A {
verify([source]);
}
- void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
+ void test_unusedElement_method_isUsed_hasReference_implicitThis() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
_m() {}
-}
-main(A a) {
- a._m;
-}''');
- resolve(source);
- assertNoErrors(source);
- verify([source]);
+ useMethod() {
+ print(_m);
}
-
- void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
}
-main() {
- new A()._m;
-}''');
+print(x) {}
+''');
resolve(source);
assertNoErrors(source);
verify([source]);
}
- void test_unusedElement_method_isUsed_hasReference_implicitThis() {
+ void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
@@ -3710,6 +3717,9 @@ class A {
print(_m);
}
}
+class B extends A {
+ _m() {}
+}
print(x) {}
''');
resolve(source);
@@ -3717,33 +3727,28 @@ print(x) {}
verify([source]);
}
- void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
+ void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
_m() {}
- useMethod() {
- print(_m);
- }
-}
-class B extends A {
- _m() {}
}
-print(x) {}
-''');
+main(A a) {
+ a._m;
+}''');
resolve(source);
assertNoErrors(source);
verify([source]);
}
- void test_unusedElement_method_isUsed_invocation_MemberElement() {
+ void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
enableUnusedElement = true;
Source source = addSource(r'''
-class A<T> {
- _m(T t) {}
+class A {
+ _m() {}
}
-main(A<int> a) {
- a._m(0);
+main() {
+ new A()._m;
}''');
resolve(source);
assertNoErrors(source);
@@ -3781,6 +3786,20 @@ class B extends A {
verify([source]);
}
+ void test_unusedElement_method_isUsed_invocation_MemberElement() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A<T> {
+ _m(T t) {}
+}
+main(A<int> a) {
+ a._m(0);
+}''');
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_unusedElement_method_isUsed_invocation_propagated() {
enableUnusedElement = true;
Source source = addSource(r'''
@@ -3879,29 +3898,28 @@ class A {
verify([source]);
}
- void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
+ void test_unusedElement_setter_isUsed_invocation_implicitThis() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
set _s(x) {}
-}
-main(A a) {
- a._s = 42;
-}
-''');
+ useSetter() {
+ _s = 42;
+ }
+}''');
resolve(source);
assertNoErrors(source);
verify([source]);
}
- void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
+ void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
set _s(x) {}
}
-main() {
- new A()._s = 42;
+main(A a) {
+ a._s = 42;
}
''');
resolve(source);
@@ -3909,15 +3927,16 @@ main() {
verify([source]);
}
- void test_unusedElement_setter_isUsed_invocation_implicitThis() {
+ void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
enableUnusedElement = true;
Source source = addSource(r'''
class A {
set _s(x) {}
- useSetter() {
- _s = 42;
- }
-}''');
+}
+main() {
+ new A()._s = 42;
+}
+''');
resolve(source);
assertNoErrors(source);
verify([source]);
@@ -7479,6 +7498,17 @@ class ResolutionVerifier extends RecursiveAstVisitor<Object> {
}
@override
+ Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ SimpleIdentifier prefix = node.prefix;
+ prefix.accept(this);
+ DartType prefixType = prefix.staticType;
+ if (prefixType == null || prefixType.isDynamic) {
+ return null;
+ }
+ return _checkResolved(node, node.staticElement, null);
+ }
+
+ @override
Object visitPrefixExpression(PrefixExpression node) {
node.visitChildren(this);
if (!node.operator.isUserDefinableOperator) {
@@ -7495,17 +7525,6 @@ class ResolutionVerifier extends RecursiveAstVisitor<Object> {
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
- SimpleIdentifier prefix = node.prefix;
- prefix.accept(this);
- DartType prefixType = prefix.staticType;
- if (prefixType == null || prefixType.isDynamic) {
- return null;
- }
- return _checkResolved(node, node.staticElement, null);
- }
-
- @override
Object visitPropertyAccess(PropertyAccess node) {
Expression target = node.realTarget;
target.accept(this);
@@ -7911,6 +7930,34 @@ class ResolverTestCase extends EngineTestCase {
}
}
+class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
+ GatheringErrorListener listener;
+
+ Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super();
+
+ @override
+ AnalysisErrorListener get errorListener => listener;
+
+ @override
+ Element internalLookup(Identifier identifier, String name,
+ LibraryElement referencingLibrary) =>
+ null;
+}
+
+class Scope_EnclosedScopeTest_test_define_normal extends Scope {
+ GatheringErrorListener listener;
+
+ Scope_EnclosedScopeTest_test_define_normal(this.listener) : super();
+
+ @override
+ AnalysisErrorListener get errorListener => listener;
+
+ @override
+ Element internalLookup(Identifier identifier, String name,
+ LibraryElement referencingLibrary) =>
+ null;
+}
+
class ScopeTest extends ResolverTestCase {
void test_define_duplicate() {
GatheringErrorListener errorListener = new GatheringErrorListener();
@@ -7968,34 +8015,6 @@ class ScopeTest_TestScope extends Scope {
localLookup(name, referencingLibrary);
}
-class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
- GatheringErrorListener listener;
-
- Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super();
-
- @override
- AnalysisErrorListener get errorListener => listener;
-
- @override
- Element internalLookup(Identifier identifier, String name,
- LibraryElement referencingLibrary) =>
- null;
-}
-
-class Scope_EnclosedScopeTest_test_define_normal extends Scope {
- GatheringErrorListener listener;
-
- Scope_EnclosedScopeTest_test_define_normal(this.listener) : super();
-
- @override
- AnalysisErrorListener get errorListener => listener;
-
- @override
- Element internalLookup(Identifier identifier, String name,
- LibraryElement referencingLibrary) =>
- null;
-}
-
class SimpleResolverTest extends ResolverTestCase {
void fail_staticInvocation() {
Source source = addSource(r'''
@@ -8012,6 +8031,39 @@ class B {
verify([source]);
}
+ void test_argumentResolution_required_matching() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3);
+ }
+ void g(a, b, c) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2]);
+ }
+
+ void test_argumentResolution_required_tooFew() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2);
+ }
+ void g(a, b, c) {}
+}''');
+ _validateArgumentResolution(source, [0, 1]);
+ }
+
+ void test_argumentResolution_required_tooMany() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3);
+ }
+ void g(a, b) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, -1]);
+ }
+
void test_argumentResolution_requiredAndNamed_extra() {
Source source = addSource(r'''
class A {
@@ -8078,39 +8130,6 @@ class A {
_validateArgumentResolution(source, [0, 1, 2, -1]);
}
- void test_argumentResolution_required_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b, c) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_required_tooFew() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2);
- }
- void g(a, b, c) {}
-}''');
- _validateArgumentResolution(source, [0, 1]);
- }
-
- void test_argumentResolution_required_tooMany() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b) {}
-}''');
- _validateArgumentResolution(source, [0, 1, -1]);
- }
-
void test_argumentResolution_setter_propagated() {
Source source = addSource(r'''
main() {
@@ -8247,6 +8266,136 @@ class B {
expect(setter.parameters[0], same(parameter));
}
+ void test_breakTarget_labeled() {
+ // Verify that the target of the label is correctly found and is recorded
+ // as the unlabeled portion of the statement.
+ String text = r'''
+void f() {
+ loop1: while (true) {
+ loop2: for (int i = 0; i < 10; i++) {
+ break loop1;
+ break loop2;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit,
+ text,
+ 'while (true)',
+ (n) => n is WhileStatement);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ BreakStatement break1 =
+ EngineTestCase.findNode(unit, text, 'break loop1', (n) => n is BreakStatement);
+ BreakStatement break2 =
+ EngineTestCase.findNode(unit, text, 'break loop2', (n) => n is BreakStatement);
+ expect(break1.target, same(whileStatement));
+ expect(break2.target, same(forStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromDo() {
+ String text = r'''
+void f() {
+ do {
+ break;
+ } while (true);
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ DoStatement doStatement =
+ EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
+ BreakStatement breakStatement =
+ EngineTestCase.findNode(unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(doStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromFor() {
+ String text = r'''
+void f() {
+ for (int i = 0; i < 10; i++) {
+ break;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ BreakStatement breakStatement =
+ EngineTestCase.findNode(unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(forStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromForEach() {
+ String text = r'''
+void f() {
+ for (x in []) {
+ break;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForEachStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForEachStatement);
+ BreakStatement breakStatement =
+ EngineTestCase.findNode(unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(forStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromSwitch() {
+ String text = r'''
+void f() {
+ while (true) {
+ switch (0) {
+ case 0:
+ break;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ SwitchStatement switchStatement =
+ EngineTestCase.findNode(unit, text, 'switch', (n) => n is SwitchStatement);
+ BreakStatement breakStatement =
+ EngineTestCase.findNode(unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(switchStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromWhile() {
+ String text = r'''
+void f() {
+ while (true) {
+ break;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement =
+ EngineTestCase.findNode(unit, text, 'while', (n) => n is WhileStatement);
+ BreakStatement breakStatement =
+ EngineTestCase.findNode(unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(whileStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakToOuterFunction() {
+ // Verify that unlabeled break statements can't resolve to loops in an
+ // outer function.
+ String text = r'''
+void f() {
+ while (true) {
+ void g() {
+ break;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ BreakStatement breakStatement =
+ EngineTestCase.findNode(unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, isNull);
+ }
+
void test_class_definesCall() {
Source source = addSource(r'''
class A {
@@ -8306,6 +8455,142 @@ class A {}''');
verify([source]);
}
+ void test_continueTarget_labeled() {
+ // Verify that the target of the label is correctly found and is recorded
+ // as the unlabeled portion of the statement.
+ String text = r'''
+void f() {
+ loop1: while (true) {
+ loop2: for (int i = 0; i < 10; i++) {
+ continue loop1;
+ continue loop2;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit,
+ text,
+ 'while (true)',
+ (n) => n is WhileStatement);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ ContinueStatement continue1 = EngineTestCase.findNode(
+ unit,
+ text,
+ 'continue loop1',
+ (n) => n is ContinueStatement);
+ ContinueStatement continue2 = EngineTestCase.findNode(
+ unit,
+ text,
+ 'continue loop2',
+ (n) => n is ContinueStatement);
+ expect(continue1.target, same(whileStatement));
+ expect(continue2.target, same(forStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromDo() {
+ String text = r'''
+void f() {
+ do {
+ continue;
+ } while (true);
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ DoStatement doStatement =
+ EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
+ ContinueStatement continueStatement =
+ EngineTestCase.findNode(unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(doStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromFor() {
+ String text = r'''
+void f() {
+ for (int i = 0; i < 10; i++) {
+ continue;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ ContinueStatement continueStatement =
+ EngineTestCase.findNode(unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(forStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromForEach() {
+ String text = r'''
+void f() {
+ for (x in []) {
+ continue;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForEachStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForEachStatement);
+ ContinueStatement continueStatement =
+ EngineTestCase.findNode(unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(forStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromWhile() {
+ String text = r'''
+void f() {
+ while (true) {
+ continue;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement =
+ EngineTestCase.findNode(unit, text, 'while', (n) => n is WhileStatement);
+ ContinueStatement continueStatement =
+ EngineTestCase.findNode(unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(whileStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueSkipsSwitch() {
+ String text = r'''
+void f() {
+ while (true) {
+ switch (0) {
+ case 0:
+ continue;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement =
+ EngineTestCase.findNode(unit, text, 'while', (n) => n is WhileStatement);
+ ContinueStatement continueStatement =
+ EngineTestCase.findNode(unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(whileStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueToOuterFunction() {
+ // Verify that unlabeled continue statements can't resolve to loops in an
+ // outer function.
+ String text = r'''
+void f() {
+ while (true) {
+ void g() {
+ continue;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ContinueStatement continueStatement =
+ EngineTestCase.findNode(unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, isNull);
+ }
+
void test_empty() {
Source source = addSource("");
resolve(source);
@@ -8891,41 +9176,6 @@ const A = null;
expect(actualElement, same(expectedElement));
}
- void test_methodCascades() {
- Source source = addSource(r'''
-class A {
- void m1() {}
- void m2() {}
- void m() {
- A a = new A();
- a..m1()
- ..m2();
- }
-}''');
- resolve(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_methodCascades_withSetter() {
- Source source = addSource(r'''
-class A {
- String name;
- void m1() {}
- void m2() {}
- void m() {
- A a = new A();
- a..m1()
- ..name = 'name'
- ..m2();
- }
-}''');
- resolve(source);
- // failing with error code: INVOCATION_OF_NON_FUNCTION
- assertNoErrors(source);
- verify([source]);
- }
-
void test_method_fromMixin() {
Source source = addSource(r'''
class B {
@@ -8961,6 +9211,41 @@ f(C c) {
verify([source]);
}
+ void test_methodCascades() {
+ Source source = addSource(r'''
+class A {
+ void m1() {}
+ void m2() {}
+ void m() {
+ A a = new A();
+ a..m1()
+ ..m2();
+ }
+}''');
+ resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_methodCascades_withSetter() {
+ Source source = addSource(r'''
+class A {
+ String name;
+ void m1() {}
+ void m2() {}
+ void m() {
+ A a = new A();
+ a..m1()
+ ..name = 'name'
+ ..m2();
+ }
+}''');
+ resolve(source);
+ // failing with error code: INVOCATION_OF_NON_FUNCTION
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_resolveAgainstNull() {
Source source = addSource(r'''
f(var p) {
@@ -9291,17 +9576,6 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
- void test_visitBinaryExpression_starID() {
- // 1 * 2.0
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1),
- TokenType.PLUS,
- _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "*");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
void test_visitBinaryExpression_star_notSpecial() {
// class A {
// A operator *(double value);
@@ -9323,6 +9597,17 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
+ void test_visitBinaryExpression_starID() {
+ // 1 * 2.0
+ BinaryExpression node = AstFactory.binaryExpression(
+ _resolvedInteger(1),
+ TokenType.PLUS,
+ _resolvedDouble(2.0));
+ node.staticElement = getMethod(_typeProvider.numType, "*");
+ expect(_analyze(node), same(_typeProvider.doubleType));
+ _listener.assertNoErrors();
+ }
+
void test_visitBooleanLiteral_false() {
// false
Expression node = AstFactory.booleanLiteral(false);
@@ -9425,6 +9710,47 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
+ void test_visitFunctionExpression_normal_block() {
+ // (p1, p2) {}
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.blockFunctionBody2());
+ _analyze5(p1);
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ dynamicType,
+ <DartType>[dynamicType, dynamicType],
+ null,
+ null,
+ resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normal_expression() {
+ // (p1, p2) -> 0
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p = AstFactory.simpleFormalParameter3("p");
+ _setType(p, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p]),
+ AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+ _analyze5(p);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ _typeProvider.intType,
+ <DartType>[dynamicType],
+ null,
+ null,
+ resultType);
+ _listener.assertNoErrors();
+ }
+
void test_visitFunctionExpression_normalAndNamed_block() {
// (p1, {p2 : 0}) {}
DartType dynamicType = _typeProvider.dynamicType;
@@ -9523,47 +9849,6 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
- void test_visitFunctionExpression_normal_block() {
- // (p1, p2) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- dynamicType,
- <DartType>[dynamicType, dynamicType],
- null,
- null,
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normal_expression() {
- // (p1, p2) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.simpleFormalParameter3("p");
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.intType,
- <DartType>[dynamicType],
- null,
- null,
- resultType);
- _listener.assertNoErrors();
- }
-
void test_visitFunctionExpression_positional_block() {
// ([p1 = 0, p2 = 0]) {}
DartType dynamicType = _typeProvider.dynamicType;
@@ -9858,6 +10143,36 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
+ void test_visitPrefixedIdentifier_getter() {
+ DartType boolType = _typeProvider.boolType;
+ PropertyAccessorElementImpl getter =
+ ElementFactory.getterElement("b", false, boolType);
+ PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+ node.identifier.staticElement = getter;
+ expect(_analyze(node), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_setter() {
+ DartType boolType = _typeProvider.boolType;
+ FieldElementImpl field =
+ ElementFactory.fieldElement("b", false, false, false, boolType);
+ PropertyAccessorElement setter = field.setter;
+ PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+ node.identifier.staticElement = setter;
+ expect(_analyze(node), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_variable() {
+ VariableElementImpl variable = ElementFactory.localVariableElement2("b");
+ variable.type = _typeProvider.boolType;
+ PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+ node.identifier.staticElement = variable;
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
void test_visitPrefixExpression_bang() {
// !0
PrefixExpression node =
@@ -9914,36 +10229,6 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
- void test_visitPrefixedIdentifier_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = getter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = setter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_variable() {
- VariableElementImpl variable = ElementFactory.localVariableElement2("b");
- variable.type = _typeProvider.boolType;
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = variable;
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
void test_visitPropertyAccess_propagated_getter() {
DartType boolType = _typeProvider.boolType;
PropertyAccessorElementImpl getter =
@@ -10042,16 +10327,16 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
_listener.assertNoErrors();
}
- void test_visitThrowExpression_withValue() {
- // throw 0
- Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
+ void test_visitThrowExpression_withoutValue() {
+ // throw
+ Expression node = AstFactory.throwExpression();
expect(_analyze(node), same(_typeProvider.bottomType));
_listener.assertNoErrors();
}
- void test_visitThrowExpression_withoutValue() {
- // throw
- Expression node = AstFactory.throwExpression();
+ void test_visitThrowExpression_withValue() {
+ // throw 0
+ Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
expect(_analyze(node), same(_typeProvider.bottomType));
_listener.assertNoErrors();
}
@@ -11470,64 +11755,6 @@ main() {
typeProvider.intType);
}
- void test_CanvasElement_getContext() {
- String code = r'''
-import 'dart:html';
-main(CanvasElement canvas) {
- var context = canvas.getContext('2d');
-}''';
- Source source = addSource(code);
- LibraryElement library = resolve(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- SimpleIdentifier identifier = EngineTestCase.findNode(
- unit,
- code,
- "context",
- (node) => node is SimpleIdentifier);
- expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
- }
-
- void test_Future_then() {
- String code = r'''
-import 'dart:async';
-main(Future<int> firstFuture) {
- firstFuture.then((p1) {
- return 1.0;
- }).then((p2) {
- return new Future<String>.value('str');
- }).then((p3) {
- });
-}''';
- Source source = addSource(code);
- LibraryElement library = resolve(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- // p1
- FormalParameter p1 = EngineTestCase.findNode(
- unit,
- code,
- "p1) {",
- (node) => node is SimpleFormalParameter);
- expect(p1.identifier.propagatedType, same(typeProvider.intType));
- // p2
- FormalParameter p2 = EngineTestCase.findNode(
- unit,
- code,
- "p2) {",
- (node) => node is SimpleFormalParameter);
- expect(p2.identifier.propagatedType, same(typeProvider.doubleType));
- // p3
- FormalParameter p3 = EngineTestCase.findNode(
- unit,
- code,
- "p3) {",
- (node) => node is SimpleFormalParameter);
- expect(p3.identifier.propagatedType, same(typeProvider.stringType));
- }
-
void test_as() {
Source source = addSource(r'''
class A {
@@ -11659,6 +11886,25 @@ main() {
}
}
+ void test_CanvasElement_getContext() {
+ String code = r'''
+import 'dart:html';
+main(CanvasElement canvas) {
+ var context = canvas.getContext('2d');
+}''';
+ Source source = addSource(code);
+ LibraryElement library = resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = resolveCompilationUnit(source, library);
+ SimpleIdentifier identifier = EngineTestCase.findNode(
+ unit,
+ code,
+ "context",
+ (node) => node is SimpleIdentifier);
+ expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
+ }
+
void test_finalPropertyInducingVariable_classMember_instance() {
addNamedSource("/lib.dart", r'''
class A {
@@ -11970,6 +12216,45 @@ f(MyList<String> list) {
expect(vIdentifier.propagatedType, same(stringType));
}
+ void test_Future_then() {
+ String code = r'''
+import 'dart:async';
+main(Future<int> firstFuture) {
+ firstFuture.then((p1) {
+ return 1.0;
+ }).then((p2) {
+ return new Future<String>.value('str');
+ }).then((p3) {
+ });
+}''';
+ Source source = addSource(code);
+ LibraryElement library = resolve(source);
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = resolveCompilationUnit(source, library);
+ // p1
+ FormalParameter p1 = EngineTestCase.findNode(
+ unit,
+ code,
+ "p1) {",
+ (node) => node is SimpleFormalParameter);
+ expect(p1.identifier.propagatedType, same(typeProvider.intType));
+ // p2
+ FormalParameter p2 = EngineTestCase.findNode(
+ unit,
+ code,
+ "p2) {",
+ (node) => node is SimpleFormalParameter);
+ expect(p2.identifier.propagatedType, same(typeProvider.doubleType));
+ // p3
+ FormalParameter p3 = EngineTestCase.findNode(
+ unit,
+ code,
+ "p3) {",
+ (node) => node is SimpleFormalParameter);
+ expect(p3.identifier.propagatedType, same(typeProvider.stringType));
+ }
+
void test_initializer() {
Source source = addSource(r'''
f() {
@@ -12052,11 +12337,11 @@ main() {
}
}
- void test_isNot_conditional() {
+ void test_is_conditional() {
Source source = addSource(r'''
class A {}
A f(var p) {
- return (p is! A) ? null : p;
+ return (p is A) ? p : null;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
@@ -12071,18 +12356,18 @@ A f(var p) {
ConditionalExpression conditional =
statement.expression as ConditionalExpression;
SimpleIdentifier variableName =
- conditional.elseExpression as SimpleIdentifier;
+ conditional.thenExpression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_isNot_if() {
+ void test_is_if() {
Source source = addSource(r'''
class A {}
A f(var p) {
- if (p is! A) {
- return null;
- } else {
+ if (p is A) {
return p;
+ } else {
+ return null;
}
}''');
LibraryElement library = resolve(source);
@@ -12096,42 +12381,46 @@ A f(var p) {
function.functionExpression.body as BlockFunctionBody;
IfStatement ifStatement = body.block.statements[0] as IfStatement;
ReturnStatement statement =
- (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
+ (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_isNot_if_logicalOr() {
+ void test_is_if_lessSpecific() {
Source source = addSource(r'''
class A {}
-A f(var p) {
- if (p is! A || null == p) {
- return null;
- } else {
+A f(A p) {
+ if (p is String) {
return p;
+ } else {
+ return null;
}
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
+ verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
- ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
- InterfaceType typeA = classA.element.type;
+// ClassDeclaration classA = (ClassDeclaration) unit.getDeclarations().get(0);
+// InterfaceType typeA = classA.getElement().getType();
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
IfStatement ifStatement = body.block.statements[0] as IfStatement;
ReturnStatement statement =
- (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
+ (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
- expect(variableName.propagatedType, same(typeA));
+ expect(variableName.propagatedType, same(null));
}
- void test_isNot_postConditional() {
+ void test_is_if_logicalAnd() {
Source source = addSource(r'''
class A {}
A f(var p) {
- A a = (p is! A) ? throw null : p;
- return p;
+ if (p is A && p != null) {
+ return p;
+ } else {
+ return null;
+ }
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
@@ -12142,18 +12431,18 @@ A f(var p) {
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- ReturnStatement statement = body.block.statements[1] as ReturnStatement;
+ IfStatement ifStatement = body.block.statements[0] as IfStatement;
+ ReturnStatement statement =
+ (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_isNot_postIf() {
+ void test_is_postConditional() {
Source source = addSource(r'''
class A {}
A f(var p) {
- if (p is! A) {
- return null;
- }
+ A a = (p is A) ? p : throw null;
return p;
}''');
LibraryElement library = resolve(source);
@@ -12170,11 +12459,16 @@ A f(var p) {
expect(variableName.propagatedType, same(typeA));
}
- void test_is_conditional() {
+ void test_is_postIf() {
Source source = addSource(r'''
class A {}
A f(var p) {
- return (p is A) ? p : null;
+ if (p is A) {
+ A a = p;
+ } else {
+ return null;
+ }
+ return p;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
@@ -12185,75 +12479,66 @@ A f(var p) {
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- ReturnStatement statement = body.block.statements[0] as ReturnStatement;
- ConditionalExpression conditional =
- statement.expression as ConditionalExpression;
- SimpleIdentifier variableName =
- conditional.thenExpression as SimpleIdentifier;
+ ReturnStatement statement = body.block.statements[1] as ReturnStatement;
+ SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_is_if() {
+ void test_is_subclass() {
Source source = addSource(r'''
class A {}
-A f(var p) {
- if (p is A) {
- return p;
- } else {
- return null;
+class B extends A {
+ B m() => this;
+}
+A f(A p) {
+ if (p is B) {
+ return p.m();
}
+ return p;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
- verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
- ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
- InterfaceType typeA = classA.element.type;
- FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
+ FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
IfStatement ifStatement = body.block.statements[0] as IfStatement;
ReturnStatement statement =
(ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
- SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
- expect(variableName.propagatedType, same(typeA));
+ MethodInvocation invocation = statement.expression as MethodInvocation;
+ expect(invocation.methodName.propagatedElement, isNotNull);
}
- void test_is_if_lessSpecific() {
+ void test_is_while() {
Source source = addSource(r'''
class A {}
-A f(A p) {
- if (p is String) {
+A f(var p) {
+ while (p is A) {
return p;
- } else {
- return null;
}
+ return p;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
-// ClassDeclaration classA = (ClassDeclaration) unit.getDeclarations().get(0);
-// InterfaceType typeA = classA.getElement().getType();
+ ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
+ InterfaceType typeA = classA.element.type;
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- IfStatement ifStatement = body.block.statements[0] as IfStatement;
+ WhileStatement whileStatement = body.block.statements[0] as WhileStatement;
ReturnStatement statement =
- (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
+ (whileStatement.body as Block).statements[0] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
- expect(variableName.propagatedType, same(null));
+ expect(variableName.propagatedType, same(typeA));
}
- void test_is_if_logicalAnd() {
+ void test_isNot_conditional() {
Source source = addSource(r'''
class A {}
A f(var p) {
- if (p is A && p != null) {
- return p;
- } else {
- return null;
- }
+ return (p is! A) ? null : p;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
@@ -12264,19 +12549,23 @@ A f(var p) {
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- IfStatement ifStatement = body.block.statements[0] as IfStatement;
- ReturnStatement statement =
- (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
- SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
+ ReturnStatement statement = body.block.statements[0] as ReturnStatement;
+ ConditionalExpression conditional =
+ statement.expression as ConditionalExpression;
+ SimpleIdentifier variableName =
+ conditional.elseExpression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_is_postConditional() {
+ void test_isNot_if() {
Source source = addSource(r'''
class A {}
A f(var p) {
- A a = (p is A) ? p : throw null;
- return p;
+ if (p is! A) {
+ return null;
+ } else {
+ return p;
+ }
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
@@ -12287,67 +12576,65 @@ A f(var p) {
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- ReturnStatement statement = body.block.statements[1] as ReturnStatement;
+ IfStatement ifStatement = body.block.statements[0] as IfStatement;
+ ReturnStatement statement =
+ (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_is_postIf() {
+ void test_isNot_if_logicalOr() {
Source source = addSource(r'''
class A {}
A f(var p) {
- if (p is A) {
- A a = p;
- } else {
+ if (p is! A || null == p) {
return null;
+ } else {
+ return p;
}
- return p;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
- verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
InterfaceType typeA = classA.element.type;
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- ReturnStatement statement = body.block.statements[1] as ReturnStatement;
+ IfStatement ifStatement = body.block.statements[0] as IfStatement;
+ ReturnStatement statement =
+ (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
- void test_is_subclass() {
+ void test_isNot_postConditional() {
Source source = addSource(r'''
class A {}
-class B extends A {
- B m() => this;
-}
-A f(A p) {
- if (p is B) {
- return p.m();
- }
+A f(var p) {
+ A a = (p is! A) ? throw null : p;
return p;
}''');
LibraryElement library = resolve(source);
assertNoErrors(source);
+ verify([source]);
CompilationUnit unit = resolveCompilationUnit(source, library);
- FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
+ ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
+ InterfaceType typeA = classA.element.type;
+ FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- IfStatement ifStatement = body.block.statements[0] as IfStatement;
- ReturnStatement statement =
- (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
- MethodInvocation invocation = statement.expression as MethodInvocation;
- expect(invocation.methodName.propagatedElement, isNotNull);
+ ReturnStatement statement = body.block.statements[1] as ReturnStatement;
+ SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
+ expect(variableName.propagatedType, same(typeA));
}
- void test_is_while() {
+ void test_isNot_postIf() {
Source source = addSource(r'''
class A {}
A f(var p) {
- while (p is A) {
- return p;
+ if (p is! A) {
+ return null;
}
return p;
}''');
@@ -12360,9 +12647,7 @@ A f(var p) {
FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
BlockFunctionBody body =
function.functionExpression.body as BlockFunctionBody;
- WhileStatement whileStatement = body.block.statements[0] as WhileStatement;
- ReturnStatement statement =
- (whileStatement.body as Block).statements[0] as ReturnStatement;
+ ReturnStatement statement = body.block.statements[1] as ReturnStatement;
SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
expect(variableName.propagatedType, same(typeA));
}
« pkg/analyzer/lib/src/generated/resolver.dart ('K') | « pkg/analyzer/lib/src/generated/resolver.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698