| 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 b22902c58c8ffe89c28803b760cfa0cd38837ea0..1c94faf5499ec7b3dd27fc87e62a9d4548518cfd 100644
|
| --- a/pkg/analyzer/test/src/task/dart_test.dart
|
| +++ b/pkg/analyzer/test/src/task/dart_test.dart
|
| @@ -15,6 +15,7 @@ import 'package:analyzer/src/generated/resolver.dart';
|
| import 'package:analyzer/src/generated/scanner.dart';
|
| import 'package:analyzer/src/generated/sdk.dart';
|
| import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/services/lint.dart';
|
| import 'package:analyzer/src/task/dart.dart';
|
| import 'package:analyzer/src/task/html.dart';
|
| import 'package:analyzer/task/dart.dart';
|
| @@ -48,6 +49,7 @@ main() {
|
| runReflectiveTests(GatherUsedImportedElementsTaskTest);
|
| runReflectiveTests(GatherUsedLocalElementsTaskTest);
|
| runReflectiveTests(GenerateHintsTaskTest);
|
| + runReflectiveTests(GenerateLintsTaskTest);
|
| runReflectiveTests(InferInstanceMembersInUnitTaskTest);
|
| runReflectiveTests(InferStaticVariableTypesInUnitTaskTest);
|
| runReflectiveTests(InferStaticVariableTypeTaskTest);
|
| @@ -98,6 +100,7 @@ isInstanceOf isGatherUsedImportedElementsTask =
|
| isInstanceOf isGatherUsedLocalElementsTask =
|
| new isInstanceOf<GatherUsedLocalElementsTask>();
|
| isInstanceOf isGenerateHintsTask = new isInstanceOf<GenerateHintsTask>();
|
| +isInstanceOf isGenerateLintsTask = new isInstanceOf<GenerateLintsTask>();
|
| isInstanceOf isInferInstanceMembersInUnitTask =
|
| new isInstanceOf<InferInstanceMembersInUnitTask>();
|
| isInstanceOf isInferStaticVariableTypesInUnitTask =
|
| @@ -122,6 +125,8 @@ isInstanceOf isResolveVariableReferencesTask =
|
| isInstanceOf isScanDartTask = new isInstanceOf<ScanDartTask>();
|
| isInstanceOf isVerifyUnitTask = new isInstanceOf<VerifyUnitTask>();
|
|
|
| +final LintCode _testLintCode = new LintCode('test lint', 'test lint code');
|
| +
|
| @reflectiveTest
|
| class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest {
|
| Source source;
|
| @@ -1876,6 +1881,62 @@ f(A a) {
|
| }
|
|
|
| @reflectiveTest
|
| +class GenerateLintsTaskTest extends _AbstractDartTaskTest {
|
| + void enableLints() {
|
| + AnalysisOptionsImpl options = context.analysisOptions;
|
| + options.lint = true;
|
| + context.analysisOptions = options;
|
| + }
|
| +
|
| + @override
|
| + void setUp() {
|
| + super.setUp();
|
| + enableLints();
|
| + }
|
| +
|
| + @override
|
| + void tearDown() {
|
| + LintGenerator.LINTERS.clear();
|
| + super.tearDown();
|
| + }
|
| +
|
| + test_camel_case_types() {
|
| + Source source = newSource(
|
| + '/test.dart',
|
| + '''
|
| +class a { }
|
| +''');
|
| +
|
| + LintGenerator.LINTERS.clear();
|
| + LintGenerator.LINTERS.add(new GenerateLintsTaskTest_TestLinter());
|
| +
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, LINTS, matcher: isGenerateLintsTask);
|
| + // validate
|
| + _fillErrorListener(LINTS);
|
| + errorListener.assertErrorsWithCodes(<ErrorCode>[_testLintCode]);
|
| + }
|
| +}
|
| +
|
| +class GenerateLintsTaskTest_AstVisitor extends SimpleAstVisitor {
|
| + Linter linter;
|
| + GenerateLintsTaskTest_AstVisitor(this.linter);
|
| +
|
| + @override
|
| + visitClassDeclaration(ClassDeclaration node) {
|
| + if (!new RegExp(r'^([_]*)([A-Z]+[a-z0-9]*)+$')
|
| + .hasMatch(node.name.toString())) {
|
| + linter.reporter.reportErrorForNode(_testLintCode, node, []);
|
| + }
|
| + }
|
| +}
|
| +
|
| +class GenerateLintsTaskTest_TestLinter extends Linter {
|
| + @override
|
| + AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this);
|
| +}
|
| +
|
| +@reflectiveTest
|
| class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest {
|
| void test_perform() {
|
| enableStrongMode();
|
| @@ -1973,6 +2034,23 @@ class C {
|
|
|
| @reflectiveTest
|
| class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
|
| + 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);
|
| + }
|
| +
|
| void test_perform_nestedDeclarations() {
|
| enableStrongMode();
|
| AnalysisTarget source = newSource(
|
| @@ -2050,23 +2128,6 @@ 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
|
| @@ -2128,31 +2189,6 @@ class C {
|
| 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));
|
| - }
|
| -
|
| void test_perform_const() {
|
| AnalysisTarget source = newSource(
|
| '/test.dart',
|
| @@ -2231,6 +2267,31 @@ var a = null;
|
| 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));
|
| + }
|
| }
|
|
|
| @reflectiveTest
|
| @@ -2594,372 +2655,307 @@ class C {
|
| }
|
|
|
| @reflectiveTest
|
| -class StrongModeInferenceTest extends _AbstractDartTaskTest {
|
| +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');
|
| + }
|
| + }
|
|
|
| - @override
|
| - void setUp() {
|
| - super.setUp();
|
| - enableStrongMode();
|
| + 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');
|
| + }
|
| }
|
| +}
|
|
|
| - // 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(
|
| +@reflectiveTest
|
| +class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest {
|
| + test_perform() {
|
| + Source source = newSource(
|
| '/test.dart',
|
| '''
|
| -var piFirst = true;
|
| -var pi = piFirst ? 3.14 : tau / 2;
|
| -var tau = piFirst ? pi * 2 : 6.28;
|
| +class A {}
|
| +class B extends A {}
|
| +int f(String p) => p.length;
|
| ''');
|
| - 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);
|
| + 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');
|
| + }
|
| }
|
|
|
| - void test_perform_local_explicit_disabled() {
|
| - AnalysisTarget source = newSource(
|
| + test_perform_errors() {
|
| + Source source = newSource(
|
| '/test.dart',
|
| '''
|
| - test() {
|
| - int x = 3;
|
| - x = "hi";
|
| - }
|
| +NoSuchClass f() => null;
|
| ''');
|
| - 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);
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
|
| + matcher: isResolveUnitTypeNamesTask);
|
| + // validate
|
| + _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
|
| + errorListener
|
| + .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
|
| }
|
|
|
| - 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_perform_typedef() {
|
| + Source source = newSource(
|
| '/test.dart',
|
| '''
|
| - test() {
|
| - int x = 3;
|
| - x = "hi";
|
| - var y = 3;
|
| - y = "hi";
|
| - }
|
| +typedef int F(G g);
|
| +typedef String G(int p);
|
| ''');
|
| - 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);
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask);
|
| + // validate
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT3];
|
| + FunctionTypeAlias nodeF = unit.declarations[0];
|
| + FunctionTypeAlias nodeG = unit.declarations[1];
|
| + {
|
| + FormalParameter parameter = nodeF.parameters.parameters[0];
|
| + DartType parameterType = parameter.element.type;
|
| + Element returnTypeElement = nodeF.returnType.type.element;
|
| + expect(returnTypeElement.displayName, 'int');
|
| + expect(parameterType.element, nodeG.element);
|
| + }
|
| + {
|
| + FormalParameter parameter = nodeG.parameters.parameters[0];
|
| + DartType parameterType = parameter.element.type;
|
| + expect(nodeG.returnType.type.element.displayName, 'String');
|
| + expect(parameterType.element.displayName, 'int');
|
| + }
|
| }
|
|
|
| - // Test inference interactions between local variables and fields
|
| - void test_perform_inference_local_variables_fields() {
|
| - AnalysisTarget source = newSource(
|
| + test_perform_typedef_errors() {
|
| + Source 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`
|
| - }
|
| +typedef int F(NoSuchType p);
|
| ''');
|
| - 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);
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
|
| + matcher: isResolveUnitTypeNamesTask);
|
| + // validate
|
| + _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
|
| + errorListener
|
| + .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
|
| + }
|
| +}
|
|
|
| - assertVariableDeclarationTypes(
|
| - getFieldInClass(unit, "A", "x"), intType, intType);
|
| - assertVariableDeclarationTypes(
|
| - getFieldInClass(unit, "A", "z"), intType, intType);
|
| +@reflectiveTest
|
| +class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest {
|
| + /**
|
| + * Verify that the mutated states of the given [variable] correspond to the
|
| + * [mutatedInClosure] and [mutatedInScope] matchers.
|
| + */
|
| + void expectMutated(VariableElement variable, Matcher mutatedInClosure,
|
| + Matcher mutatedInScope) {
|
| + expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure);
|
| + expect(variable.isPotentiallyMutatedInScope, mutatedInScope);
|
| }
|
|
|
| - // Test inference interactions between local variables and top level
|
| - // variables
|
| - void test_perform_inference_local_variables_topLevel() {
|
| - AnalysisTarget source = newSource(
|
| + test_perform_buildClosureLibraryElements() {
|
| + Source 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`
|
| +main() {
|
| +}
|
| ''');
|
| - 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);
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, RESOLVED_UNIT4,
|
| + matcher: isResolveVariableReferencesTask);
|
| }
|
|
|
| - // Test that inference does not propagate from null
|
| - void test_perform_inference_null() {
|
| - AnalysisTarget source = newSource(
|
| + test_perform_local() {
|
| + Source 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";
|
| - }
|
| +main() {
|
| + var v1 = 1;
|
| + var v2 = 1;
|
| + var v3 = 1;
|
| + var v4 = 1;
|
| + v2 = 2;
|
| + v4 = 2;
|
| + localFunction() {
|
| + v3 = 3;
|
| + v4 = 3;
|
| + }
|
| +}
|
| ''');
|
| - 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);
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, RESOLVED_UNIT4,
|
| + matcher: isResolveVariableReferencesTask);
|
| + // validate
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT4];
|
| + FunctionElement main = unit.element.functions[0];
|
| + expectMutated(main.localVariables[0], isFalse, isFalse);
|
| + expectMutated(main.localVariables[1], isFalse, isTrue);
|
| + expectMutated(main.localVariables[2], isTrue, isTrue);
|
| + expectMutated(main.localVariables[3], isTrue, isTrue);
|
| }
|
|
|
| - // 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_perform_parameter() {
|
| + Source 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";
|
| - }
|
| -''');
|
| - 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");
|
| +main(p1, p2, p3, p4) {
|
| + p2 = 2;
|
| + p4 = 2;
|
| + localFunction() {
|
| + p3 = 3;
|
| + p4 = 3;
|
| + }
|
| +}
|
| +''');
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, RESOLVED_UNIT4,
|
| + matcher: isResolveVariableReferencesTask);
|
| + // validate
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT4];
|
| + FunctionElement main = unit.element.functions[0];
|
| + expectMutated(main.parameters[0], isFalse, isFalse);
|
| + expectMutated(main.parameters[1], isFalse, isTrue);
|
| + expectMutated(main.parameters[2], isTrue, isTrue);
|
| + expectMutated(main.parameters[3], isTrue, isTrue);
|
| + }
|
| +}
|
|
|
| - assertAssignmentStatementTypes(statements[0], intType, stringType);
|
| - assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| +@reflectiveTest
|
| +class ScanDartTaskTest extends _AbstractDartTaskTest {
|
| + test_perform_errors() {
|
| + _performScanTask('import "');
|
| + expect(outputs, hasLength(3));
|
| + expect(outputs[LINE_INFO], isNotNull);
|
| + expect(outputs[SCAN_ERRORS], hasLength(1));
|
| + expect(outputs[TOKEN_STREAM], isNotNull);
|
| }
|
|
|
| - // 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; }
|
| + test_perform_noErrors() {
|
| + _performScanTask('class A {}');
|
| + expect(outputs, hasLength(3));
|
| + expect(outputs[LINE_INFO], isNotNull);
|
| + expect(outputs[SCAN_ERRORS], hasLength(0));
|
| + expect(outputs[TOKEN_STREAM], isNotNull);
|
| + }
|
|
|
| - 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];
|
| + test_perform_script() {
|
| + String scriptContent = '''
|
| + void buttonPressed() {
|
| + ''';
|
| + String htmlContent = '''
|
| +<!DOCTYPE html>
|
| +<html>
|
| + <head>
|
| + <title>test page</title>
|
| + <script type='application/dart'>$scriptContent</script>
|
| + </head>
|
| + <body>Test</body>
|
| +</html>
|
| +''';
|
| + Source source = newSource('/test.html', htmlContent);
|
| + DartScript script =
|
| + new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]);
|
|
|
| - InterfaceType intType = context.typeProvider.intType;
|
| + computeResult(script, TOKEN_STREAM, matcher: isScanDartTask);
|
| + expect(outputs[LINE_INFO], isNotNull);
|
| + expect(outputs[SCAN_ERRORS], isEmpty);
|
| + Token tokenStream = outputs[TOKEN_STREAM];
|
| + expect(tokenStream, isNotNull);
|
| + expect(tokenStream.lexeme, 'void');
|
| + }
|
|
|
| - assertVariableDeclarationTypes(
|
| - getTopLevelVariable(unit1, "x"), intType, intType);
|
| - assertVariableDeclarationTypes(
|
| - getFieldInClass(unit1, "A", "x"), intType, intType);
|
| + void _performScanTask(String content) {
|
| + AnalysisTarget target = newSource('/test.dart', content);
|
| + computeResult(target, TOKEN_STREAM, matcher: isScanDartTask);
|
| + }
|
| +}
|
|
|
| - assertVariableDeclarationTypes(
|
| - getTopLevelVariable(unit2, "y"), intType, intType);
|
| - assertVariableDeclarationTypes(
|
| - getFieldInClass(unit2, "B", "y"), intType, intType);
|
| +@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);
|
| + }
|
|
|
| - List<Statement> statements =
|
| - getStatementsInTopLevelFunction(unit2, "test1");
|
| + // 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);
|
| + }
|
|
|
| - assertAssignmentStatementTypes(statements[1], intType, intType);
|
| - assertAssignmentStatementTypes(statements[2], intType, intType);
|
| - assertAssignmentStatementTypes(statements[3], intType, intType);
|
| - assertAssignmentStatementTypes(statements[4], intType, intType);
|
| + void assertVariableDeclarationTypes(
|
| + VariableDeclaration decl, DartType varType, DartType initializerType) {
|
| + expect(decl.element.type, varType);
|
| + expect(decl.initializer.staticType, initializerType);
|
| }
|
|
|
| - // 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': '''
|
| @@ -3002,9 +2998,6 @@ var tau = piFirst ? pi * 2 : 6.28;
|
| 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': '''
|
| @@ -3040,298 +3033,365 @@ var tau = piFirst ? pi * 2 : 6.28;
|
| InterfaceType intType = context.typeProvider.intType;
|
|
|
| assertVariableDeclarationTypes(
|
| - getFieldInClass(unit0, "A", "a1"), intType, intType);
|
| + 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
|
| + 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);
|
| + }
|
| +
|
| + // 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(
|
| + '/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;
|
| +
|
| + assertVariableDeclarationTypes(
|
| + getTopLevelVariable(unit1, "x"), intType, intType);
|
| assertVariableDeclarationTypes(
|
| - getFieldInClass(unit0, "A", "a2"), intType, intType);
|
| + getFieldInClass(unit1, "A", "x"), intType, intType);
|
|
|
| assertVariableDeclarationTypes(
|
| - getFieldInClass(unit1, "B", "b1"), intType, intType);
|
| + getTopLevelVariable(unit2, "y"), intType, intType);
|
| assertVariableDeclarationTypes(
|
| - getFieldInClass(unit1, "B", "b2"), intType, intType);
|
| + getFieldInClass(unit2, "B", "y"), intType, intType);
|
|
|
| List<Statement> statements =
|
| getStatementsInTopLevelFunction(unit2, "test1");
|
|
|
| - assertAssignmentStatementTypes(statements[1], intType, intType);
|
| - assertAssignmentStatementTypes(statements[2], intType, intType);
|
| + assertAssignmentStatementTypes(statements[0], intType, stringType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| }
|
| -}
|
|
|
| -@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',
|
| + // Test that inference does not propagate from null
|
| + void test_perform_inference_local_variables() {
|
| + AnalysisTarget source = newSource(
|
| + '/test.dart',
|
| '''
|
| -part of my_lib;
|
| -class C extends A {}
|
| + test() {
|
| + int x = 3;
|
| + x = "hi";
|
| + var y = 3;
|
| + y = "hi";
|
| + }
|
| ''');
|
| - 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');
|
| - }
|
| - }
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
|
|
| - 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');
|
| - }
|
| - }
|
| -}
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
|
|
| -@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');
|
| - }
|
| - }
|
| + List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
|
|
|
| - test_perform_errors() {
|
| - Source source = newSource(
|
| - '/test.dart',
|
| - '''
|
| -NoSuchClass f() => null;
|
| -''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
|
| - matcher: isResolveUnitTypeNamesTask);
|
| - // validate
|
| - _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
|
| - errorListener
|
| - .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
|
| + assertVariableDeclarationStatementTypes(statements[0], intType, intType);
|
| + assertAssignmentStatementTypes(statements[1], intType, stringType);
|
| + assertVariableDeclarationStatementTypes(statements[2], intType, intType);
|
| + assertAssignmentStatementTypes(statements[3], intType, stringType);
|
| }
|
|
|
| - test_perform_typedef() {
|
| - Source source = newSource(
|
| + // Test inference across units (non-cyclic)
|
| + void test_perform_inference_local_variables_fields() {
|
| + AnalysisTarget source = newSource(
|
| '/test.dart',
|
| '''
|
| -typedef int F(G g);
|
| -typedef String G(int p);
|
| + 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`
|
| + }
|
| ''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask);
|
| - // validate
|
| - CompilationUnit unit = outputs[RESOLVED_UNIT3];
|
| - FunctionTypeAlias nodeF = unit.declarations[0];
|
| - FunctionTypeAlias nodeG = unit.declarations[1];
|
| - {
|
| - FormalParameter parameter = nodeF.parameters.parameters[0];
|
| - DartType parameterType = parameter.element.type;
|
| - Element returnTypeElement = nodeF.returnType.type.element;
|
| - expect(returnTypeElement.displayName, 'int');
|
| - expect(parameterType.element, nodeG.element);
|
| - }
|
| - {
|
| - FormalParameter parameter = nodeG.parameters.parameters[0];
|
| - DartType parameterType = parameter.element.type;
|
| - expect(nodeG.returnType.type.element.displayName, 'String');
|
| - expect(parameterType.element.displayName, '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_perform_typedef_errors() {
|
| - Source source = newSource(
|
| + // Test inference across units (cyclic)
|
| + void test_perform_inference_local_variables_topLevel() {
|
| + AnalysisTarget source = newSource(
|
| '/test.dart',
|
| '''
|
| -typedef int F(NoSuchType p);
|
| + 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`
|
| ''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
|
| - matcher: isResolveUnitTypeNamesTask);
|
| - // validate
|
| - _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
|
| - errorListener
|
| - .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
|
| - }
|
| -}
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
|
|
| -@reflectiveTest
|
| -class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest {
|
| - /**
|
| - * Verify that the mutated states of the given [variable] correspond to the
|
| - * [mutatedInClosure] and [mutatedInScope] matchers.
|
| - */
|
| - void expectMutated(VariableElement variable, Matcher mutatedInClosure,
|
| - Matcher mutatedInScope) {
|
| - expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure);
|
| - expect(variable.isPotentiallyMutatedInScope, mutatedInScope);
|
| - }
|
| + 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);
|
|
|
| - test_perform_buildClosureLibraryElements() {
|
| - Source source = newSource(
|
| - '/test.dart',
|
| - '''
|
| -main() {
|
| -}
|
| -''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, RESOLVED_UNIT4,
|
| - matcher: isResolveVariableReferencesTask);
|
| + 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_perform_local() {
|
| - Source source = newSource(
|
| + // Test inference of instance fields across units
|
| + // TODO(leafp): Fix this
|
| + // https://github.com/dart-lang/dev_compiler/issues/354
|
| + void test_perform_inference_null() {
|
| + AnalysisTarget source = newSource(
|
| '/test.dart',
|
| '''
|
| -main() {
|
| - var v1 = 1;
|
| - var v2 = 1;
|
| - var v3 = 1;
|
| - var v4 = 1;
|
| - v2 = 2;
|
| - v4 = 2;
|
| - localFunction() {
|
| - v3 = 3;
|
| - v4 = 3;
|
| - }
|
| -}
|
| + 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";
|
| + }
|
| ''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, RESOLVED_UNIT4,
|
| - matcher: isResolveVariableReferencesTask);
|
| - // validate
|
| - CompilationUnit unit = outputs[RESOLVED_UNIT4];
|
| - FunctionElement main = unit.element.functions[0];
|
| - expectMutated(main.localVariables[0], isFalse, isFalse);
|
| - expectMutated(main.localVariables[1], isFalse, isTrue);
|
| - expectMutated(main.localVariables[2], isTrue, isTrue);
|
| - expectMutated(main.localVariables[3], isTrue, isTrue);
|
| + 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_perform_parameter() {
|
| - Source source = newSource(
|
| + // 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.dart',
|
| '''
|
| -main(p1, p2, p3, p4) {
|
| - p2 = 2;
|
| - p4 = 2;
|
| - localFunction() {
|
| - p3 = 3;
|
| - p4 = 3;
|
| - }
|
| -}
|
| + test() {
|
| + int x = 3;
|
| + x = "hi";
|
| + }
|
| ''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, RESOLVED_UNIT4,
|
| - matcher: isResolveVariableReferencesTask);
|
| - // validate
|
| - CompilationUnit unit = outputs[RESOLVED_UNIT4];
|
| - FunctionElement main = unit.element.functions[0];
|
| - expectMutated(main.parameters[0], isFalse, isFalse);
|
| - expectMutated(main.parameters[1], isFalse, isTrue);
|
| - expectMutated(main.parameters[2], isTrue, isTrue);
|
| - expectMutated(main.parameters[3], isTrue, isTrue);
|
| - }
|
| -}
|
| -
|
| -@reflectiveTest
|
| -class ScanDartTaskTest extends _AbstractDartTaskTest {
|
| - test_perform_errors() {
|
| - _performScanTask('import "');
|
| - expect(outputs, hasLength(3));
|
| - expect(outputs[LINE_INFO], isNotNull);
|
| - expect(outputs[SCAN_ERRORS], hasLength(1));
|
| - expect(outputs[TOKEN_STREAM], isNotNull);
|
| - }
|
| -
|
| - test_perform_noErrors() {
|
| - _performScanTask('class A {}');
|
| - expect(outputs, hasLength(3));
|
| - expect(outputs[LINE_INFO], isNotNull);
|
| - expect(outputs[SCAN_ERRORS], hasLength(0));
|
| - expect(outputs[TOKEN_STREAM], isNotNull);
|
| - }
|
| + computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
|
| + CompilationUnit unit = outputs[RESOLVED_UNIT8];
|
|
|
| - test_perform_script() {
|
| - String scriptContent = '''
|
| - void buttonPressed() {
|
| - ''';
|
| - String htmlContent = '''
|
| -<!DOCTYPE html>
|
| -<html>
|
| - <head>
|
| - <title>test page</title>
|
| - <script type='application/dart'>$scriptContent</script>
|
| - </head>
|
| - <body>Test</body>
|
| -</html>
|
| -''';
|
| - Source source = newSource('/test.html', htmlContent);
|
| - DartScript script =
|
| - new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]);
|
| + InterfaceType intType = context.typeProvider.intType;
|
| + InterfaceType stringType = context.typeProvider.stringType;
|
|
|
| - computeResult(script, TOKEN_STREAM, matcher: isScanDartTask);
|
| - expect(outputs[LINE_INFO], isNotNull);
|
| - expect(outputs[SCAN_ERRORS], isEmpty);
|
| - Token tokenStream = outputs[TOKEN_STREAM];
|
| - expect(tokenStream, isNotNull);
|
| - expect(tokenStream.lexeme, 'void');
|
| - }
|
| + 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);
|
|
|
| - void _performScanTask(String content) {
|
| - AnalysisTarget target = newSource('/test.dart', content);
|
| - computeResult(target, TOKEN_STREAM, matcher: isScanDartTask);
|
| + ExpressionStatement statement = statements[1];
|
| + AssignmentExpression assgn = statement.expression;
|
| + expect(assgn.leftHandSide.staticType, intType);
|
| + expect(assgn.rightHandSide.staticType, stringType);
|
| }
|
| }
|
|
|
| @@ -3368,39 +3428,39 @@ import 'no-such-file.dart';
|
| <ErrorCode>[CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
|
| }
|
|
|
| - test_perform_verifyError() {
|
| - Source source = newSource(
|
| + void test_perform_reresolution() {
|
| + enableStrongMode();
|
| + AnalysisTarget source = newSource(
|
| '/test.dart',
|
| '''
|
| -main() {
|
| - if (42) {
|
| - print('Not bool!');
|
| - }
|
| +const topLevel = 3;
|
| +class C {
|
| + String field = topLevel;
|
| }
|
| ''');
|
| - LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| - computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
|
| + computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS);
|
| // validate
|
| _fillErrorListener(VERIFY_ERRORS);
|
| errorListener.assertErrorsWithCodes(
|
| - <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]);
|
| + <ErrorCode>[StaticTypeWarningCode.INVALID_ASSIGNMENT]);
|
| }
|
|
|
| - void test_perform_reresolution() {
|
| - enableStrongMode();
|
| - AnalysisTarget source = newSource(
|
| + test_perform_verifyError() {
|
| + Source source = newSource(
|
| '/test.dart',
|
| '''
|
| -const topLevel = 3;
|
| -class C {
|
| - String field = topLevel;
|
| +main() {
|
| + if (42) {
|
| + print('Not bool!');
|
| + }
|
| }
|
| ''');
|
| - computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS);
|
| + LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
|
| + computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
|
| // validate
|
| _fillErrorListener(VERIFY_ERRORS);
|
| errorListener.assertErrorsWithCodes(
|
| - <ErrorCode>[StaticTypeWarningCode.INVALID_ASSIGNMENT]);
|
| + <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]);
|
| }
|
| }
|
|
|
| @@ -3538,6 +3598,23 @@ class _AbstractDartTaskTest extends AbstractContextTest {
|
| }
|
|
|
| /**
|
| + * 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;
|
| + }
|
| +
|
| + /**
|
| * Return the declaration of the top-level variable with the given
|
| * [variableName] in the given compilation [unit].
|
| */
|
| @@ -3558,23 +3635,6 @@ 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');
|
|
|