| 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));
|
| }
|
|
|