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..69a97cad78e3d438bb11944d71ac1a032a5df403 100644 |
--- a/pkg/analyzer/test/src/task/dart_test.dart |
+++ b/pkg/analyzer/test/src/task/dart_test.dart |
@@ -1906,6 +1906,68 @@ class Z {} |
expect(method.element.returnType, typeY); |
expect(method.element.parameters[0].type, typeZ); |
} |
+ |
+ void test_perform_cross_library_const() { |
+ enableStrongMode(); |
Brian Wilkerson
2015/09/25 20:50:17
It looks like all of the tests in this class call
Leaf
2015/09/26 00:09:33
All but the first. I split all the strong mode on
|
+ 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 +2049,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 +2104,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 +2436,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 |
@@ -2461,6 +2590,472 @@ class C { |
body.accept(verifier); |
verifier.assertResolved(); |
} |
+ |
+ // Check that even within a static variable cycle, inferred |
+ // types get propagated to the members of the cycle. |
+ void test_perform_cycle() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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() { |
+ enableStrongMode(); |
+ 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 |
@@ -2791,6 +3386,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 +3428,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 +3524,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 +3559,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'); |