| Index: pkg/analyzer/test/src/task/dart_test.dart
|
| diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
|
| index 366703821dc46e01592a4a44c9fe1ebe69f01c80..51a86fb9b3068aa9f98cbc2b1da631be35d9817d 100644
|
| --- a/pkg/analyzer/test/src/task/dart_test.dart
|
| +++ b/pkg/analyzer/test/src/task/dart_test.dart
|
| @@ -60,6 +60,7 @@ main() {
|
| runReflectiveTests(ResolveUnitTypeNamesTaskTest);
|
| runReflectiveTests(ResolveVariableReferencesTaskTest);
|
| runReflectiveTests(ScanDartTaskTest);
|
| + runReflectiveTests(StrongModeInferenceTest);
|
| runReflectiveTests(VerifyUnitTaskTest);
|
| }
|
|
|
| @@ -1906,6 +1907,68 @@ class Z {}
|
| expect(method.element.returnType, typeY);
|
| expect(method.element.parameters[0].type, typeZ);
|
| }
|
| +
|
| + void test_perform_cross_library_const() {
|
| + enableStrongMode();
|
| + AnalysisTarget firstSource = newSource(
|
| + '/first.dart',
|
| + '''
|
| +library first;
|
| +
|
| +const a = 'hello';
|
| +''');
|
| + AnalysisTarget secondSource = newSource(
|
| + '/second.dart',
|
| + '''
|
| +import 'first.dart';
|
| +
|
| +const b = a;
|
| +class M {
|
| + String c = a;
|
| +}
|
| +''');
|
| + computeResult(
|
| + new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT7,
|
| + matcher: isInferInstanceMembersInUnitTask);
|
| + CompilationUnit firstUnit = outputs[RESOLVED_UNIT7];
|
| + computeResult(
|
| + new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT7);
|
| + CompilationUnit secondUnit = outputs[RESOLVED_UNIT7];
|
| +
|
| + VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a');
|
| + VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b');
|
| + VariableDeclaration variableC = getFieldInClass(secondUnit, 'M', 'c');
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| +
|
| + expect(variableA.element.type, stringType);
|
| + expect(variableB.element.type, stringType);
|
| + expect(variableB.initializer.staticType, stringType);
|
| + expect(variableC.element.type, stringType);
|
| + expect(variableC.initializer.staticType, stringType);
|
| + }
|
| +
|
| + void test_perform_reresolution() {
|
| + enableStrongMode();
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| +const topLevel = '';
|
| +class C {
|
| + String field = topLevel;
|
| +}
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT7];
|
| + VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel');
|
| + VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field');
|
| + VariableElement topLevel = topLevelDecl.name.staticElement;
|
| + VariableElement field = fieldDecl.name.staticElement;
|
| +
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| + expect(topLevel.type, stringType);
|
| + expect(field.type, stringType);
|
| + expect(fieldDecl.initializer.staticType, stringType);
|
| + }
|
| }
|
|
|
| @reflectiveTest
|
| @@ -1987,6 +2050,23 @@ var Y = () {
|
| InterfaceType intType = context.typeProvider.intType;
|
| expect(expression.staticType, intType);
|
| }
|
| +
|
| + void test_perform_const_field() {
|
| + enableStrongMode();
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| +class M {
|
| + static const X = "";
|
| +}
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
|
| + matcher: isInferStaticVariableTypesInUnitTask);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT6];
|
| + VariableDeclaration declaration = getFieldInClass(unit, 'M', 'X');
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| + expect(declaration.element.type, stringType);
|
| + }
|
| }
|
|
|
| @reflectiveTest
|
| @@ -2025,9 +2105,59 @@ var topLevel = '';
|
|
|
| void test_perform() {
|
| AnalysisTarget source = newSource(
|
| + '/test3.dart',
|
| + '''
|
| +var topLevel3 = '';
|
| +class C {
|
| + var field3 = topLevel3;
|
| +}
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT5];
|
| + VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel3');
|
| + VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field3');
|
| + VariableElement topLevel = topLevelDecl.name.staticElement;
|
| + VariableElement field = fieldDecl.name.staticElement;
|
| +
|
| + computeResult(field, INFERRED_STATIC_VARIABLE,
|
| + matcher: isInferStaticVariableTypeTask);
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| + expect(topLevel.type, stringType);
|
| + expect(field.type, stringType);
|
| + expect(fieldDecl.initializer.staticType, stringType);
|
| + expect(outputs[INFER_STATIC_VARIABLE_ERRORS], hasLength(0));
|
| + }
|
| +
|
| + void test_perform_reresolution() {
|
| + AnalysisTarget source = newSource(
|
| '/test.dart',
|
| '''
|
| -var topLevel = '';
|
| +const topLevel = '';
|
| +class C {
|
| + String field = topLevel;
|
| +}
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT5];
|
| + VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel');
|
| + VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field');
|
| + VariableElement topLevel = topLevelDecl.name.staticElement;
|
| + VariableElement field = fieldDecl.name.staticElement;
|
| +
|
| + computeResult(field, INFERRED_STATIC_VARIABLE,
|
| + matcher: isInferStaticVariableTypeTask);
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| + expect(topLevel.type, stringType);
|
| + expect(field.type, stringType);
|
| + expect(fieldDecl.initializer.staticType, stringType);
|
| + expect(outputs[INFER_STATIC_VARIABLE_ERRORS], hasLength(0));
|
| + }
|
| +
|
| + void test_perform_const() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| +const topLevel = "hello";
|
| class C {
|
| var field = topLevel;
|
| }
|
| @@ -2307,7 +2437,7 @@ class C {
|
| computeResult(target, RESOLVED_UNIT5,
|
| matcher: isPartiallyResolveUnitReferencesTask);
|
| // Test the outputs
|
| - expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(4));
|
| + expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(5));
|
| CompilationUnit unit = outputs[RESOLVED_UNIT5];
|
| expect(unit, same(outputs[RESOLVED_UNIT5]));
|
| // Test the state of the AST
|
| @@ -2464,6 +2594,472 @@ class C {
|
| }
|
|
|
| @reflectiveTest
|
| +class StrongModeInferenceTest extends _AbstractDartTaskTest {
|
| +
|
| + @override
|
| + void setUp() {
|
| + super.setUp();
|
| + enableStrongMode();
|
| + }
|
| +
|
| + // Check that even within a static variable cycle, inferred
|
| + // types get propagated to the members of the cycle.
|
| + void test_perform_cycle() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| +var piFirst = true;
|
| +var pi = piFirst ? 3.14 : tau / 2;
|
| +var tau = piFirst ? pi * 2 : 6.28;
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
| + VariableElement piFirst =
|
| + getTopLevelVariable(unit, 'piFirst').name.staticElement;
|
| + VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement;
|
| + VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement;
|
| + Expression piFirstUse = (getTopLevelVariable(unit, 'tau').initializer
|
| + as ConditionalExpression).condition;
|
| +
|
| + expect(piFirstUse.staticType, context.typeProvider.boolType);
|
| + expect(piFirst.type, context.typeProvider.boolType);
|
| + expect(pi.type.isDynamic, isTrue);
|
| + expect(tau.type.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_perform_local_explicit_disabled() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| + test() {
|
| + int x = 3;
|
| + x = "hi";
|
| + }
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| +
|
| + List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
|
| + VariableDeclaration decl =
|
| + (statements[0] as VariableDeclarationStatement).variables.variables[0];
|
| + expect(decl.element.type, intType);
|
| + expect(decl.initializer.staticType, intType);
|
| +
|
| + ExpressionStatement statement = statements[1];
|
| + AssignmentExpression assgn = statement.expression;
|
| + expect(assgn.leftHandSide.staticType, intType);
|
| + expect(assgn.rightHandSide.staticType, stringType);
|
| + }
|
| +
|
| + void assertVariableDeclarationTypes(
|
| + VariableDeclaration decl, DartType varType, DartType initializerType) {
|
| + expect(decl.element.type, varType);
|
| + expect(decl.initializer.staticType, initializerType);
|
| + }
|
| +
|
| + void assertVariableDeclarationStatementTypes(
|
| + Statement stmt, DartType varType, DartType initializerType) {
|
| + VariableDeclaration decl =
|
| + (stmt as VariableDeclarationStatement).variables.variables[0];
|
| + assertVariableDeclarationTypes(decl, varType, initializerType);
|
| + }
|
| +
|
| + void assertAssignmentStatementTypes(
|
| + Statement stmt, DartType leftType, DartType rightType) {
|
| + AssignmentExpression assgn = (stmt as ExpressionStatement).expression;
|
| + expect(assgn.leftHandSide.staticType, leftType);
|
| + expect(assgn.rightHandSide.staticType, rightType);
|
| + }
|
| +
|
| + // Test that local variables in method bodies are inferred appropriately
|
| + void test_perform_inference_local_variables() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| + test() {
|
| + int x = 3;
|
| + x = "hi";
|
| + var y = 3;
|
| + y = "hi";
|
| + }
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| +
|
| + List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[0], intType, intType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| + assertVariableDeclarationStatementTypes(statements[2], intType, intType);
|
| + assertAssignmentStatementTypes(statements[3], intType, stringType);
|
| + }
|
| +
|
| + // Test inference interactions between local variables and fields
|
| + void test_perform_inference_local_variables_fields() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| + class A {
|
| + int x = 0;
|
| +
|
| + test1() {
|
| + var a = x;
|
| + a = "hi";
|
| + a = 3;
|
| + var b = y;
|
| + b = "hi";
|
| + b = 4;
|
| + var c = z;
|
| + c = "hi";
|
| + c = 4;
|
| + }
|
| +
|
| + int y; // field def after use
|
| + final z = 42; // should infer `int`
|
| + }
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| +
|
| + List<Statement> statements = getStatementsInMethod(unit, "A", "test1");
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[0], intType, intType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[2], intType, intType);
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[3], intType, intType);
|
| + assertAssignmentStatementTypes(statements[4], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[5], intType, intType);
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[6], intType, intType);
|
| + assertAssignmentStatementTypes(statements[7], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[8], intType, intType);
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit, "A", "x"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit, "A", "z"), intType, intType);
|
| + }
|
| +
|
| + // Test inference interactions between local variables and top level
|
| + // variables
|
| + void test_perform_inference_local_variables_topLevel() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| + int x = 0;
|
| +
|
| + test1() {
|
| + var a = x;
|
| + a = /*severe:StaticTypeError*/"hi";
|
| + a = 3;
|
| + var b = y;
|
| + b = /*severe:StaticTypeError*/"hi";
|
| + b = 4;
|
| + var c = z;
|
| + c = /*severe:StaticTypeError*/"hi";
|
| + c = 4;
|
| + }
|
| +
|
| + int y = 0; // field def after use
|
| + final z = 42; // should infer `int`
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| +
|
| + List<Statement> statements = getStatementsInTopLevelFunction(unit, "test1");
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[0], intType, intType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[2], intType, intType);
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[3], intType, intType);
|
| + assertAssignmentStatementTypes(statements[4], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[5], intType, intType);
|
| +
|
| + assertVariableDeclarationStatementTypes(statements[6], intType, intType);
|
| + assertAssignmentStatementTypes(statements[7], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[8], intType, intType);
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit, "x"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit, "y"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit, "z"), intType, intType);
|
| + }
|
| +
|
| + // Test that inference does not propagate from null
|
| + void test_perform_inference_null() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| + var x = null;
|
| + var y = 3;
|
| + class A {
|
| + static var x = null;
|
| + static var y = 3;
|
| +
|
| + var x2 = null;
|
| + var y2 = 3;
|
| + }
|
| +
|
| + test() {
|
| + x = "hi";
|
| + y = /*severe:StaticTypeError*/"hi";
|
| + A.x = "hi";
|
| + A.y = /*severe:StaticTypeError*/"hi";
|
| + new A().x2 = "hi";
|
| + new A().y2 = /*severe:StaticTypeError*/"hi";
|
| + }
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| + DartType bottomType = context.typeProvider.bottomType;
|
| + DartType dynamicType = context.typeProvider.dynamicType;
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit, "x"), dynamicType, bottomType);
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit, "y"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit, "A", "x"), dynamicType, bottomType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit, "A", "y"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit, "A", "x2"), dynamicType, bottomType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit, "A", "y2"), intType, intType);
|
| +
|
| + List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
|
| +
|
| + assertAssignmentStatementTypes(statements[0], dynamicType, stringType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[2], dynamicType, stringType);
|
| + assertAssignmentStatementTypes(statements[3], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[4], dynamicType, stringType);
|
| + assertAssignmentStatementTypes(statements[5], intType, stringType);
|
| + }
|
| +
|
| + // Test inference across units (non-cyclic)
|
| + void test_perform_inference_cross_unit_non_cyclic() {
|
| + AnalysisTarget firstSource = newSource(
|
| + '/a.dart',
|
| + '''
|
| + var x = 2;
|
| + class A { static var x = 2; }
|
| +''');
|
| + AnalysisTarget secondSource = newSource(
|
| + '/test.dart',
|
| + '''
|
| + import 'a.dart';
|
| + var y = x;
|
| + class B { static var y = A.x; }
|
| +
|
| + test1() {
|
| + x = /*severe:StaticTypeError*/"hi";
|
| + y = /*severe:StaticTypeError*/"hi";
|
| + A.x = /*severe:StaticTypeError*/"hi";
|
| + B.y = /*severe:StaticTypeError*/"hi";
|
| + }
|
| +''');
|
| + computeResult(
|
| + new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8);
|
| + CompilationUnit unit1 = outputs[RESOLVED_UNIT8];
|
| + computeResult(
|
| + new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
|
| + CompilationUnit unit2 = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| + DartType dynamicType = context.typeProvider.dynamicType;
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit1, "x"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit1, "A", "x"), intType, intType);
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit2, "y"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit2, "B", "y"), intType, intType);
|
| +
|
| + List<Statement> statements =
|
| + getStatementsInTopLevelFunction(unit2, "test1");
|
| +
|
| + assertAssignmentStatementTypes(statements[0], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| + }
|
| +
|
| + // Test inference across units (cyclic)
|
| + void test_perform_inference_cross_unit_cyclic() {
|
| + AnalysisTarget firstSource = newSource(
|
| + '/a.dart',
|
| + '''
|
| + import 'test.dart';
|
| + var x = 2;
|
| + class A { static var x = 2; }
|
| +''');
|
| + AnalysisTarget secondSource = newSource(
|
| + '/test.dart',
|
| + '''
|
| + import 'a.dart';
|
| + var y = x;
|
| + class B { static var y = A.x; }
|
| +
|
| + test1() {
|
| + int t = 3;
|
| + t = x;
|
| + t = y;
|
| + t = A.x;
|
| + t = B.y;
|
| + }
|
| +''');
|
| + computeResult(
|
| + new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8);
|
| + CompilationUnit unit1 = outputs[RESOLVED_UNIT8];
|
| + computeResult(
|
| + new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
|
| + CompilationUnit unit2 = outputs[RESOLVED_UNIT8];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit1, "x"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit1, "A", "x"), intType, intType);
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit2, "y"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit2, "B", "y"), intType, intType);
|
| +
|
| + List<Statement> statements =
|
| + getStatementsInTopLevelFunction(unit2, "test1");
|
| +
|
| + assertAssignmentStatementTypes(statements[1], intType, intType);
|
| + assertAssignmentStatementTypes(statements[2], intType, intType);
|
| + assertAssignmentStatementTypes(statements[3], intType, intType);
|
| + assertAssignmentStatementTypes(statements[4], intType, intType);
|
| + }
|
| +
|
| + // Test inference of instance fields across units
|
| + // TODO(leafp): Fix this
|
| + // https://github.com/dart-lang/dev_compiler/issues/354
|
| + void fail_perform_inference_cross_unit_instance() {
|
| + List<Source> sources = newSources({
|
| + '/a7.dart': '''
|
| + import 'b7.dart';
|
| + class A {
|
| + final a2 = new B().b2;
|
| + }
|
| + ''',
|
| + '/b7.dart': '''
|
| + class B {
|
| + final b2 = 1;
|
| + }
|
| + ''',
|
| + '/main7.dart': '''
|
| + import "a7.dart";
|
| +
|
| + test1() {
|
| + int x = 0;
|
| + x = new A().a2;
|
| + }
|
| + '''
|
| + });
|
| + List<dynamic> units =
|
| + computeLibraryResults(sources, RESOLVED_UNIT8).toList();
|
| + CompilationUnit unit0 = units[0];
|
| + CompilationUnit unit1 = units[1];
|
| + CompilationUnit unit2 = units[2];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit0, "A", "a2"), intType, intType);
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit1, "B", "b2"), intType, intType);
|
| +
|
| + List<Statement> statements =
|
| + getStatementsInTopLevelFunction(unit2, "test1");
|
| +
|
| + assertAssignmentStatementTypes(statements[1], intType, intType);
|
| + }
|
| +
|
| + // Test inference between static and instance fields
|
| + // TODO(leafp): Fix this
|
| + // https://github.com/dart-lang/dev_compiler/issues/354
|
| + void fail_perform_inference_cross_unit_static_instance() {
|
| + List<Source> sources = newSources({
|
| + '/a.dart': '''
|
| + import 'b.dart';
|
| + class A {
|
| + static final a1 = B.b1;
|
| + final a2 = new B().b2;
|
| + }
|
| + ''',
|
| + '/b.dart': '''
|
| + class B {
|
| + static final b1 = 1;
|
| + final b2 = 1;
|
| + }
|
| + ''',
|
| + '/main.dart': '''
|
| + import "a.dart";
|
| +
|
| + test1() {
|
| + int x = 0;
|
| + // inference in A now works.
|
| + x = A.a1;
|
| + x = new A().a2;
|
| + }
|
| + '''
|
| + });
|
| + List<dynamic> units =
|
| + computeLibraryResults(sources, RESOLVED_UNIT8).toList();
|
| + CompilationUnit unit0 = units[0];
|
| + CompilationUnit unit1 = units[1];
|
| + CompilationUnit unit2 = units[2];
|
| +
|
| + InterfaceType intType = context.typeProvider.intType;
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit0, "A", "a1"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit0, "A", "a2"), intType, intType);
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit1, "B", "b1"), intType, intType);
|
| + assertVariableDeclarationTypes(
|
| + getFieldInClass(unit1, "B", "b2"), intType, intType);
|
| +
|
| + List<Statement> statements =
|
| + getStatementsInTopLevelFunction(unit2, "test1");
|
| +
|
| + assertAssignmentStatementTypes(statements[1], intType, intType);
|
| + assertAssignmentStatementTypes(statements[2], intType, intType);
|
| + }
|
| +}
|
| +
|
| +@reflectiveTest
|
| class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest {
|
| test_perform() {
|
| Source sourceLib = newSource(
|
| @@ -2791,6 +3387,23 @@ main() {
|
| errorListener.assertErrorsWithCodes(
|
| <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]);
|
| }
|
| +
|
| + void test_perform_reresolution() {
|
| + enableStrongMode();
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| + '''
|
| +const topLevel = 3;
|
| +class C {
|
| + String field = topLevel;
|
| +}
|
| +''');
|
| + computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS);
|
| + // validate
|
| + _fillErrorListener(VERIFY_ERRORS);
|
| + errorListener.assertErrorsWithCodes(
|
| + <ErrorCode>[StaticTypeWarningCode.INVALID_ASSIGNMENT]);
|
| + }
|
| }
|
|
|
| class _AbstractDartTaskTest extends AbstractContextTest {
|
| @@ -2816,6 +3429,17 @@ class _AbstractDartTaskTest extends AbstractContextTest {
|
| });
|
| }
|
|
|
| + List<dynamic> computeLibraryResults(
|
| + List<Source> sources, ResultDescriptor result,
|
| + {isInstanceOf matcher: null}) {
|
| + dynamic compute(Source source) {
|
| + computeResult(new LibrarySpecificUnit(source, source), result,
|
| + matcher: matcher);
|
| + return outputs[result];
|
| + }
|
| + return sources.map(compute).toList();
|
| + }
|
| +
|
| /**
|
| * Create a script object with a single fragment containing the given
|
| * [scriptContent].
|
| @@ -2901,6 +3525,20 @@ class _AbstractDartTaskTest extends AbstractContextTest {
|
| return null;
|
| }
|
|
|
| + List<Statement> getStatementsInMethod(
|
| + CompilationUnit unit, String className, String methodName) {
|
| + MethodDeclaration method = getMethodInClass(unit, className, methodName);
|
| + BlockFunctionBody body = method.body;
|
| + return body.block.statements;
|
| + }
|
| +
|
| + List<Statement> getStatementsInTopLevelFunction(
|
| + CompilationUnit unit, String functionName) {
|
| + FunctionDeclaration function = getTopLevelFunction(unit, functionName);
|
| + BlockFunctionBody body = function.functionExpression.body;
|
| + return body.block.statements;
|
| + }
|
| +
|
| /**
|
| * Return the declaration of the top-level variable with the given
|
| * [variableName] in the given compilation [unit].
|
| @@ -2922,6 +3560,23 @@ class _AbstractDartTaskTest extends AbstractContextTest {
|
| return null;
|
| }
|
|
|
| + /**
|
| + * Return the declaration of the top-level function with the given
|
| + * [functionName] in the given compilation [unit].
|
| + */
|
| + FunctionDeclaration getTopLevelFunction(
|
| + CompilationUnit unit, String functionName) {
|
| + NodeList<CompilationUnitMember> unitMembers = unit.declarations;
|
| + for (CompilationUnitMember unitMember in unitMembers) {
|
| + if (unitMember is FunctionDeclaration) {
|
| + if (unitMember.name.name == functionName) {
|
| + return unitMember;
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| void setUp() {
|
| super.setUp();
|
| emptySource = newSource('/test.dart');
|
|
|