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 1c94faf5499ec7b3dd27fc87e62a9d4548518cfd..e467615296e982f4d167fce993a403783ec735e1 100644 |
--- a/pkg/analyzer/test/src/task/dart_test.dart |
+++ b/pkg/analyzer/test/src/task/dart_test.dart |
@@ -43,6 +43,7 @@ main() { |
runReflectiveTests(ComputeConstantDependenciesTaskTest); |
runReflectiveTests(ComputeConstantValueTaskTest); |
runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest); |
+ runReflectiveTests(ComputeLibraryCycleTaskTest); |
runReflectiveTests(ContainingLibrariesTaskTest); |
runReflectiveTests(DartErrorsTaskTest); |
runReflectiveTests(EvaluateUnitConstantsTaskTest); |
@@ -57,8 +58,9 @@ main() { |
runReflectiveTests(LibraryUnitErrorsTaskTest); |
runReflectiveTests(ParseDartTaskTest); |
runReflectiveTests(PartiallyResolveUnitReferencesTaskTest); |
- runReflectiveTests(ResolveFunctionBodiesInUnitTaskTest); |
+ runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest); |
runReflectiveTests(ResolveLibraryTypeNamesTaskTest); |
+ runReflectiveTests(ResolveUnitTaskTest); |
runReflectiveTests(ResolveUnitTypeNamesTaskTest); |
runReflectiveTests(ResolveVariableReferencesTaskTest); |
runReflectiveTests(ScanDartTaskTest); |
@@ -114,10 +116,9 @@ isInstanceOf isLibraryUnitErrorsTask = |
isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>(); |
isInstanceOf isPartiallyResolveUnitReferencesTask = |
new isInstanceOf<PartiallyResolveUnitReferencesTask>(); |
-isInstanceOf isResolveFunctionBodiesInUnitTask = |
- new isInstanceOf<ResolveFunctionBodiesInUnitTask>(); |
isInstanceOf isResolveLibraryTypeNamesTask = |
new isInstanceOf<ResolveLibraryTypeNamesTask>(); |
+isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>(); |
isInstanceOf isResolveUnitTypeNamesTask = |
new isInstanceOf<ResolveUnitTypeNamesTask>(); |
isInstanceOf isResolveVariableReferencesTask = |
@@ -1429,6 +1430,13 @@ const x = 1; |
@reflectiveTest |
class ComputeInferableStaticVariableDependenciesTaskTest |
extends _AbstractDartTaskTest { |
+ @override |
+ void setUp() { |
+ super.setUp(); |
+ // Variable dependencies are only available in strong mode. |
+ enableStrongMode(); |
+ } |
+ |
test_perform() { |
AnalysisTarget source = newSource( |
'/test.dart', |
@@ -1494,6 +1502,305 @@ class ContainingLibrariesTaskTest extends _AbstractDartTaskTest { |
} |
@reflectiveTest |
+class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest { |
+ @override |
+ void setUp() { |
+ super.setUp(); |
+ enableStrongMode(); |
+ } |
+ |
+ void test_library_cycle_singleton() { |
+ Source source = newSource( |
+ '/test.dart', |
+ ''' |
+import 'dart:core'; |
+'''); |
+ computeResult(new LibrarySpecificUnit(source, source), LIBRARY_CYCLE); |
+ List<LibraryElement> component = outputs[LIBRARY_CYCLE]; |
+ List<CompilationUnitElement> units = outputs[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> deps = outputs[LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(component, hasLength(1)); |
+ expect(units, hasLength(1)); |
+ expect(deps, hasLength(1)); |
+ } |
+ |
+ void test_library_cycle_linear() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+''', |
+ '/b.dart': ''' |
+import 'a.dart'; |
+ ''' |
+ }); |
+ List<Map<ResultDescriptor, dynamic>> results = |
+ computeLibraryResultsMap(sources, LIBRARY_CYCLE); |
+ List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
+ List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
+ expect(component0, hasLength(1)); |
+ expect(component1, hasLength(1)); |
+ |
+ List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
+ expect(units0, hasLength(1)); |
+ expect(units1, hasLength(1)); |
+ |
+ List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(dep0, hasLength(1)); // dart:core |
+ expect(dep1, hasLength(2)); // dart:core, a.dart |
+ } |
+ |
+ void test_library_cycle_tree() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+''', |
+ '/b.dart': ''' |
+ ''', |
+ '/c.dart': ''' |
+ import 'a.dart'; |
+ import 'b.dart'; |
+ ''' |
+ }); |
+ List<Map<ResultDescriptor, dynamic>> results = |
+ computeLibraryResultsMap(sources, LIBRARY_CYCLE); |
+ List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
+ List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
+ List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; |
+ expect(component0, hasLength(1)); |
+ expect(component1, hasLength(1)); |
+ expect(component2, hasLength(1)); |
+ |
+ List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; |
+ expect(units0, hasLength(1)); |
+ expect(units1, hasLength(1)); |
+ expect(units2, hasLength(1)); |
+ |
+ List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(dep0, hasLength(1)); // dart:core |
+ expect(dep1, hasLength(1)); // dart:core, |
+ expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart |
+ } |
+ |
+ void test_library_cycle_loop() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'c.dart'; |
+''', |
+ '/b.dart': ''' |
+ import 'a.dart'; |
+ ''', |
+ '/c.dart': ''' |
+ import 'b.dart'; |
+ ''' |
+ }); |
+ List<Map<ResultDescriptor, dynamic>> results = |
+ computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList(); |
+ List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
+ List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
+ List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; |
+ |
+ expect(component0, hasLength(3)); |
+ expect(component1, hasLength(3)); |
+ expect(component2, hasLength(3)); |
+ |
+ List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; |
+ expect(units0, hasLength(3)); |
+ expect(units1, hasLength(3)); |
+ expect(units2, hasLength(3)); |
+ |
+ List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(dep0, hasLength(1)); // dart:core |
+ expect(dep1, hasLength(1)); // dart:core |
+ expect(dep2, hasLength(1)); // dart:core |
+ } |
+ |
+ void test_library_cycle_self_loop() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'a.dart'; |
+''' |
+ }); |
+ List<Map<ResultDescriptor, dynamic>> results = |
+ computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList(); |
+ List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
+ expect(component0, hasLength(1)); |
+ |
+ List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
+ expect(units0, hasLength(1)); |
+ |
+ List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(dep0, hasLength(1)); // dart:core |
+ } |
+ |
+ void test_library_double_loop() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+''', |
+ '/b.dart': ''' |
+ import 'a.dart'; |
+ ''', |
+ '/c.dart': ''' |
+ import 'd.dart' as foo; |
+ import 'a.dart' as bar; |
+ export 'b.dart'; |
+ ''', |
+ '/d.dart': ''' |
+ import 'c.dart' as foo; |
+ import 'b.dart' as bar; |
+ export 'a.dart'; |
+ ''' |
+ }); |
+ List<Map<ResultDescriptor, dynamic>> results = |
+ computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList(); |
+ List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
+ List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
+ List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; |
+ List<LibraryElement> component3 = results[3][LIBRARY_CYCLE]; |
+ |
+ expect(component0, hasLength(2)); |
+ expect(component1, hasLength(2)); |
+ expect(component2, hasLength(2)); |
+ expect(component3, hasLength(2)); |
+ |
+ List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units3 = results[3][LIBRARY_CYCLE_UNITS]; |
+ expect(units0, hasLength(2)); |
+ expect(units1, hasLength(2)); |
+ expect(units2, hasLength(2)); |
+ expect(units3, hasLength(2)); |
+ |
+ List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(dep0, hasLength(1)); // dart:core |
+ expect(dep1, hasLength(1)); // dart:core |
+ expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart |
+ expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart |
+ } |
+ |
+ void test_library_double_loop_parts() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+ part 'aa.dart'; |
+ part 'ab.dart'; |
+''', |
+ '/b.dart': ''' |
+ import 'a.dart'; |
+''', |
+ '/aa.dart': ''' |
+''', |
+ '/ab.dart': ''' |
+''', |
+ '/c.dart': ''' |
+ import 'd.dart' as foo; |
+ import 'a.dart' as bar; |
+ export 'b.dart'; |
+''', |
+ '/d.dart': ''' |
+ import 'c.dart' as foo; |
+ import 'b.dart' as bar; |
+ export 'a.dart'; |
+ part 'da.dart'; |
+ part 'db.dart'; |
+''', |
+ '/da.dart': ''' |
+''', |
+ '/db.dart': ''' |
+''' |
+ }); |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[0]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results0 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[1], sources[1]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results1 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[2]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results2 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[3]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results3 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[4], sources[4]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results4 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[5], sources[5]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results5 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[5], sources[6]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results6 = outputs; |
+ computeResult( |
+ new LibrarySpecificUnit(sources[5], sources[7]), LIBRARY_CYCLE); |
+ Map<ResultDescriptor, dynamic> results7 = outputs; |
+ |
+ List<LibraryElement> component0 = results0[LIBRARY_CYCLE]; |
+ List<LibraryElement> component1 = results1[LIBRARY_CYCLE]; |
+ List<LibraryElement> component2 = results2[LIBRARY_CYCLE]; |
+ List<LibraryElement> component3 = results3[LIBRARY_CYCLE]; |
+ List<LibraryElement> component4 = results4[LIBRARY_CYCLE]; |
+ List<LibraryElement> component5 = results5[LIBRARY_CYCLE]; |
+ List<LibraryElement> component6 = results6[LIBRARY_CYCLE]; |
+ List<LibraryElement> component7 = results7[LIBRARY_CYCLE]; |
+ |
+ expect(component0, hasLength(2)); |
+ expect(component1, hasLength(2)); |
+ expect(component2, hasLength(2)); |
+ expect(component3, hasLength(2)); |
+ expect(component4, hasLength(2)); |
+ expect(component5, hasLength(2)); |
+ expect(component6, hasLength(2)); |
+ expect(component7, hasLength(2)); |
+ |
+ List<CompilationUnitElement> units0 = results0[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units1 = results1[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units2 = results2[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units3 = results3[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units4 = results4[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units5 = results5[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units6 = results6[LIBRARY_CYCLE_UNITS]; |
+ List<CompilationUnitElement> units7 = results7[LIBRARY_CYCLE_UNITS]; |
+ expect(units0, hasLength(4)); |
+ expect(units1, hasLength(4)); |
+ expect(units2, hasLength(4)); |
+ expect(units3, hasLength(4)); |
+ expect(units4, hasLength(4)); |
+ expect(units5, hasLength(4)); |
+ expect(units6, hasLength(4)); |
+ expect(units7, hasLength(4)); |
+ |
+ List<CompilationUnitElement> dep0 = results0[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep1 = results1[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep2 = results2[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep3 = results3[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep4 = results4[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep5 = results5[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep6 = results6[LIBRARY_CYCLE_DEPENDENCIES]; |
+ List<CompilationUnitElement> dep7 = results7[LIBRARY_CYCLE_DEPENDENCIES]; |
+ expect(dep0, hasLength(1)); // dart:core |
+ expect(dep1, hasLength(1)); // dart:core |
+ expect(dep2, hasLength(1)); // dart:core |
+ expect(dep3, hasLength(1)); // dart:core |
+ expect(dep4, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
+ expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
+ expect(dep6, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
+ expect(dep7, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
+ } |
+} |
+ |
+@reflectiveTest |
class DartErrorsTaskTest extends _AbstractDartTaskTest { |
test_perform_definingCompilationUnit() { |
AnalysisTarget library = |
@@ -1955,9 +2262,9 @@ class X {} |
class Y {} |
class Z {} |
'''); |
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7, |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8, |
matcher: isInferInstanceMembersInUnitTask); |
- CompilationUnit unit = outputs[RESOLVED_UNIT7]; |
+ CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
VariableDeclaration field = getFieldInClass(unit, 'B', 'f'); |
MethodDeclaration method = getMethodInClass(unit, 'B', 'm'); |
DartType typeX = getClass(unit, 'X').element.type; |
@@ -1989,12 +2296,12 @@ class M { |
} |
'''); |
computeResult( |
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT7, |
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8, |
matcher: isInferInstanceMembersInUnitTask); |
- CompilationUnit firstUnit = outputs[RESOLVED_UNIT7]; |
+ CompilationUnit firstUnit = outputs[RESOLVED_UNIT8]; |
computeResult( |
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT7); |
- CompilationUnit secondUnit = outputs[RESOLVED_UNIT7]; |
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8); |
+ CompilationUnit secondUnit = outputs[RESOLVED_UNIT8]; |
VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a'); |
VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b'); |
@@ -2018,8 +2325,8 @@ class C { |
String field = topLevel; |
} |
'''); |
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7); |
- CompilationUnit unit = outputs[RESOLVED_UNIT7]; |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel'); |
VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field'); |
VariableElement topLevel = topLevelDecl.name.staticElement; |
@@ -2165,6 +2472,7 @@ var topLevel = ''; |
} |
void test_perform() { |
+ enableStrongMode(); |
AnalysisTarget source = newSource( |
'/test3.dart', |
''' |
@@ -2186,10 +2494,10 @@ class C { |
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() { |
+ enableStrongMode(); |
AnalysisTarget source = newSource( |
'/test.dart', |
''' |
@@ -2210,10 +2518,10 @@ class C { |
InterfaceType stringType = context.typeProvider.stringType; |
expect(topLevel.type, stringType); |
expect(field.type, stringType); |
- expect(outputs[INFER_STATIC_VARIABLE_ERRORS], hasLength(0)); |
} |
void test_perform_cycle() { |
+ enableStrongMode(); |
AnalysisTarget source = newSource( |
'/test.dart', |
''' |
@@ -2233,10 +2541,10 @@ var tau = piFirst ? pi * 2 : 6.28; |
expect(piFirst.type, context.typeProvider.boolType); |
expect(pi.type.isDynamic, isTrue); |
expect(tau.type.isDynamic, isTrue); |
- expect(outputs[INFER_STATIC_VARIABLE_ERRORS], hasLength(0)); |
} |
void test_perform_error() { |
+ enableStrongMode(); |
AnalysisTarget source = newSource( |
'/test.dart', |
''' |
@@ -2249,10 +2557,10 @@ var a = '' / null; |
computeResult(a, INFERRED_STATIC_VARIABLE, |
matcher: isInferStaticVariableTypeTask); |
expect(a.type.isDynamic, isTrue); |
- expect(outputs[INFER_STATIC_VARIABLE_ERRORS], hasLength(1)); |
} |
void test_perform_null() { |
+ enableStrongMode(); |
AnalysisTarget source = newSource( |
'/test.dart', |
''' |
@@ -2265,32 +2573,6 @@ var a = null; |
computeResult(a, INFERRED_STATIC_VARIABLE, |
matcher: isInferStaticVariableTypeTask); |
expect(a.type.isDynamic, isTrue); |
- expect(outputs[INFER_STATIC_VARIABLE_ERRORS], hasLength(0)); |
- } |
- |
- void test_perform_reresolution() { |
- AnalysisTarget source = newSource( |
- '/test.dart', |
- ''' |
-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)); |
} |
} |
@@ -2498,7 +2780,7 @@ class C { |
computeResult(target, RESOLVED_UNIT5, |
matcher: isPartiallyResolveUnitReferencesTask); |
// Test the outputs |
- expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(5)); |
+ expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(4)); |
CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
expect(unit, same(outputs[RESOLVED_UNIT5])); |
// Test the state of the AST |
@@ -2506,9 +2788,6 @@ class C { |
VariableDeclaration variableA = a.variables.variables[0]; |
SimpleIdentifier initializer = variableA.initializer; |
expect(initializer.staticElement, isNotNull); |
- // Test the error generation |
- _fillErrorListener(PARTIALLY_RESOLVE_REFERENCES_ERRORS); |
- errorListener.assertNoErrors(); |
} |
test_perform_importExport() { |
@@ -2619,132 +2898,361 @@ class C { |
} |
@reflectiveTest |
-class ResolveFunctionBodiesInUnitTaskTest extends _AbstractDartTaskTest { |
- void test_perform() { |
- AnalysisTarget source = newSource( |
- '/test.dart', |
- ''' |
-void f() { |
- var c = new C(); |
- c.m(); |
-} |
-class C { |
- void m() { |
- f(); |
+class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest { |
+ @override |
+ void setUp() { |
+ super.setUp(); |
+ enableStrongMode(); |
} |
-} |
-'''); |
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8, |
- matcher: isResolveFunctionBodiesInUnitTask); |
- CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
- FunctionDeclaration f = unit.declarations[0]; |
- _assertResolved(f.functionExpression.body); |
+ // Test inference of instance fields across units |
+ void test_perform_inference_instance() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+ class A { |
+ final a2 = new B().b2; |
+ } |
- MethodDeclaration m = (unit.declarations[1] as ClassDeclaration).members[0]; |
- _assertResolved(m.body); |
+ class B { |
+ final b2 = 1; |
+ } |
+ ''', |
+ '/main.dart': ''' |
+ import "a.dart"; |
- expect(outputs[RESOLVE_FUNCTION_BODIES_ERRORS], hasLength(0)); |
- } |
+ test1() { |
+ int x = 0; |
+ x = new A().a2; |
+ } |
+ ''' |
+ }); |
+ InterfaceType intType = context.typeProvider.intType; |
+ DartType dynamicType = context.typeProvider.dynamicType; |
- void _assertResolved(FunctionBody body) { |
- ResolutionVerifier verifier = new ResolutionVerifier(); |
- body.accept(verifier); |
- verifier.assertResolved(); |
- } |
-} |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
-@reflectiveTest |
-class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest { |
- test_perform() { |
- Source sourceLib = newSource( |
- '/my_lib.dart', |
- ''' |
-library my_lib; |
-part 'my_part.dart'; |
-class A {} |
-class B extends A {} |
-'''); |
- newSource( |
- '/my_part.dart', |
- ''' |
-part of my_lib; |
-class C extends A {} |
-'''); |
- computeResult(sourceLib, LIBRARY_ELEMENT5, |
- matcher: isResolveLibraryTypeNamesTask); |
- // validate |
- LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
- { |
- ClassElement classB = library.getType('B'); |
- expect(classB.supertype.displayName, 'A'); |
- } |
- { |
- ClassElement classC = library.getType('C'); |
- expect(classC.supertype.displayName, 'A'); |
- } |
- } |
+ // A.a2 should now be resolved on the rhs, but not yet inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
- test_perform_external() { |
- Source sourceA = newSource( |
- '/a.dart', |
- ''' |
-library a; |
-import 'b.dart'; |
-class A extends B {} |
-'''); |
- newSource( |
- '/b.dart', |
- ''' |
-library b; |
-class B {} |
-'''); |
- // The reference A to B should be resolved, but there's no requirement that |
- // the full class hierarchy be resolved. |
- computeResult(sourceA, LIBRARY_ELEMENT5, |
- matcher: isResolveLibraryTypeNamesTask); |
- // validate |
- LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
- { |
- ClassElement clazz = library.getType('A'); |
- expect(clazz.displayName, 'A'); |
- clazz = clazz.supertype.element; |
- expect(clazz.displayName, 'B'); |
- } |
- } |
-} |
+ // B.b2 shoud be resolved on the rhs, but not yet inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "B", "b2"), dynamicType, intType); |
-@reflectiveTest |
-class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest { |
- test_perform() { |
- Source source = newSource( |
- '/test.dart', |
- ''' |
-class A {} |
-class B extends A {} |
-int f(String p) => p.length; |
-'''); |
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
- computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask); |
- // validate |
- CompilationUnit unit = outputs[RESOLVED_UNIT3]; |
- { |
- ClassDeclaration nodeA = unit.declarations[0]; |
- ClassDeclaration nodeB = unit.declarations[1]; |
- DartType extendsType = nodeB.extendsClause.superclass.type; |
- expect(extendsType, nodeA.element.type); |
- } |
- { |
- FunctionDeclaration functionNode = unit.declarations[2]; |
- DartType returnType = functionNode.returnType.type; |
- List<FormalParameter> parameters = |
- functionNode.functionExpression.parameters.parameters; |
- expect(returnType.displayName, 'int'); |
- expect(parameters[0].element.type.displayName, 'String'); |
- } |
+ computeResult( |
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); |
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; |
+ |
+ // A.a2 should now be fully resolved and inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
+ |
+ // B.b2 should now be fully resolved and inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "B", "b2"), intType, intType); |
} |
- test_perform_errors() { |
+ // Test inference of instance fields across units |
+ void test_perform_inference_cross_unit_instance() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+ class A { |
+ final a2 = new B().b2; |
+ } |
+ ''', |
+ '/b.dart': ''' |
+ class B { |
+ final b2 = 1; |
+ } |
+ ''', |
+ '/main.dart': ''' |
+ import "a.dart"; |
+ |
+ test1() { |
+ int x = 0; |
+ x = new A().a2; |
+ } |
+ ''' |
+ }); |
+ InterfaceType intType = context.typeProvider.intType; |
+ DartType dynamicType = context.typeProvider.dynamicType; |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); |
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; |
+ |
+ // B.b2 shoud be resolved on the rhs, but not yet inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b2"), dynamicType, intType); |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
+ |
+ // B.b2 should now be fully resolved and inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b2"), intType, intType); |
+ |
+ // A.a2 should now be resolved on the rhs, but not yet inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), dynamicType, intType); |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); |
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; |
+ |
+ // A.a2 should now be fully resolved and inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), intType, intType); |
+ |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b2"), intType, intType); |
+ } |
+ |
+ // Test inference of instance fields across units with cycles |
+ void test_perform_inference_cross_unit_instance_cyclic() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+ class A { |
+ final a2 = new B().b2; |
+ } |
+ ''', |
+ '/b.dart': ''' |
+ import 'a.dart'; |
+ class B { |
+ final b2 = 1; |
+ } |
+ ''', |
+ '/main.dart': ''' |
+ import "a.dart"; |
+ |
+ test1() { |
+ int x = 0; |
+ x = new A().a2; |
+ } |
+ ''' |
+ }); |
+ InterfaceType intType = context.typeProvider.intType; |
+ DartType dynamicType = context.typeProvider.dynamicType; |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
+ |
+ // A.a2 should now be resolved on the rhs, but not yet inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); |
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; |
+ |
+ // A.a2 should now be fully resolved and inferred. |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
+ } |
+ |
+ // Test inference between static and instance fields |
+ void test_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; |
+ } |
+ ''' |
+ }); |
+ InterfaceType intType = context.typeProvider.intType; |
+ DartType dynamicType = context.typeProvider.dynamicType; |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); |
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; |
+ |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b1"), intType, intType); |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b2"), dynamicType, intType); |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
+ |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a1"), intType, intType); |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit0, "A", "a2"), dynamicType, intType); |
+ |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b1"), intType, intType); |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "B", "b2"), intType, intType); |
+ |
+ computeResult( |
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); |
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; |
+ |
+ 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); |
+ } |
+} |
+ |
+@reflectiveTest |
+class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest { |
+ test_perform() { |
+ Source sourceLib = newSource( |
+ '/my_lib.dart', |
+ ''' |
+library my_lib; |
+part 'my_part.dart'; |
+class A {} |
+class B extends A {} |
+'''); |
+ newSource( |
+ '/my_part.dart', |
+ ''' |
+part of my_lib; |
+class C extends A {} |
+'''); |
+ computeResult(sourceLib, LIBRARY_ELEMENT5, |
+ matcher: isResolveLibraryTypeNamesTask); |
+ // validate |
+ LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
+ { |
+ ClassElement classB = library.getType('B'); |
+ expect(classB.supertype.displayName, 'A'); |
+ } |
+ { |
+ ClassElement classC = library.getType('C'); |
+ expect(classC.supertype.displayName, 'A'); |
+ } |
+ } |
+ |
+ test_perform_external() { |
+ Source sourceA = newSource( |
+ '/a.dart', |
+ ''' |
+library a; |
+import 'b.dart'; |
+class A extends B {} |
+'''); |
+ newSource( |
+ '/b.dart', |
+ ''' |
+library b; |
+class B {} |
+'''); |
+ // The reference A to B should be resolved, but there's no requirement that |
+ // the full class hierarchy be resolved. |
+ computeResult(sourceA, LIBRARY_ELEMENT5, |
+ matcher: isResolveLibraryTypeNamesTask); |
+ // validate |
+ LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
+ { |
+ ClassElement clazz = library.getType('A'); |
+ expect(clazz.displayName, 'A'); |
+ clazz = clazz.supertype.element; |
+ expect(clazz.displayName, 'B'); |
+ } |
+ } |
+} |
+ |
+@reflectiveTest |
+class ResolveUnitTaskTest extends _AbstractDartTaskTest { |
+ void test_perform() { |
+ AnalysisTarget source = newSource( |
+ '/test.dart', |
+ ''' |
+void f() { |
+ var c = new C(); |
+ c.m(); |
+} |
+class C { |
+ void m() { |
+ f(); |
+ } |
+} |
+'''); |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9, |
+ matcher: isResolveUnitTask); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
+ |
+ FunctionDeclaration f = unit.declarations[0]; |
+ _assertResolved(f.functionExpression.body); |
+ |
+ MethodDeclaration m = (unit.declarations[1] as ClassDeclaration).members[0]; |
+ _assertResolved(m.body); |
+ |
+ expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0)); |
+ } |
+ |
+ void _assertResolved(FunctionBody body) { |
+ ResolutionVerifier verifier = new ResolutionVerifier(); |
+ body.accept(verifier); |
+ verifier.assertResolved(); |
+ } |
+} |
+ |
+@reflectiveTest |
+class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest { |
+ test_perform() { |
+ Source source = newSource( |
+ '/test.dart', |
+ ''' |
+class A {} |
+class B extends A {} |
+int f(String p) => p.length; |
+'''); |
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
+ computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask); |
+ // validate |
+ CompilationUnit unit = outputs[RESOLVED_UNIT3]; |
+ { |
+ ClassDeclaration nodeA = unit.declarations[0]; |
+ ClassDeclaration nodeB = unit.declarations[1]; |
+ DartType extendsType = nodeB.extendsClause.superclass.type; |
+ expect(extendsType, nodeA.element.type); |
+ } |
+ { |
+ FunctionDeclaration functionNode = unit.declarations[2]; |
+ DartType returnType = functionNode.returnType.type; |
+ List<FormalParameter> parameters = |
+ functionNode.functionExpression.parameters.parameters; |
+ expect(returnType.displayName, 'int'); |
+ expect(parameters[0].element.type.displayName, 'String'); |
+ } |
+ } |
+ |
+ test_perform_errors() { |
Source source = newSource( |
'/test.dart', |
''' |
@@ -2934,128 +3442,14 @@ class ScanDartTaskTest extends _AbstractDartTaskTest { |
@reflectiveTest |
class StrongModeInferenceTest extends _AbstractDartTaskTest { |
- void assertAssignmentStatementTypes( |
- Statement stmt, DartType leftType, DartType rightType) { |
- AssignmentExpression assgn = (stmt as ExpressionStatement).expression; |
- expect(assgn.leftHandSide.staticType, leftType); |
- expect(assgn.rightHandSide.staticType, rightType); |
- } |
- |
- // Check that even within a static variable cycle, inferred |
- // types get propagated to the members of the cycle. |
- void assertVariableDeclarationStatementTypes( |
- Statement stmt, DartType varType, DartType initializerType) { |
- VariableDeclaration decl = |
- (stmt as VariableDeclarationStatement).variables.variables[0]; |
- assertVariableDeclarationTypes(decl, varType, initializerType); |
- } |
- |
- void assertVariableDeclarationTypes( |
- VariableDeclaration decl, DartType varType, DartType initializerType) { |
- expect(decl.element.type, varType); |
- expect(decl.initializer.staticType, initializerType); |
- } |
- |
- 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); |
- } |
- |
- 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); |
- } |
- |
@override |
void setUp() { |
super.setUp(); |
enableStrongMode(); |
} |
- // Test that local variables in method bodies are inferred appropriately |
+ // 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', |
@@ -3064,8 +3458,8 @@ 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]; |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
VariableElement piFirst = |
getTopLevelVariable(unit, 'piFirst').name.staticElement; |
VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement; |
@@ -3079,109 +3473,34 @@ var tau = piFirst ? pi * 2 : 6.28; |
expect(tau.type.isDynamic, isTrue); |
} |
- // Test inference interactions between local variables and fields |
- 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; |
- |
- 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 interactions between local variables and top level |
- // variables |
- 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( |
+ void test_perform_local_explicit_disabled() { |
+ AnalysisTarget source = 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"; |
- } |
+ test() { |
+ int x = 3; |
+ x = "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]; |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
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"); |
+ 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); |
- assertAssignmentStatementTypes(statements[0], intType, stringType); |
- assertAssignmentStatementTypes(statements[1], intType, stringType); |
+ ExpressionStatement statement = statements[1]; |
+ AssignmentExpression assgn = statement.expression; |
+ expect(assgn.leftHandSide.staticType, intType); |
+ expect(assgn.rightHandSide.staticType, stringType); |
} |
- // Test that inference does not propagate from null |
+ // Test that local variables in method bodies are inferred appropriately |
void test_perform_inference_local_variables() { |
AnalysisTarget source = newSource( |
'/test.dart', |
@@ -3192,9 +3511,9 @@ var tau = piFirst ? pi * 2 : 6.28; |
var y = 3; |
y = "hi"; |
} |
-'''); |
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8); |
- CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
+'''); |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
InterfaceType intType = context.typeProvider.intType; |
InterfaceType stringType = context.typeProvider.stringType; |
@@ -3207,7 +3526,7 @@ var tau = piFirst ? pi * 2 : 6.28; |
assertAssignmentStatementTypes(statements[3], intType, stringType); |
} |
- // Test inference across units (non-cyclic) |
+ // Test inference interactions between local variables and fields |
void test_perform_inference_local_variables_fields() { |
AnalysisTarget source = newSource( |
'/test.dart', |
@@ -3231,8 +3550,8 @@ var tau = piFirst ? pi * 2 : 6.28; |
final z = 42; // should infer `int` |
} |
'''); |
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8); |
- CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
InterfaceType intType = context.typeProvider.intType; |
InterfaceType stringType = context.typeProvider.stringType; |
@@ -3257,7 +3576,8 @@ var tau = piFirst ? pi * 2 : 6.28; |
getFieldInClass(unit, "A", "z"), intType, intType); |
} |
- // Test inference across units (cyclic) |
+ // Test inference interactions between local variables and top level |
+ // variables |
void test_perform_inference_local_variables_topLevel() { |
AnalysisTarget source = newSource( |
'/test.dart', |
@@ -3279,8 +3599,8 @@ var tau = piFirst ? pi * 2 : 6.28; |
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]; |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
InterfaceType intType = context.typeProvider.intType; |
InterfaceType stringType = context.typeProvider.stringType; |
@@ -3307,9 +3627,7 @@ var tau = piFirst ? pi * 2 : 6.28; |
getTopLevelVariable(unit, "z"), intType, intType); |
} |
- // Test inference of instance fields across units |
- // TODO(leafp): Fix this |
- // https://github.com/dart-lang/dev_compiler/issues/354 |
+ // Test that inference does not propagate from null |
void test_perform_inference_null() { |
AnalysisTarget source = newSource( |
'/test.dart', |
@@ -3333,8 +3651,8 @@ var tau = piFirst ? pi * 2 : 6.28; |
new A().y2 = /*severe:StaticTypeError*/"hi"; |
} |
'''); |
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8); |
- CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
+ CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
InterfaceType intType = context.typeProvider.intType; |
InterfaceType stringType = context.typeProvider.stringType; |
@@ -3364,34 +3682,242 @@ var tau = piFirst ? pi * 2 : 6.28; |
assertAssignmentStatementTypes(statements[5], intType, stringType); |
} |
- // Test inference between static and instance fields |
- // TODO(leafp): Fix this |
- // https://github.com/dart-lang/dev_compiler/issues/354 |
- void test_perform_local_explicit_disabled() { |
- AnalysisTarget source = newSource( |
+ // 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', |
''' |
- test() { |
- int x = 3; |
- x = "hi"; |
- } |
+ 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(source, source), RESOLVED_UNIT8); |
- CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
+ computeResult( |
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9); |
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT9]; |
+ computeResult( |
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9); |
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT9]; |
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); |
+ assertVariableDeclarationTypes( |
+ getTopLevelVariable(unit1, "x"), intType, intType); |
+ assertVariableDeclarationTypes( |
+ getFieldInClass(unit1, "A", "x"), intType, intType); |
- ExpressionStatement statement = statements[1]; |
- AssignmentExpression assgn = statement.expression; |
- expect(assgn.leftHandSide.staticType, intType); |
- expect(assgn.rightHandSide.staticType, stringType); |
+ 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_UNIT9); |
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT9]; |
+ computeResult( |
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9); |
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT9]; |
+ |
+ InterfaceType intType = context.typeProvider.intType; |
+ |
+ 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 |
+ void test_perform_inference_cross_unit_instance() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+ class A { |
+ final a2 = new B().b2; |
+ } |
+ ''', |
+ '/b.dart': ''' |
+ class B { |
+ final b2 = 1; |
+ } |
+ ''', |
+ '/main.dart': ''' |
+ import "a.dart"; |
+ |
+ test1() { |
+ int x = 0; |
+ x = new A().a2; |
+ } |
+ ''' |
+ }); |
+ List<dynamic> units = |
+ computeLibraryResults(sources, RESOLVED_UNIT9).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 |
+ void test_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_UNIT9).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); |
+ } |
+ |
+ // Test inference between fields and method bodies |
+ void test_perform_inference_cross_unit_instance_member() { |
+ List<Source> sources = newSources({ |
+ '/a.dart': ''' |
+ import 'b.dart'; |
+ var bar = new B(); |
+ void foo() { |
+ String x = bar.f.z; |
+ } |
+ ''', |
+ '/b.dart': ''' |
+ class C { |
+ var z = 3; |
+ } |
+ |
+ class B { |
+ var f = new C(); |
+ } |
+ ''', |
+ '/c.dart': ''' |
+ import 'b.dart'; |
+ var bar = new B(); |
+ void foo() { |
+ String x = bar.f.z; |
+ } |
+ ''' |
+ }); |
+ List<dynamic> units = |
+ computeLibraryResults(sources, RESOLVED_UNIT9).toList(); |
+ CompilationUnit unit0 = units[0]; |
+ CompilationUnit unit1 = units[1]; |
+ CompilationUnit unit2 = units[2]; |
+ |
+ InterfaceType intType = context.typeProvider.intType; |
+ InterfaceType stringType = context.typeProvider.stringType; |
+ |
+ assertVariableDeclarationStatementTypes( |
+ getStatementsInTopLevelFunction(unit0, "foo")[0], stringType, intType); |
+ assertVariableDeclarationStatementTypes( |
+ getStatementsInTopLevelFunction(unit2, "foo")[0], stringType, intType); |
} |
} |
@@ -3469,6 +3995,13 @@ class _AbstractDartTaskTest extends AbstractContextTest { |
GatheringErrorListener errorListener = new GatheringErrorListener(); |
+ void assertAssignmentStatementTypes( |
+ Statement stmt, DartType leftType, DartType rightType) { |
+ AssignmentExpression assgn = (stmt as ExpressionStatement).expression; |
+ expect(assgn.leftHandSide.staticType, leftType); |
+ expect(assgn.rightHandSide.staticType, rightType); |
+ } |
+ |
void assertIsInvalid(AnalysisTarget target, ResultDescriptor descriptor) { |
CacheEntry entry = context.getCacheEntry(target); |
expect(entry.isInvalid(descriptor), isTrue); |
@@ -3487,6 +4020,19 @@ class _AbstractDartTaskTest extends AbstractContextTest { |
}); |
} |
+ 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); |
+ } |
+ |
List<dynamic> computeLibraryResults( |
List<Source> sources, ResultDescriptor result, |
{isInstanceOf matcher: null}) { |
@@ -3498,6 +4044,17 @@ class _AbstractDartTaskTest extends AbstractContextTest { |
return sources.map(compute).toList(); |
} |
+ List<Map<ResultDescriptor, dynamic>> computeLibraryResultsMap( |
+ List<Source> sources, ResultDescriptor result, |
+ {isInstanceOf matcher: null}) { |
+ Map<ResultDescriptor, dynamic> compute(Source source) { |
+ computeResult(new LibrarySpecificUnit(source, source), result, |
+ matcher: matcher); |
+ return outputs; |
+ } |
+ return sources.map(compute).toList(); |
+ } |
+ |
/** |
* Create a script object with a single fragment containing the given |
* [scriptContent]. |