| Index: packages/analyzer/test/src/task/strong_mode_test.dart
|
| diff --git a/packages/analyzer/test/src/task/strong_mode_test.dart b/packages/analyzer/test/src/task/strong_mode_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ff87d92a6e6ff8616cac3cf4764f2485ba3d3aa4
|
| --- /dev/null
|
| +++ b/packages/analyzer/test/src/task/strong_mode_test.dart
|
| @@ -0,0 +1,1049 @@
|
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library test.src.task.strong_mode_test;
|
| +
|
| +import 'package:analyzer/src/generated/ast.dart';
|
| +import 'package:analyzer/src/generated/element.dart';
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/task/strong_mode.dart';
|
| +import 'package:unittest/unittest.dart';
|
| +
|
| +import '../../reflective_tests.dart';
|
| +import '../../utils.dart';
|
| +import '../context/abstract_context.dart';
|
| +
|
| +main() {
|
| + initializeTestEnvironment();
|
| + runReflectiveTests(InstanceMemberInferrerTest);
|
| + runReflectiveTests(VariableGathererTest);
|
| +}
|
| +
|
| +@reflectiveTest
|
| +class InstanceMemberInferrerTest extends AbstractContextTest {
|
| + InstanceMemberInferrer get createInferrer =>
|
| + new InstanceMemberInferrer(context.typeProvider,
|
| + typeSystem: context.typeSystem);
|
| +
|
| + /**
|
| + * Add a source with the given [content] and return the result of resolving
|
| + * the source.
|
| + */
|
| + CompilationUnitElement resolve(String content) {
|
| + Source source = addSource('/test.dart', content);
|
| + return context.resolveCompilationUnit2(source, source).element;
|
| + }
|
| +
|
| + void test_creation() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + expect(inferrer, isNotNull);
|
| + expect(inferrer.typeSystem, isNotNull);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_multiple_different() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $fieldName;
|
| +}
|
| +class B {
|
| + double $fieldName;
|
| +}
|
| +class C implements A, B {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(fieldName);
|
| + PropertyAccessorElement getterC = classC.getGetter(fieldName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_multiple_different_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + E $fieldName;
|
| +}
|
| +class B<E> {
|
| + E $fieldName;
|
| +}
|
| +class C implements A<int>, B<double> {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(fieldName);
|
| + PropertyAccessorElement getterC = classC.getGetter(fieldName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_multiple_dynamic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $fieldName;
|
| +}
|
| +class B {
|
| + var $fieldName;
|
| +}
|
| +class C implements A, B {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(fieldName);
|
| + PropertyAccessorElement getterC = classC.getGetter(fieldName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_multiple_same() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $fieldName;
|
| +}
|
| +class B {
|
| + int $fieldName;
|
| +}
|
| +class C implements A, B {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + DartType expectedType = fieldA.type;
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(fieldName);
|
| + PropertyAccessorElement getterC = classC.getGetter(fieldName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type, expectedType);
|
| + expect(getterC.returnType, expectedType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_noOverride() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + final $fieldName = 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + PropertyAccessorElement getterA = classA.getGetter(fieldName);
|
| + expect(fieldA.type.isDynamic, isTrue);
|
| + expect(getterA.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + DartType intType = inferrer.typeProvider.intType;
|
| + expect(fieldA.type, intType);
|
| + expect(getterA.returnType, intType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_noOverride_bottom() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + var $fieldName = null;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + PropertyAccessorElement getterA = classA.getGetter(fieldName);
|
| + expect(fieldA.type.isDynamic, isTrue);
|
| + expect(getterA.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldA.type.isDynamic, isTrue);
|
| + expect(getterA.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_single_explicitlyDynamic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + dynamic $fieldName;
|
| +}
|
| +class B extends A {
|
| + var $fieldName = 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + PropertyAccessorElement getterA = classA.getGetter(fieldName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(fieldName);
|
| + PropertyAccessorElement getterB = classB.getGetter(fieldName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, fieldA.type);
|
| + expect(getterB.returnType, getterA.returnType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_single_final() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + final int $fieldName;
|
| +}
|
| +class B extends A {
|
| + final $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + PropertyAccessorElement getterA = classA.getGetter(fieldName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(fieldName);
|
| + PropertyAccessorElement getterB = classB.getGetter(fieldName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, fieldA.type);
|
| + expect(getterB.returnType, getterA.returnType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_single_final_narrowType() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + final $fieldName;
|
| +}
|
| +class B extends A {
|
| + final $fieldName = 0;
|
| +}
|
| +''');
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(fieldName);
|
| + PropertyAccessorElement getterB = classB.getGetter(fieldName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, inferrer.typeProvider.intType);
|
| + expect(getterB.returnType, fieldB.type);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_single_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + E $fieldName;
|
| +}
|
| +class B<E> extends A<E> {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classB = unit.getType('B');
|
| + DartType typeBE = classB.typeParameters[0].type;
|
| + FieldElement fieldB = classB.getField(fieldName);
|
| + PropertyAccessorElement getterB = classB.getGetter(fieldName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, typeBE);
|
| + expect(getterB.returnType, typeBE);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_single_inconsistentAccessors() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int get $fieldName => 0;
|
| + set $fieldName(String value) {}
|
| +}
|
| +class B extends A {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(fieldName);
|
| + PropertyAccessorElement getterB = classB.getGetter(fieldName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_field_single_noModifiers() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $fieldName;
|
| +}
|
| +class B extends A {
|
| + var $fieldName;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + PropertyAccessorElement getterA = classA.getGetter(fieldName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(fieldName);
|
| + PropertyAccessorElement getterB = classB.getGetter(fieldName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, fieldA.type);
|
| + expect(getterB.returnType, getterA.returnType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_getter_multiple_different() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int get $getterName => 0;
|
| +}
|
| +class B {
|
| + double get $getterName => 0.0;
|
| +}
|
| +class C implements A, B {
|
| + get $getterName => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(getterName);
|
| + PropertyAccessorElement getterC = classC.getGetter(getterName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_getter_multiple_dynamic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int get $getterName => 0;
|
| +}
|
| +class B {
|
| + get $getterName => 0;
|
| +}
|
| +class C implements A, B {
|
| + get $getterName => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(getterName);
|
| + PropertyAccessorElement getterC = classC.getGetter(getterName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_getter_multiple_same() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + String get $getterName => '';
|
| +}
|
| +class B {
|
| + String get $getterName => '';
|
| +}
|
| +class C implements A, B {
|
| + get $getterName => '';
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + PropertyAccessorElement getterA = classA.getGetter(getterName);
|
| + DartType expectedType = getterA.returnType;
|
| + ClassElement classC = unit.getType('C');
|
| + FieldElement fieldC = classC.getField(getterName);
|
| + PropertyAccessorElement getterC = classC.getGetter(getterName);
|
| + expect(fieldC.type.isDynamic, isTrue);
|
| + expect(getterC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldC.type, expectedType);
|
| + expect(getterC.returnType, expectedType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_getter_single() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int get $getterName => 0;
|
| +}
|
| +class B extends A {
|
| + get $getterName => 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(getterName);
|
| + PropertyAccessorElement getterA = classA.getGetter(getterName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(getterName);
|
| + PropertyAccessorElement getterB = classB.getGetter(getterName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, fieldA.type);
|
| + expect(getterB.returnType, getterA.returnType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_getter_single_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + E get $getterName => 0;
|
| +}
|
| +class B<E> extends A<E> {
|
| + get $getterName => 0;
|
| +}
|
| +''');
|
| + ClassElement classB = unit.getType('B');
|
| + DartType typeBE = classB.typeParameters[0].type;
|
| + FieldElement fieldB = classB.getField(getterName);
|
| + PropertyAccessorElement getterB = classB.getGetter(getterName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, typeBE);
|
| + expect(getterB.returnType, typeBE);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_getter_single_inconsistentAccessors() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int get $getterName => 0;
|
| + set $getterName(String value) {}
|
| +}
|
| +class B extends A {
|
| + var get $getterName => 1;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(getterName);
|
| + PropertyAccessorElement getterA = classA.getGetter(getterName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(getterName);
|
| + PropertyAccessorElement getterB = classB.getGetter(getterName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(getterB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + // Expected behavior is that the getter is inferred: getters and setters
|
| + // are treated as independent methods.
|
| + expect(fieldB.type, fieldA.type);
|
| + expect(getterB.returnType, getterA.returnType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_setter_single() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String setterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + set $setterName(int x) {}
|
| +}
|
| +class B extends A {
|
| + set $setterName(x) {}
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(setterName);
|
| + PropertyAccessorElement setterA = classA.getSetter(setterName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(setterName);
|
| + PropertyAccessorElement setterB = classB.getSetter(setterName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(setterB.parameters[0].type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, fieldA.type);
|
| + expect(setterB.parameters[0].type, setterA.parameters[0].type);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_setter_single_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String setterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + set $setterName(E x) {}
|
| +}
|
| +class B<E> extends A<E> {
|
| + set $setterName(x) {}
|
| +}
|
| +''');
|
| + ClassElement classB = unit.getType('B');
|
| + DartType typeBE = classB.typeParameters[0].type;
|
| + FieldElement fieldB = classB.getField(setterName);
|
| + PropertyAccessorElement setterB = classB.getSetter(setterName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(setterB.parameters[0].type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(fieldB.type, typeBE);
|
| + expect(setterB.parameters[0].type, typeBE);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_setter_single_inconsistentAccessors() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String getterName = 'g';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int get $getterName => 0;
|
| + set $getterName(String value) {}
|
| +}
|
| +class B extends A {
|
| + set $getterName(x) {}
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + PropertyAccessorElement setterA = classA.getSetter(getterName);
|
| + ClassElement classB = unit.getType('B');
|
| + FieldElement fieldB = classB.getField(getterName);
|
| + PropertyAccessorElement setterB = classB.getSetter(getterName);
|
| + expect(fieldB.type.isDynamic, isTrue);
|
| + expect(setterB.parameters[0].type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + // Expected behavior is that the getter is inferred: getters and setters
|
| + // are treated as independent methods.
|
| + expect(setterB.parameters[0].type, setterA.parameters[0].type);
|
| +
|
| + // Note that B's synthetic field type will be String. This matches what
|
| + // resolver would do if we explicitly typed the parameter as 'String'
|
| + expect(fieldB.type, setterB.parameters[0].type);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_invalid_inheritanceCycle() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + CompilationUnitElement unit = resolve('''
|
| +class A extends C {}
|
| +class B extends A {}
|
| +class C extends B {}
|
| +''');
|
| + inferrer.inferCompilationUnit(unit);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_parameter_multiple_different() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + $methodName(int p) => 0;
|
| +}
|
| +class B {
|
| + $methodName(double p) => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName(p) => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + ParameterElement parameterC = methodC.parameters[0];
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_parameter_multiple_named_different() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + $methodName({int p}) => 0;
|
| +}
|
| +class B {
|
| + $methodName({int q}) => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName({p}) => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + ParameterElement parameterC = methodC.parameters[0];
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_parameter_multiple_named_same() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + $methodName({int p}) => 0;
|
| +}
|
| +class B {
|
| + $methodName({int p}) => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName({p}) => 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + MethodElement methodA = classA.getMethod(methodName);
|
| + ParameterElement parameterA = methodA.parameters[0];
|
| + DartType expectedType = parameterA.type;
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + ParameterElement parameterC = methodC.parameters[0];
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(parameterC.type, expectedType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_parameter_multiple_namedAndRequired() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + $methodName({int p}) => 0;
|
| +}
|
| +class B {
|
| + $methodName(int p) => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName(p) => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + ParameterElement parameterC = methodC.parameters[0];
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + $methodName(int p) => 0;
|
| +}
|
| +class B {
|
| + $methodName([int p]) => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName(p) => 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + MethodElement methodA = classA.getMethod(methodName);
|
| + ParameterElement parameterA = methodA.parameters[0];
|
| + DartType expectedType = parameterA.type;
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + ParameterElement parameterC = methodC.parameters[0];
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(parameterC.type, expectedType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_parameter_single_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + $methodName(E p) => 0;
|
| +}
|
| +class C<E> implements A<E> {
|
| + $methodName(p) => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + DartType typeCE = classC.typeParameters[0].type;
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + ParameterElement parameterC = methodC.parameters[0];
|
| + expect(parameterC.type.isDynamic, isTrue);
|
| + expect(methodC.type.typeArguments, [typeCE]);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(parameterC.type, classC.typeParameters[0].type);
|
| + expect(methodC.type.typeArguments, [typeCE],
|
| + reason: 'function type should still have type arguments');
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_different() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $methodName() => 0;
|
| +}
|
| +class B {
|
| + double $methodName() => 0.0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_different_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + E $methodName() => null;
|
| +}
|
| +class B<E> {
|
| + E $methodName() => null;
|
| +}
|
| +class C implements A<int>, B<double> {
|
| + $methodName() => null;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_dynamic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $methodName() => 0;
|
| +}
|
| +class B {
|
| + $methodName() => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_same_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + E $methodName() => 0;
|
| +}
|
| +class B<E> {
|
| + E $methodName() => 0;
|
| +}
|
| +class C<E> implements A<E>, B<E> {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType, classC.typeParameters[0].type);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_same_nonVoid() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $methodName() => 0;
|
| +}
|
| +class B {
|
| + int $methodName() => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + MethodElement methodA = classA.getMethod(methodName);
|
| + DartType expectedType = methodA.returnType;
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType, expectedType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_same_void() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + void $methodName() {};
|
| +}
|
| +class B {
|
| + void $methodName() {};
|
| +}
|
| +class C implements A, B {
|
| + $methodName() {};
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + MethodElement methodA = classA.getMethod(methodName);
|
| + DartType expectedType = methodA.returnType;
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType, expectedType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_multiple_void() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $methodName() => 0;
|
| +}
|
| +class B {
|
| + void $methodName() => 0;
|
| +}
|
| +class C implements A, B {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classC = unit.getType('C');
|
| + MethodElement methodC = classC.getMethod(methodName);
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodC.returnType.isDynamic, isTrue);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_single() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + int $methodName() => 0;
|
| +}
|
| +class B extends A {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + MethodElement methodA = classA.getMethod(methodName);
|
| + ClassElement classB = unit.getType('B');
|
| + MethodElement methodB = classB.getMethod(methodName);
|
| + expect(methodB.returnType.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodB.returnType, methodA.returnType);
|
| + }
|
| +
|
| + void test_inferCompilationUnit_method_return_single_generic() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String methodName = 'm';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A<E> {
|
| + E $methodName() => 0;
|
| +}
|
| +class B<E> extends A<E> {
|
| + $methodName() => 0;
|
| +}
|
| +''');
|
| + ClassElement classB = unit.getType('B');
|
| + DartType typeBE = classB.typeParameters[0].type;
|
| + MethodElement methodB = classB.getMethod(methodName);
|
| + expect(methodB.returnType.isDynamic, isTrue);
|
| + expect(methodB.type.typeArguments, [typeBE]);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + expect(methodB.returnType, classB.typeParameters[0].type);
|
| + expect(methodB.type.typeArguments, [typeBE],
|
| + reason: 'function type should still have type arguments');
|
| + }
|
| +
|
| + void test_inferCompilationUnit_fieldFormal() {
|
| + InstanceMemberInferrer inferrer = createInferrer;
|
| + String fieldName = 'f';
|
| + CompilationUnitElement unit = resolve('''
|
| +class A {
|
| + final $fieldName = 0;
|
| + A([this.$fieldName = 'hello']);
|
| +}
|
| +''');
|
| + ClassElement classA = unit.getType('A');
|
| + FieldElement fieldA = classA.getField(fieldName);
|
| + FieldFormalParameterElement paramA =
|
| + classA.unnamedConstructor.parameters[0];
|
| + expect(fieldA.type.isDynamic, isTrue);
|
| + expect(paramA.type.isDynamic, isTrue);
|
| +
|
| + inferrer.inferCompilationUnit(unit);
|
| +
|
| + DartType intType = inferrer.typeProvider.intType;
|
| + expect(fieldA.type, intType);
|
| + expect(paramA.type, intType);
|
| + }
|
| +}
|
| +
|
| +@reflectiveTest
|
| +class VariableGathererTest extends AbstractContextTest {
|
| + void test_creation_withFilter() {
|
| + VariableFilter filter = (variable) => true;
|
| + VariableGatherer gatherer = new VariableGatherer(filter);
|
| + expect(gatherer, isNotNull);
|
| + expect(gatherer.filter, filter);
|
| + }
|
| +
|
| + void test_creation_withoutFilter() {
|
| + VariableGatherer gatherer = new VariableGatherer();
|
| + expect(gatherer, isNotNull);
|
| + expect(gatherer.filter, isNull);
|
| + }
|
| +
|
| + void test_visit_noReferences() {
|
| + Source source = addSource(
|
| + '/test.dart',
|
| + '''
|
| +library lib;
|
| +import 'dart:math';
|
| +int zero = 0;
|
| +class C {
|
| + void m() => null;
|
| +}
|
| +typedef void F();
|
| +''');
|
| + CompilationUnit unit = context.resolveCompilationUnit2(source, source);
|
| + VariableGatherer gatherer = new VariableGatherer();
|
| + unit.accept(gatherer);
|
| + expect(gatherer.results, hasLength(0));
|
| + }
|
| +
|
| + void test_visit_withFilter() {
|
| + VariableFilter filter = (VariableElement variable) => variable.isStatic;
|
| + expect(_gather(filter), hasLength(1));
|
| + }
|
| +
|
| + void test_visit_withoutFilter() {
|
| + expect(_gather(), hasLength(4));
|
| + }
|
| +
|
| + Set<VariableElement> _gather([VariableFilter filter = null]) {
|
| + Source source = addSource(
|
| + '/test.dart',
|
| + '''
|
| +const int zero = 0;
|
| +class Counter {
|
| + int value = zero;
|
| + void inc() {
|
| + value++;
|
| + }
|
| + void dec() {
|
| + value = value - 1;
|
| + }
|
| + void fromZero(f(int index)) {
|
| + for (int i = zero; i < value; i++) {
|
| + f(i);
|
| + }
|
| + }
|
| +}
|
| +''');
|
| + CompilationUnit unit = context.resolveCompilationUnit2(source, source);
|
| + VariableGatherer gatherer = new VariableGatherer(filter);
|
| + unit.accept(gatherer);
|
| + return gatherer.results;
|
| + }
|
| +}
|
|
|