| Index: packages/analyzer/test/src/task/incremental_element_builder_test.dart
|
| diff --git a/packages/analyzer/test/src/task/incremental_element_builder_test.dart b/packages/analyzer/test/src/task/incremental_element_builder_test.dart
|
| index b495be76e68c596d8753407e46f7a7e2ae36d922..b5765ebc5f495f3d4a84e461a5a1e0d986d3e23c 100644
|
| --- a/packages/analyzer/test/src/task/incremental_element_builder_test.dart
|
| +++ b/packages/analyzer/test/src/task/incremental_element_builder_test.dart
|
| @@ -2,21 +2,27 @@
|
| // 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.incremental_element_builder_test;
|
| +library analyzer.test.src.task.incremental_element_builder_test;
|
|
|
| -import 'package:analyzer/src/generated/ast.dart';
|
| -import 'package:analyzer/src/generated/element.dart';
|
| +import 'package:analyzer/dart/ast/ast.dart';
|
| +import 'package:analyzer/dart/element/element.dart';
|
| +import 'package:analyzer/dart/element/visitor.dart';
|
| +import 'package:analyzer/src/dart/ast/utilities.dart';
|
| +import 'package:analyzer/src/dart/element/element.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/task/dart.dart';
|
| import 'package:analyzer/src/task/incremental_element_builder.dart';
|
| +import 'package:analyzer/task/dart.dart';
|
| +import 'package:test_reflective_loader/test_reflective_loader.dart';
|
| import 'package:unittest/unittest.dart';
|
|
|
| -import '../../reflective_tests.dart';
|
| import '../../utils.dart';
|
| import '../context/abstract_context.dart';
|
|
|
| main() {
|
| initializeTestEnvironment();
|
| - runReflectiveTests(IncrementalCompilationUnitElementBuilderTest);
|
| + defineReflectiveTests(IncrementalCompilationUnitElementBuilderTest);
|
| }
|
|
|
| @reflectiveTest
|
| @@ -36,6 +42,1046 @@ class IncrementalCompilationUnitElementBuilderTest extends AbstractContextTest {
|
| return newCode.substring(node.offset, node.end);
|
| }
|
|
|
| + test_classDelta_annotation_add() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + expect(helper.element.metadata, isEmpty);
|
| + _buildNewUnit(r'''
|
| +@deprecated
|
| +class A {}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + expect(helper.delta.hasAnnotationChanges, isTrue);
|
| + expect(helper.element.metadata, hasLength(1));
|
| + }
|
| +
|
| + test_classDelta_annotation_remove() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +@deprecated
|
| +class A {}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + expect(helper.element.metadata, hasLength(1));
|
| + _buildNewUnit(r'''
|
| +class A {}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + expect(helper.delta.hasAnnotationChanges, isTrue);
|
| + expect(helper.element.metadata, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_0to1() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + ConstructorElement oldConstructorElement =
|
| + helper.element.unnamedConstructor;
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A.a();
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember newConstructorNode = helper.newMembers[0];
|
| + // elements
|
| + ConstructorElement newConstructorElement = newConstructorNode.element;
|
| + expect(newConstructorElement, isNotNull);
|
| + expect(newConstructorElement.name, 'a');
|
| + // classElement.constructors
|
| + ClassElement classElement = helper.element;
|
| + expect(classElement.constructors, unorderedEquals([newConstructorElement]));
|
| + // verify delta
|
| + expect(helper.delta.hasUnnamedConstructorChange, isTrue);
|
| + expect(helper.delta.addedConstructors,
|
| + unorderedEquals([newConstructorElement]));
|
| + expect(helper.delta.removedConstructors,
|
| + unorderedEquals([oldConstructorElement]));
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_1to0() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A.a();
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + ConstructorElement oldElementA = helper.element.getNamedConstructor('a');
|
| + _buildNewUnit(r'''
|
| +class A {
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // classElement.constructors
|
| + ClassElement classElement = helper.element;
|
| + {
|
| + List<ConstructorElement> constructors = classElement.constructors;
|
| + expect(constructors, hasLength(1));
|
| + expect(constructors[0].isDefaultConstructor, isTrue);
|
| + expect(constructors[0].isSynthetic, isTrue);
|
| + }
|
| + // verify delta
|
| + expect(helper.delta.hasUnnamedConstructorChange, isTrue);
|
| + expect(helper.delta.addedConstructors,
|
| + unorderedEquals([classElement.unnamedConstructor]));
|
| + expect(helper.delta.removedConstructors, unorderedEquals([oldElementA]));
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_1to1_unnamed_addParameter() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A();
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + ConstructorElement oldConstructor = helper.element.unnamedConstructor;
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A(int p);
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + ClassElement classElement = helper.element;
|
| + ConstructorElement newConstructor = classElement.unnamedConstructor;
|
| + expect(classElement.constructors, [newConstructor]);
|
| + // verify delta
|
| + expect(helper.delta.hasUnnamedConstructorChange, isTrue);
|
| + expect(helper.delta.addedConstructors, unorderedEquals([newConstructor]));
|
| + expect(helper.delta.removedConstructors, unorderedEquals([oldConstructor]));
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_1to1_unnamed_removeParameter() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + final int a;
|
| + final int b;
|
| + A(this.a, this.b);
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + ConstructorElement oldConstructor = helper.element.unnamedConstructor;
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + final int a;
|
| + final int b;
|
| + A(this.a);
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + ClassElement classElement = helper.element;
|
| + ConstructorElement newConstructor = classElement.unnamedConstructor;
|
| + expect(classElement.constructors, [newConstructor]);
|
| + // verify delta
|
| + expect(helper.delta.hasUnnamedConstructorChange, isTrue);
|
| + expect(helper.delta.addedConstructors, unorderedEquals([newConstructor]));
|
| + expect(helper.delta.removedConstructors, unorderedEquals([oldConstructor]));
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_1to2() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A.a();
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A.a();
|
| + A.b();
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember nodeA = helper.newMembers[0];
|
| + ClassMember nodeB = helper.newMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + ConstructorElement elementA = nodeA.element;
|
| + ConstructorElement elementB = nodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementB, isNotNull);
|
| + expect(elementA.name, 'a');
|
| + expect(elementB.name, 'b');
|
| + // classElement.constructors
|
| + ClassElement classElement = helper.element;
|
| + expect(classElement.constructors, unorderedEquals([elementA, elementB]));
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, unorderedEquals([elementB]));
|
| + expect(helper.delta.removedConstructors, unorderedEquals([]));
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_2to1() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A.a();
|
| + A.b();
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + ConstructorElement oldElementA = helper.element.getNamedConstructor('a');
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A.b();
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + expect(helper.delta.hasUnnamedConstructorChange, isFalse);
|
| + // nodes
|
| + ClassMember nodeB = helper.newMembers[0];
|
| + expect(nodeB, same(helper.oldMembers[1]));
|
| + // elements
|
| + ConstructorElement elementB = nodeB.element;
|
| + expect(elementB, isNotNull);
|
| + expect(elementB.name, 'b');
|
| + // classElement.constructors
|
| + ClassElement classElement = helper.element;
|
| + expect(classElement.constructors, unorderedEquals([elementB]));
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, unorderedEquals([]));
|
| + expect(helper.delta.removedConstructors, unorderedEquals([oldElementA]));
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_2to2_reorder() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A.a();
|
| + A.b();
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A.b();
|
| + A.a();
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember nodeB = helper.newMembers[0];
|
| + ClassMember nodeA = helper.newMembers[1];
|
| + expect(nodeB, same(helper.oldMembers[1]));
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + ConstructorElement elementB = nodeB.element;
|
| + ConstructorElement elementA = nodeA.element;
|
| + expect(elementB, isNotNull);
|
| + expect(elementA, isNotNull);
|
| + expect(elementB.name, 'b');
|
| + expect(elementA.name, 'a');
|
| + // classElement.constructors
|
| + ClassElement classElement = helper.element;
|
| + expect(classElement.constructors, unorderedEquals([elementB, elementA]));
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_constructor_fieldReference_initializer() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + final int f;
|
| + A() : f = 1 {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + final int f;
|
| + A() : f = 1;
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + }
|
| +
|
| + test_classDelta_constructor_fieldReference_parameter() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + final int f;
|
| + A(this.f) {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + final int f;
|
| + A(this.f);
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + }
|
| +
|
| + test_classDelta_constructor_fieldReference_parameter_default() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + final int f;
|
| + A([this.f = 1]) {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + final int f;
|
| + A([this.f = 1]);
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + }
|
| +
|
| + test_classDelta_duplicate_constructor() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A() {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A() {}
|
| + A() {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ConstructorDeclaration oldNode = helper.oldMembers[0];
|
| + ConstructorDeclaration newNode1 = helper.newMembers[0];
|
| + ConstructorDeclaration newNode2 = helper.newMembers[1];
|
| + // elements
|
| + ConstructorElement oldElement = oldNode.element;
|
| + ConstructorElement newElement1 = newNode1.element;
|
| + ConstructorElement newElement2 = newNode2.element;
|
| + expect(newElement1, same(oldElement));
|
| + expect(newElement2, isNot(same(oldElement)));
|
| + expect(oldElement.name, '');
|
| + expect(newElement1.name, '');
|
| + expect(newElement2.name, '');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, unorderedEquals([newElement2]));
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_duplicate_method() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + m() {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + m() {}
|
| + m() {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + MethodDeclaration oldNode = helper.oldMembers[0];
|
| + MethodDeclaration newNode1 = helper.newMembers[0];
|
| + MethodDeclaration newNode2 = helper.newMembers[1];
|
| + // elements
|
| + MethodElement oldElement = oldNode.element;
|
| + MethodElement newElement1 = newNode1.element;
|
| + MethodElement newElement2 = newNode2.element;
|
| + expect(newElement1, same(oldElement));
|
| + expect(newElement2, isNot(same(oldElement)));
|
| + expect(oldElement.name, 'm');
|
| + expect(newElement1.name, 'm');
|
| + expect(newElement2.name, 'm');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, unorderedEquals([newElement2]));
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_field_add() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + int aaa;
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + int aaa;
|
| + int bbb;
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + FieldDeclaration nodeA = helper.newMembers[0];
|
| + FieldDeclaration newNodeB = helper.newMembers[1];
|
| + List<VariableDeclaration> newFieldsB = newNodeB.fields.variables;
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + expect(newFieldsB, hasLength(1));
|
| + // elements
|
| + FieldElement newFieldElementB = newFieldsB[0].name.staticElement;
|
| + expect(newFieldElementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.hasAnnotationChanges, isFalse);
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors,
|
| + unorderedEquals([newFieldElementB.getter, newFieldElementB.setter]));
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_field_remove() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + int aaa;
|
| + int bbb;
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + int aaa;
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + FieldDeclaration nodeA = helper.newMembers[0];
|
| + FieldDeclaration oldNodeB = helper.oldMembers[1];
|
| + List<VariableDeclaration> oldFieldsB = oldNodeB.fields.variables;
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + FieldElement oldFieldElementB = oldFieldsB[0].name.staticElement;
|
| + expect(oldFieldElementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors,
|
| + unorderedEquals([oldFieldElementB.getter, oldFieldElementB.setter]));
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_field_syntheticAndNot_renameNonSynthetic() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + int foo;
|
| + int get foo => 1;
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + FieldDeclaration oldFieldDeclNode = helper.oldMembers[0];
|
| + VariableDeclaration oldFieldNode = oldFieldDeclNode.fields.variables.single;
|
| + FieldElement oldFieldElement = oldFieldNode.name.staticElement;
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + int _foo;
|
| + int get foo => 1;
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + FieldDeclaration newFieldDeclNode = helper.newMembers[0];
|
| + VariableDeclaration newFieldNode = newFieldDeclNode.fields.variables.single;
|
| + MethodDeclaration getterNode = helper.newMembers[1];
|
| + expect(getterNode, same(helper.oldMembers[1]));
|
| + // elements
|
| + FieldElement newFieldElement = newFieldNode.name.staticElement;
|
| + PropertyAccessorElement getterElement = getterNode.element;
|
| + expect(newFieldElement.name, '_foo');
|
| + expect(
|
| + helper.element.fields,
|
| + unorderedMatches(
|
| + [same(newFieldElement), same(getterElement.variable)]));
|
| + expect(
|
| + helper.element.accessors,
|
| + unorderedMatches([
|
| + same(newFieldElement.getter),
|
| + same(newFieldElement.setter),
|
| + same(getterElement)
|
| + ]));
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors,
|
| + unorderedEquals([newFieldElement.getter, newFieldElement.setter]));
|
| + expect(helper.delta.removedAccessors,
|
| + [oldFieldElement.getter, oldFieldElement.setter]);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_getter_add() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + int get aaa => 1;
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + int get aaa => 1;
|
| + int get bbb => 2;
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + MethodDeclaration nodeA = helper.oldMembers[0];
|
| + MethodDeclaration newNodeB = helper.newMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + PropertyAccessorElement elementA = nodeA.element;
|
| + PropertyAccessorElement newElementB = newNodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementA.name, 'aaa');
|
| + expect(newElementB, isNotNull);
|
| + expect(newElementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, unorderedEquals([newElementB]));
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_getter_remove() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + int get aaa => 1;
|
| + int get bbb => 2;
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + int get aaa => 1;
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + MethodDeclaration nodeA = helper.oldMembers[0];
|
| + MethodDeclaration oldNodeB = helper.oldMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + PropertyAccessorElement elementA = nodeA.element;
|
| + PropertyAccessorElement oldElementB = oldNodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementA.name, 'aaa');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, unorderedEquals([oldElementB]));
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_method_add() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + aaa() {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + aaa() {}
|
| + bbb() {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember nodeA = helper.oldMembers[0];
|
| + ClassMember newNodeB = helper.newMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + MethodElement elementA = nodeA.element;
|
| + MethodElement newElementB = newNodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementA.name, 'aaa');
|
| + expect(newElementB, isNotNull);
|
| + expect(newElementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, unorderedEquals([newElementB]));
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_method_addParameter() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + aaa() {}
|
| + bbb() {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + aaa(int p) {}
|
| + bbb() {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember oldNodeA = helper.oldMembers[0];
|
| + ClassMember newNodeA = helper.newMembers[0];
|
| + ClassMember nodeB = helper.newMembers[1];
|
| + expect(newNodeA, isNot(same(oldNodeA)));
|
| + expect(nodeB, same(helper.oldMembers[1]));
|
| + // elements
|
| + MethodElement oldElementA = oldNodeA.element;
|
| + MethodElement newElementA = newNodeA.element;
|
| + MethodElement elementB = nodeB.element;
|
| + expect(newElementA, isNotNull);
|
| + expect(newElementA.name, 'aaa');
|
| + expect(oldElementA.parameters, hasLength(0));
|
| + expect(newElementA.parameters, hasLength(1));
|
| + expect(elementB, isNotNull);
|
| + expect(elementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, unorderedEquals([newElementA]));
|
| + expect(helper.delta.removedMethods, unorderedEquals([oldElementA]));
|
| + }
|
| +
|
| + test_classDelta_method_changeName() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + aaa(int ap) {
|
| + int av = 1;
|
| + af(afp) {}
|
| + }
|
| + bbb(int bp) {
|
| + int bv = 1;
|
| + bf(bfp) {}
|
| + }
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + ConstructorElement oldConstructor = helper.element.unnamedConstructor;
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + aaa2(int ap) {
|
| + int av = 1;
|
| + af(afp) {}
|
| + }
|
| + bbb(int bp) {
|
| + int bv = 1;
|
| + bf(bfp) {}
|
| + }
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + expect(helper.element.unnamedConstructor, same(oldConstructor));
|
| + // nodes
|
| + ClassMember oldNodeA = helper.oldMembers[0];
|
| + ClassMember newNodeA = helper.newMembers[0];
|
| + ClassMember nodeB = helper.newMembers[1];
|
| + expect(nodeB, same(helper.oldMembers[1]));
|
| + // elements
|
| + MethodElement oldElementA = oldNodeA.element;
|
| + MethodElement newElementA = newNodeA.element;
|
| + MethodElement elementB = nodeB.element;
|
| + expect(newElementA, isNotNull);
|
| + expect(newElementA.name, 'aaa2');
|
| + expect(elementB, isNotNull);
|
| + expect(elementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, unorderedEquals([newElementA]));
|
| + expect(helper.delta.removedMethods, unorderedEquals([oldElementA]));
|
| + }
|
| +
|
| + test_classDelta_method_remove() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + aaa() {}
|
| + bbb() {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + aaa() {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember nodeA = helper.oldMembers[0];
|
| + ClassMember oldNodeB = helper.oldMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + MethodElement elementA = nodeA.element;
|
| + MethodElement oldElementB = oldNodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementA.name, 'aaa');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, unorderedEquals([oldElementB]));
|
| + }
|
| +
|
| + test_classDelta_method_removeParameter() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + aaa(int p) {}
|
| + bbb() {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + aaa() {}
|
| + bbb() {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + ClassMember oldNodeA = helper.oldMembers[0];
|
| + ClassMember newNodeA = helper.newMembers[0];
|
| + ClassMember nodeB = helper.newMembers[1];
|
| + expect(newNodeA, isNot(same(oldNodeA)));
|
| + expect(nodeB, same(helper.oldMembers[1]));
|
| + // elements
|
| + MethodElement oldElementA = oldNodeA.element;
|
| + MethodElement newElementA = newNodeA.element;
|
| + MethodElement elementB = nodeB.element;
|
| + expect(newElementA, isNotNull);
|
| + expect(newElementA.name, 'aaa');
|
| + expect(oldElementA.parameters, hasLength(1));
|
| + expect(newElementA.parameters, hasLength(0));
|
| + expect(elementB, isNotNull);
|
| + expect(elementB.name, 'bbb');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, unorderedEquals([newElementA]));
|
| + expect(helper.delta.removedMethods, unorderedEquals([oldElementA]));
|
| + }
|
| +
|
| + test_classDelta_null_abstractKeyword_add() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +''',
|
| + r'''
|
| +abstract class A {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_abstractKeyword_remove() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +abstract class A {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_extendsClause_add() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class B {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class B extends A {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_extendsClause_change() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A1 {}
|
| +class A2 {}
|
| +class B extends A1 {}
|
| +''',
|
| + r'''
|
| +class A1 {}
|
| +class A2 {}
|
| +class B extends A2 {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_extendsClause_remove() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class B extends A {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class B {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_implementsClause_add() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class B {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class B implements A {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_implementsClause_change() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A1 {}
|
| +class A2 {}
|
| +class B implements A1 {}
|
| +''',
|
| + r'''
|
| +class A1 {}
|
| +class A2 {}
|
| +class B implements A2 {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_implementsClause_remove() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class B implements A {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class B {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_typeParameters_change() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class B<T> {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class B<T extends A> {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_withClause_add() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class M {}
|
| +class B extends A {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class M {}
|
| +class B extends A with M {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_withClause_change1() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class M1 {}
|
| +class M2 {}
|
| +class B extends A with M1 {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class M1 {}
|
| +class M2 {}
|
| +class B extends A with M2 {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_withClause_change2() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class M1 {}
|
| +class M2 {}
|
| +class B extends A with M1, M2 {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class M1 {}
|
| +class M2 {}
|
| +class B extends A with M2, M1 {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_null_withClause_remove() {
|
| + _verifyNoClassDeltaForTheLast(
|
| + r'''
|
| +class A {}
|
| +class M {}
|
| +class B extends A with M {}
|
| +''',
|
| + r'''
|
| +class A {}
|
| +class M {}
|
| +class B extends A {}
|
| +''');
|
| + }
|
| +
|
| + test_classDelta_setter_add() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + void set aaa(int pa) {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + void set aaa(int pa) {}
|
| + void set bbb(int pb) {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + MethodDeclaration nodeA = helper.oldMembers[0];
|
| + MethodDeclaration newNodeB = helper.newMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + PropertyAccessorElement elementA = nodeA.element;
|
| + PropertyAccessorElement newElementB = newNodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementA.name, 'aaa=');
|
| + expect(newElementB, isNotNull);
|
| + expect(newElementB.name, 'bbb=');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, unorderedEquals([newElementB]));
|
| + expect(helper.delta.removedAccessors, isEmpty);
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_setter_remove() {
|
| + var helper = new _ClassDeltaHelper('A');
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + void set aaa(int pa) {}
|
| + void set bbb(int pb) {}
|
| +}
|
| +''');
|
| + helper.initOld(oldUnit);
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + void set aaa(int pa) {}
|
| +}
|
| +''');
|
| + helper.initNew(newUnit, unitDelta);
|
| + // nodes
|
| + MethodDeclaration nodeA = helper.oldMembers[0];
|
| + MethodDeclaration oldNodeB = helper.oldMembers[1];
|
| + expect(nodeA, same(helper.oldMembers[0]));
|
| + // elements
|
| + PropertyAccessorElement elementA = nodeA.element;
|
| + PropertyAccessorElement oldElementB = oldNodeB.element;
|
| + expect(elementA, isNotNull);
|
| + expect(elementA.name, 'aaa=');
|
| + // verify delta
|
| + expect(helper.delta.addedConstructors, isEmpty);
|
| + expect(helper.delta.removedConstructors, isEmpty);
|
| + expect(helper.delta.addedAccessors, isEmpty);
|
| + expect(helper.delta.removedAccessors, unorderedEquals([oldElementB]));
|
| + expect(helper.delta.addedMethods, isEmpty);
|
| + expect(helper.delta.removedMethods, isEmpty);
|
| + }
|
| +
|
| + test_classDelta_typeParameter_same() {
|
| + _buildOldUnit(r'''
|
| +class A<T> {
|
| + m() {}
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class A<T> {
|
| + m2() {}
|
| +}
|
| +''');
|
| + }
|
| +
|
| test_directives_add() {
|
| _buildOldUnit(r'''
|
| library test;
|
| @@ -102,6 +1148,27 @@ class A {}
|
| }
|
| }
|
|
|
| + test_directives_library_updateOffset() {
|
| + _buildOldUnit(r'''
|
| +#!/bin/sh
|
| +library my_lib;
|
| +class A {}
|
| +''');
|
| + LibraryDirective libraryDirective = oldUnit.directives.single;
|
| + // Set the LibraryElement and check that its nameOffset is correct.
|
| + libraryDirective.element =
|
| + new LibraryElementImpl.forNode(context, libraryDirective.name);
|
| + expect(libraryDirective.element.nameOffset, libraryDirective.name.offset);
|
| + // Update and check again that the nameOffset is correct.
|
| + _buildNewUnit(r'''
|
| +#!/bin/sh
|
| +
|
| +library my_lib;
|
| +class A {}
|
| +''');
|
| + expect(libraryDirective.element.nameOffset, libraryDirective.name.offset);
|
| + }
|
| +
|
| test_directives_remove() {
|
| _buildOldUnit(r'''
|
| library test;
|
| @@ -174,6 +1241,35 @@ import 'dart:math' as m;
|
| expect(unitDelta.hasDirectiveChange, isFalse);
|
| }
|
|
|
| + test_directives_sameImportPrefix_sameOrder() {
|
| + _buildOldUnit(r'''
|
| +import 'test1.dart' as m;
|
| +import 'test2.dart' as m;
|
| +''');
|
| + List<Directive> oldDirectives = oldUnit.directives.toList();
|
| + ImportDirective import1 = oldDirectives[0];
|
| + ImportDirective import2 = oldDirectives[1];
|
| + ImportElementImpl importElement1 = new ImportElementImpl(import1.offset);
|
| + ImportElementImpl importElement2 = new ImportElementImpl(import2.offset);
|
| + PrefixElement prefixElement = new PrefixElementImpl.forNode(import1.prefix);
|
| + importElement1.prefix = prefixElement;
|
| + importElement2.prefix = prefixElement;
|
| + import1.element = importElement1;
|
| + import2.element = importElement2;
|
| + import1.prefix.staticElement = prefixElement;
|
| + import2.prefix.staticElement = prefixElement;
|
| + _buildNewUnit(r'''
|
| +import 'test1.dart' as m;
|
| +import 'test2.dart' as m;
|
| +class A {}
|
| +''');
|
| + int expectedPrefixOffset = 23;
|
| + expect(import1.prefix.staticElement.nameOffset, expectedPrefixOffset);
|
| + expect(import2.prefix.staticElement.nameOffset, expectedPrefixOffset);
|
| + expect(importElement1.prefix.nameOffset, expectedPrefixOffset);
|
| + expect(importElement2.prefix.nameOffset, expectedPrefixOffset);
|
| + }
|
| +
|
| test_directives_sameOrder_insertSpaces() {
|
| _buildOldUnit(r'''
|
| library test;
|
| @@ -488,6 +1584,14 @@ enum B {B1, B2}
|
| expect(elementB, isNotNull);
|
| expect(elementA.name, 'A');
|
| expect(elementB.name, 'B');
|
| + expect(elementA.fields.map((f) => f.name),
|
| + unorderedEquals(['index', 'values', 'A1', 'A2']));
|
| + expect(elementA.accessors.map((a) => a.name),
|
| + unorderedEquals(['index', 'values', 'A1', 'A2']));
|
| + expect(elementB.fields.map((f) => f.name),
|
| + unorderedEquals(['index', 'values', 'B1', 'B2']));
|
| + expect(elementB.accessors.map((a) => a.name),
|
| + unorderedEquals(['index', 'values', 'B1', 'B2']));
|
| // unit.types
|
| expect(unitElement.enums, unorderedEquals([elementA, elementB]));
|
| // verify delta
|
| @@ -670,15 +1774,247 @@ final int a = 1;
|
| expect(unitDelta.removedDeclarations, unorderedEquals([]));
|
| }
|
|
|
| + test_update_addIdentifier_beforeConstructorWithComment() {
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + /// CCC
|
| + A();
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + b
|
| +
|
| + /// CCC
|
| + A();
|
| +}
|
| +''');
|
| + }
|
| +
|
| + test_update_annotation_add() {
|
| + _buildOldUnit(r'''
|
| +const myAnnotation = const Object();
|
| +foo() {}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +const myAnnotation = const Object();
|
| +@myAnnotation
|
| +foo() {}
|
| +''');
|
| + }
|
| +
|
| + test_update_beforeClassWithDelta_nameOffset() {
|
| + _buildOldUnit(r'''
|
| +class A {}
|
| +
|
| +class B {
|
| + A a;
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class A2 {}
|
| +
|
| +class B {
|
| + A2 a;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + test_update_changeDuplicatingOffsetsMapping() {
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + m() {
|
| + }
|
| +}
|
| +
|
| +/// X
|
| +class C {}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + m2() {
|
| + b
|
| + }
|
| +}
|
| +
|
| +/// X
|
| +class C {}
|
| +''');
|
| + }
|
| +
|
| + test_update_closuresOfSyntheticInitializer() {
|
| + _buildOldUnit(r'''
|
| +f1() {
|
| + print(1);
|
| +}
|
| +f2() {
|
| + B b = new B((C c) {});
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +f1() {
|
| + print(12);
|
| +}
|
| +f2() {
|
| + B b = new B((C c) {});
|
| +}
|
| +''');
|
| + }
|
| +
|
| + test_update_commentReference_empty() {
|
| + _buildOldUnit(r'''
|
| +/// Empty [] reference.
|
| +class A {}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +/// Empty [] reference.
|
| +class A {}
|
| +''');
|
| + }
|
| +
|
| + test_update_commentReference_multipleCommentTokens() {
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + /// C1 [C2]
|
| + /// C3 [C4]
|
| + /// C5 [C6]
|
| + void m() {}
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + int field;
|
| +
|
| + /// C1 [C2]
|
| + /// C3 [C4]
|
| + /// C5 [C6]
|
| + void m() {}
|
| +}
|
| +''');
|
| + }
|
| +
|
| + test_update_commentReference_new() {
|
| + _buildOldUnit(r'''
|
| +/// Comment reference with new [new A].
|
| +class A {}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class B {}
|
| +/// Comment reference with new [new A].
|
| +class A {}
|
| +''');
|
| + }
|
| +
|
| + test_update_commentReference_notClosed() {
|
| + _buildOldUnit(r'''
|
| +/// [c)
|
| +class A {}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +int a;
|
| +/// [c)
|
| +class A {}
|
| +''');
|
| + }
|
| +
|
| + test_update_element_implicitAccessors_classField() {
|
| + _buildOldUnit(r'''
|
| +// 0
|
| +class A {
|
| + var F = 0;
|
| +}
|
| +''');
|
| + _materializeLazyElements(unitElement);
|
| + _buildNewUnit(r'''
|
| +// 012
|
| +class A {
|
| + var F = 0;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + test_update_element_implicitAccessors_topLevelVariable() {
|
| + _buildOldUnit(r'''
|
| +var A = 0;
|
| +var B = 1;
|
| +''');
|
| + _materializeLazyElements(unitElement);
|
| + _buildNewUnit(r'''
|
| +var B = 1;
|
| +''');
|
| + }
|
| +
|
| + test_update_parseError_diffPlus_removeOne() {
|
| + _buildOldUnit(r'''
|
| +class C {
|
| + + /// comment
|
| + + String field;
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class C {
|
| + + /// comment
|
| + String field;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + test_update_rewrittenConstructorName() {
|
| + _buildOldUnit(r'''
|
| +class A {
|
| + A();
|
| + A.named();
|
| +}
|
| +
|
| +foo() {}
|
| +
|
| +main() {
|
| + new A();
|
| + new A.named();
|
| +}
|
| +''');
|
| + _buildNewUnit(r'''
|
| +class A {
|
| + A();
|
| + A.named();
|
| +}
|
| +
|
| +bar() {}
|
| +
|
| +main() {
|
| + new A();
|
| + new A.named();
|
| +}
|
| +''');
|
| + }
|
| +
|
| void _buildNewUnit(String newCode) {
|
| this.newCode = newCode;
|
| - context.setContents(source, newCode);
|
| - newUnit = context.parseCompilationUnit(source);
|
| - IncrementalCompilationUnitElementBuilder builder =
|
| - new IncrementalCompilationUnitElementBuilder(oldUnit, newUnit);
|
| - builder.build();
|
| - unitDelta = builder.unitDelta;
|
| - expect(newUnit.element, unitElement);
|
| + AnalysisOptionsImpl analysisOptions = context.analysisOptions;
|
| + analysisOptions.finerGrainedInvalidation = false;
|
| + try {
|
| + context.setContents(source, newCode);
|
| + newUnit = context.parseCompilationUnit(source);
|
| + IncrementalCompilationUnitElementBuilder builder =
|
| + new IncrementalCompilationUnitElementBuilder(oldUnit, newUnit);
|
| + builder.build();
|
| + unitDelta = builder.unitDelta;
|
| + expect(newUnit.element, unitElement);
|
| + // Flush all tokens, ASTs and elements.
|
| + context.analysisCache.flush((target, result) {
|
| + return result == TOKEN_STREAM ||
|
| + result == PARSED_UNIT ||
|
| + RESOLVED_UNIT_RESULTS.contains(result) ||
|
| + LIBRARY_ELEMENT_RESULTS.contains(result);
|
| + });
|
| + // Compute a new AST with built elements.
|
| + CompilationUnit newUnitFull = context.computeResult(
|
| + new LibrarySpecificUnit(source, source), RESOLVED_UNIT1);
|
| + expect(newUnitFull, isNot(same(newUnit)));
|
| + new _BuiltElementsValidator().isEqualNodes(newUnitFull, newUnit);
|
| + } finally {
|
| + analysisOptions.finerGrainedInvalidation = true;
|
| + }
|
| }
|
|
|
| void _buildOldUnit(String oldCode, [Source libSource]) {
|
| @@ -691,4 +2027,202 @@ final int a = 1;
|
| unitElement = oldUnit.element;
|
| expect(unitElement, isNotNull);
|
| }
|
| +
|
| + void _materializeLazyElements(CompilationUnitElement unitElement) {
|
| + unitElement.accept(new _MaterializeLazyElementsVisitor());
|
| + }
|
| +
|
| + void _verifyNoClassDeltaForTheLast(String oldCode, String newCode) {
|
| + _buildOldUnit(oldCode);
|
| + List<CompilationUnitMember> oldMembers = oldUnit.declarations.toList();
|
| + Element oldElementLast = oldMembers.last.element;
|
| + _buildNewUnit(newCode);
|
| + List<CompilationUnitMember> newMembers = newUnit.declarations;
|
| + Element newElementLast = newMembers.last.element;
|
| + expect(newElementLast, isNot(same(oldElementLast)));
|
| + expect(unitDelta.classDeltas, isEmpty);
|
| + expect(unitDelta.removedDeclarations, unorderedEquals([oldElementLast]));
|
| + expect(unitDelta.addedDeclarations, unorderedEquals([newElementLast]));
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Compares tokens and ASTs, and built elements of declared identifiers.
|
| + */
|
| +class _BuiltElementsValidator extends AstComparator {
|
| + final Set visited = new Set.identity();
|
| +
|
| + @override
|
| + bool isEqualNodes(AstNode expected, AstNode actual) {
|
| + // Elements of nodes which are children of ClassDeclaration(s) must be
|
| + // linked to the corresponding ClassElement(s).
|
| + if (actual is TypeParameter) {
|
| + TypeParameterElement element = actual.element;
|
| + ClassDeclaration classNode = actual.parent.parent;
|
| + expect(element.enclosingElement, same(classNode.element));
|
| + } else if (actual is FieldDeclaration) {
|
| + for (VariableDeclaration field in actual.fields.variables) {
|
| + Element element = field.element;
|
| + ClassDeclaration classNode = actual.parent;
|
| + expect(element.enclosingElement, same(classNode.element));
|
| + }
|
| + } else if (actual is ClassMember) {
|
| + Element element = actual.element;
|
| + ClassDeclaration classNode = actual.parent;
|
| + expect(element.enclosingElement, same(classNode.element));
|
| + }
|
| + // Field elements referenced by field formal parameters of constructors
|
| + // must by fields of the enclosing class element.
|
| + if (actual is FieldFormalParameter) {
|
| + FieldFormalParameterElement parameterElement = actual.element;
|
| + FieldElement element = parameterElement.field;
|
| + ClassDeclaration classNode =
|
| + actual.getAncestor((n) => n is ClassDeclaration);
|
| + expect(element.enclosingElement, same(classNode.element));
|
| + }
|
| + // ElementAnnotationImpl must use the enclosing CompilationUnitElement.
|
| + if (actual is Annotation) {
|
| + AstNode parent = actual.parent;
|
| + if (parent is Declaration) {
|
| + ElementAnnotationImpl actualElement = actual.elementAnnotation;
|
| + CompilationUnitElement enclosingUnitElement =
|
| + parent.element.getAncestor((a) => a is CompilationUnitElement);
|
| + expect(actualElement.compilationUnit, same(enclosingUnitElement));
|
| + }
|
| + }
|
| + // Identifiers like 'a.b' in 'new a.b()' might be rewritten if resolver
|
| + // sees that 'a' is actually a class name, so 'b' is a constructor name.
|
| + //
|
| + if (expected is ConstructorName && actual is ConstructorName) {
|
| + Identifier expectedTypeName = expected.type.name;
|
| + Identifier actualTypeName = actual.type.name;
|
| + if (expectedTypeName is PrefixedIdentifier &&
|
| + actualTypeName is SimpleIdentifier) {
|
| + return isEqualNodes(expectedTypeName.prefix, actualTypeName) &&
|
| + isEqualNodes(expectedTypeName.identifier, actual.name);
|
| + }
|
| + }
|
| + // Compare nodes.
|
| + bool result = super.isEqualNodes(expected, actual);
|
| + if (!result) {
|
| + fail('|$actual| != expected |$expected|');
|
| + }
|
| + // Verify that declared identifiers have equal elements.
|
| + if (expected is SimpleIdentifier && actual is SimpleIdentifier) {
|
| + if (expected.inDeclarationContext()) {
|
| + expect(actual.inDeclarationContext(), isTrue);
|
| + Element expectedElement = expected.staticElement;
|
| + Element actualElement = actual.staticElement;
|
| + _verifyElement(
|
| + expectedElement, actualElement, 'staticElement ($expectedElement)');
|
| + }
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + void _verifyElement(Element expected, Element actual, String desc) {
|
| + if (!visited.add(expected)) {
|
| + return;
|
| + }
|
| + if (expected == null && actual == null) {
|
| + return;
|
| + }
|
| + // Prefixes are built later.
|
| + if (actual is PrefixElement) {
|
| + return;
|
| + }
|
| + // Compare properties.
|
| + _verifyEqual('$desc name', expected.name, actual.name);
|
| + _verifyEqual('$desc nameOffset', expected.nameOffset, actual.nameOffset);
|
| + _verifyEqual('$desc isSynthetic', expected.isSynthetic, actual.isSynthetic);
|
| + if (expected is ElementImpl && actual is ElementImpl) {
|
| + _verifyEqual('$desc codeOffset', expected.codeOffset, actual.codeOffset);
|
| + _verifyEqual('$desc codeLength', expected.codeLength, actual.codeLength);
|
| + }
|
| + if (expected is LocalElement && actual is LocalElement) {
|
| + _verifyEqual(
|
| + '$desc visibleRange', expected.visibleRange, actual.visibleRange);
|
| + }
|
| + _verifyEqual('$desc documentationComment', expected.documentationComment,
|
| + actual.documentationComment);
|
| + {
|
| + var expectedEnclosing = expected.enclosingElement;
|
| + var actualEnclosing = actual.enclosingElement;
|
| + if (expectedEnclosing != null) {
|
| + expect(actualEnclosing, isNotNull, reason: '$desc enclosingElement');
|
| + _verifyElement(expectedEnclosing, actualEnclosing,
|
| + '${expectedEnclosing.name}.$desc');
|
| + }
|
| + }
|
| + // Compare implicit accessors.
|
| + if (expected is PropertyInducingElement &&
|
| + actual is PropertyInducingElement &&
|
| + !expected.isSynthetic) {
|
| + _verifyElement(expected.getter, actual.getter, '$desc getter');
|
| + _verifyElement(expected.setter, actual.setter, '$desc setter');
|
| + }
|
| + // Compare implicit properties.
|
| + if (expected is PropertyAccessorElement &&
|
| + actual is PropertyAccessorElement &&
|
| + !expected.isSynthetic) {
|
| + _verifyElement(expected.variable, actual.variable, '$desc variable');
|
| + }
|
| + // Compare parameters.
|
| + if (expected is ExecutableElement && actual is ExecutableElement) {
|
| + List<ParameterElement> actualParameters = actual.parameters;
|
| + List<ParameterElement> expectedParameters = expected.parameters;
|
| + expect(actualParameters, hasLength(expectedParameters.length));
|
| + for (int i = 0; i < expectedParameters.length; i++) {
|
| + _verifyElement(
|
| + expectedParameters[i], actualParameters[i], '$desc parameters[$i]');
|
| + }
|
| + }
|
| + }
|
| +
|
| + void _verifyEqual(String name, expected, actual) {
|
| + if (actual != expected) {
|
| + fail('$name\nExpected: $expected\n Actual: $actual');
|
| + }
|
| + }
|
| +}
|
| +
|
| +class _ClassDeltaHelper {
|
| + final String name;
|
| +
|
| + ClassElementDelta delta;
|
| + ClassElementImpl element;
|
| + int oldVersion;
|
| + List<ClassMember> oldMembers;
|
| + List<ClassMember> newMembers;
|
| +
|
| + _ClassDeltaHelper(this.name);
|
| +
|
| + void initNew(CompilationUnit newUnit, CompilationUnitElementDelta unitDelta) {
|
| + expect(element.version, isNot(oldVersion));
|
| + ClassDeclaration newClass = _findClassNode(newUnit, name);
|
| + expect(newClass, isNotNull);
|
| + newMembers = newClass.members.toList();
|
| + delta = unitDelta.classDeltas[name];
|
| + expect(delta, isNotNull, reason: 'No delta for class: $name');
|
| + }
|
| +
|
| + void initOld(CompilationUnit oldUnit) {
|
| + ClassDeclaration oldClass = _findClassNode(oldUnit, name);
|
| + expect(oldClass, isNotNull);
|
| + element = oldClass.element;
|
| + oldVersion = element.version;
|
| + oldMembers = oldClass.members.toList();
|
| + }
|
| +
|
| + ClassDeclaration _findClassNode(CompilationUnit unit, String name) =>
|
| + unit.declarations.singleWhere((unitMember) =>
|
| + unitMember is ClassDeclaration && unitMember.name.name == name);
|
| +}
|
| +
|
| +class _MaterializeLazyElementsVisitor extends GeneralizingElementVisitor {
|
| + @override
|
| + visitExecutableElement(ExecutableElement element) {
|
| + element.parameters;
|
| + super.visitExecutableElement(element);
|
| + }
|
| }
|
|
|