| Index: pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
|
| diff --git a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
|
| index 8ff8eb511316e216fcddcedf10fd67d3d2f3fb11..a6e05ae0e2f476de85af53feeaa7088b64ccf8be 100644
|
| --- a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
|
| +++ b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
|
| @@ -12,7 +12,12 @@ import 'package:analyzer/dart/ast/ast.dart';
|
| import 'package:analyzer/dart/ast/standard_resolution_map.dart';
|
| import 'package:analyzer/dart/element/element.dart';
|
| import 'package:analyzer/dart/element/type.dart';
|
| +import 'package:analyzer/src/context/source.dart';
|
| import 'package:analyzer/src/dart/analysis/driver.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/resolver.dart';
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/generated/testing/test_type_provider.dart';
|
| import 'package:test/test.dart';
|
| import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
| @@ -23,9 +28,34 @@ main() {
|
| defineReflectiveTests(DartChangeBuilderImplTest);
|
| defineReflectiveTests(DartEditBuilderImplTest);
|
| defineReflectiveTests(DartFileEditBuilderImplTest);
|
| + defineReflectiveTests(DartLinkedEditBuilderImplTest);
|
| });
|
| }
|
|
|
| +abstract class BuilderTestMixin {
|
| + SourceEdit getEdit(DartChangeBuilderImpl builder) {
|
| + SourceChange sourceChange = builder.sourceChange;
|
| + expect(sourceChange, isNotNull);
|
| + List<SourceFileEdit> fileEdits = sourceChange.edits;
|
| + expect(fileEdits, hasLength(1));
|
| + SourceFileEdit fileEdit = fileEdits[0];
|
| + expect(fileEdit, isNotNull);
|
| + List<SourceEdit> edits = fileEdit.edits;
|
| + expect(edits, hasLength(1));
|
| + return edits[0];
|
| + }
|
| +
|
| + List<SourceEdit> getEdits(DartChangeBuilderImpl builder) {
|
| + SourceChange sourceChange = builder.sourceChange;
|
| + expect(sourceChange, isNotNull);
|
| + List<SourceFileEdit> fileEdits = sourceChange.edits;
|
| + expect(fileEdits, hasLength(1));
|
| + SourceFileEdit fileEdit = fileEdits[0];
|
| + expect(fileEdit, isNotNull);
|
| + return fileEdit.edits;
|
| + }
|
| +}
|
| +
|
| @reflectiveTest
|
| class DartChangeBuilderImplTest extends AbstractContextTest {
|
| @override
|
| @@ -46,22 +76,11 @@ class DartChangeBuilderImplTest extends AbstractContextTest {
|
| }
|
|
|
| @reflectiveTest
|
| -class DartEditBuilderImplTest extends AbstractContextTest {
|
| +class DartEditBuilderImplTest extends AbstractContextTest
|
| + with BuilderTestMixin {
|
| @override
|
| bool get enableNewAnalysisDriver => true;
|
|
|
| - SourceEdit getEdit(DartChangeBuilderImpl builder) {
|
| - SourceChange sourceChange = builder.sourceChange;
|
| - expect(sourceChange, isNotNull);
|
| - List<SourceFileEdit> fileEdits = sourceChange.edits;
|
| - expect(fileEdits, hasLength(1));
|
| - SourceFileEdit fileEdit = fileEdits[0];
|
| - expect(fileEdit, isNotNull);
|
| - List<SourceEdit> edits = fileEdit.edits;
|
| - expect(edits, hasLength(1));
|
| - return edits[0];
|
| - }
|
| -
|
| test_writeClassDeclaration_interfaces() async {
|
| String path = '/test.dart';
|
| addSource(path, 'class A {}');
|
| @@ -176,12 +195,19 @@ class DartEditBuilderImplTest extends AbstractContextTest {
|
| DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| builder.addInsertion(0, (EditBuilder builder) {
|
| - (builder as DartEditBuilder)
|
| - .writeClassDeclaration('C', superclass: typeB);
|
| + (builder as DartEditBuilder).writeClassDeclaration('C',
|
| + superclass: typeB, superclassGroupName: 'superclass');
|
| });
|
| });
|
| SourceEdit edit = getEdit(builder);
|
| expect(edit.replacement, equalsIgnoringWhitespace('class C extends B { }'));
|
| +
|
| + List<LinkedEditGroup> linkedEditGroups =
|
| + builder.sourceChange.linkedEditGroups;
|
| + expect(linkedEditGroups, hasLength(1));
|
| + LinkedEditGroup group = linkedEditGroups[0];
|
| + expect(group.length, 1);
|
| + expect(group.positions, hasLength(1));
|
| }
|
|
|
| test_writeFieldDeclaration_initializerWriter() async {
|
| @@ -314,6 +340,90 @@ class DartEditBuilderImplTest extends AbstractContextTest {
|
| expect(position.offset, equals(20));
|
| }
|
|
|
| + test_writeFunctionDeclaration_noReturnType_noParams_body() async {
|
| + String path = '/test.dart';
|
| + String content = '';
|
| + addSource(path, content);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(0, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeFunctionDeclaration('fib',
|
| + bodyWriter: () {
|
| + builder.write('{ ... }');
|
| + });
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('fib() { ... }'));
|
| + }
|
| +
|
| + test_writeFunctionDeclaration_noReturnType_noParams_noBody() async {
|
| + String path = '/test.dart';
|
| + String content = '';
|
| + addSource(path, content);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(0, (EditBuilder builder) {
|
| + (builder as DartEditBuilder)
|
| + .writeFunctionDeclaration('fib', nameGroupName: 'name');
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('fib() {}'));
|
| +
|
| + List<LinkedEditGroup> linkedEditGroups =
|
| + builder.sourceChange.linkedEditGroups;
|
| + expect(linkedEditGroups, hasLength(1));
|
| + LinkedEditGroup group = linkedEditGroups[0];
|
| + expect(group.length, 3);
|
| + expect(group.positions, hasLength(1));
|
| + }
|
| +
|
| + test_writeFunctionDeclaration_noReturnType_params_noBody() async {
|
| + String path = '/test.dart';
|
| + String content = '';
|
| + addSource(path, content);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(0, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeFunctionDeclaration('fib',
|
| + parameterWriter: () {
|
| + builder.write('p, q, r');
|
| + });
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('fib(p, q, r) {}'));
|
| + }
|
| +
|
| + test_writeFunctionDeclaration_returnType_noParams_noBody() async {
|
| + String path = '/test.dart';
|
| + String content = 'class A {}';
|
| + addSource(path, content);
|
| +
|
| + DartType typeA = await _getType(path, 'A');
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(0, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeFunctionDeclaration('fib',
|
| + returnType: typeA, returnTypeGroupName: 'type');
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('A fib() => null;'));
|
| +
|
| + List<LinkedEditGroup> linkedEditGroups =
|
| + builder.sourceChange.linkedEditGroups;
|
| + expect(linkedEditGroups, hasLength(1));
|
| + LinkedEditGroup group = linkedEditGroups[0];
|
| + expect(group.length, 1);
|
| + expect(group.positions, hasLength(1));
|
| + }
|
| +
|
| test_writeGetterDeclaration_bodyWriter() async {
|
| String path = '/test.dart';
|
| String content = 'class A {}';
|
| @@ -399,6 +509,180 @@ class DartEditBuilderImplTest extends AbstractContextTest {
|
| expect(position.offset, equals(20));
|
| }
|
|
|
| + test_writeLocalVariableDeclaration_noType_initializer() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}''';
|
| + addSource(path, content);
|
| + await driver.getResult(path);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
|
| + initializerWriter: () {
|
| + builder.write('null');
|
| + });
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('var foo = null;'));
|
| + }
|
| +
|
| + test_writeLocalVariableDeclaration_noType_noInitializer() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}''';
|
| + addSource(path, content);
|
| + await driver.getResult(path);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder)
|
| + .writeLocalVariableDeclaration('foo', nameGroupName: 'name');
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('var foo;'));
|
| +
|
| + List<LinkedEditGroup> linkedEditGroups =
|
| + builder.sourceChange.linkedEditGroups;
|
| + expect(linkedEditGroups, hasLength(1));
|
| + LinkedEditGroup group = linkedEditGroups[0];
|
| + expect(group.length, 3);
|
| + expect(group.positions, hasLength(1));
|
| + }
|
| +
|
| + test_writeLocalVariableDeclaration_noType_noInitializer_const() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}''';
|
| + addSource(path, content);
|
| + await driver.getResult(path);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder)
|
| + .writeLocalVariableDeclaration('foo', isConst: true);
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('const foo;'));
|
| + }
|
| +
|
| + test_writeLocalVariableDeclaration_noType_noInitializer_final() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}''';
|
| + addSource(path, content);
|
| + await driver.getResult(path);
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder)
|
| + .writeLocalVariableDeclaration('foo', isFinal: true);
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('final foo;'));
|
| + }
|
| +
|
| + test_writeLocalVariableDeclaration_type_initializer() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}
|
| +class MyClass {}''';
|
| + addSource(path, content);
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| +
|
| + ClassDeclaration A = unit.declarations[1];
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
|
| + initializerWriter: () {
|
| + builder.write('null');
|
| + }, type: A.element.type);
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo = null;'));
|
| + }
|
| +
|
| + test_writeLocalVariableDeclaration_type_noInitializer() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}
|
| +class MyClass {}''';
|
| + addSource(path, content);
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| +
|
| + ClassDeclaration A = unit.declarations[1];
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
|
| + type: A.element.type, typeGroupName: 'type');
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo;'));
|
| +
|
| + List<LinkedEditGroup> linkedEditGroups =
|
| + builder.sourceChange.linkedEditGroups;
|
| + expect(linkedEditGroups, hasLength(1));
|
| + LinkedEditGroup group = linkedEditGroups[0];
|
| + expect(group.length, 7);
|
| + expect(group.positions, hasLength(1));
|
| + }
|
| +
|
| + test_writeLocalVariableDeclaration_type_noInitializer_final() async {
|
| + String path = '/test.dart';
|
| + String content = '''
|
| +void f() {
|
| +
|
| +}
|
| +class MyClass {}''';
|
| + addSource(path, content);
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| +
|
| + ClassDeclaration A = unit.declarations[1];
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(11, (EditBuilder builder) {
|
| + (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
|
| + isFinal: true, type: A.element.type, typeGroupName: 'type');
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('final MyClass foo;'));
|
| +
|
| + List<LinkedEditGroup> linkedEditGroups =
|
| + builder.sourceChange.linkedEditGroups;
|
| + expect(linkedEditGroups, hasLength(1));
|
| + LinkedEditGroup group = linkedEditGroups[0];
|
| + expect(group.length, 7);
|
| + expect(group.positions, hasLength(1));
|
| + }
|
| +
|
| test_writeOverrideOfInheritedMember() async {
|
| String path = '/test.dart';
|
| String content = '''
|
| @@ -426,10 +710,39 @@ A add(A a) {
|
| }'''));
|
| }
|
|
|
| + test_writeParameterMatchingArgument() async {
|
| + String path = '/test.dart';
|
| + String content = r'''
|
| +f() {}
|
| +g() {
|
| + f(new A());
|
| +}
|
| +class A {}
|
| +''';
|
| + addSource(path, content);
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| + FunctionDeclaration g = unit.declarations[1];
|
| + BlockFunctionBody body = g.functionExpression.body;
|
| + ExpressionStatement statement = body.block.statements[0];
|
| + MethodInvocation invocation = statement.expression;
|
| + Expression argument = invocation.argumentList.arguments[0];
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + builder.addInsertion(2, (EditBuilder builder) {
|
| + (builder as DartEditBuilder)
|
| + .writeParameterMatchingArgument(argument, 0, new Set<String>());
|
| + });
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('A a'));
|
| + }
|
| +
|
| test_writeParameters_named() async {
|
| String path = '/test.dart';
|
| String content = 'f(int i, {String s}) {}';
|
| addSource(path, content);
|
| +
|
| CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| FunctionDeclaration f = unit.declarations[0];
|
| FormalParameterList parameters = f.functionExpression.parameters;
|
| @@ -507,8 +820,7 @@ f(int i, String s) {
|
| });
|
| });
|
| SourceEdit edit = getEdit(builder);
|
| - expect(
|
| - edit.replacement, equalsIgnoringWhitespace('(String s, [int index])'));
|
| + expect(edit.replacement, equalsIgnoringWhitespace('String s, {int index}'));
|
| }
|
|
|
| test_writeParametersMatchingArguments_required() async {
|
| @@ -532,7 +844,7 @@ f(int i, String s) {
|
| });
|
| });
|
| SourceEdit edit = getEdit(builder);
|
| - expect(edit.replacement, equalsIgnoringWhitespace('(String s, int i)'));
|
| + expect(edit.replacement, equalsIgnoringWhitespace('String s, int i'));
|
| }
|
|
|
| test_writeParameterSource() async {
|
| @@ -804,10 +1116,36 @@ f(int i, String s) {
|
| }
|
|
|
| @reflectiveTest
|
| -class DartFileEditBuilderImplTest extends AbstractContextTest {
|
| +class DartFileEditBuilderImplTest extends AbstractContextTest
|
| + with BuilderTestMixin {
|
| @override
|
| bool get enableNewAnalysisDriver => true;
|
|
|
| + TypeProvider get typeProvider {
|
| + AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
|
| + context.sourceFactory = new SourceFactoryImpl([new DartUriResolver(sdk)]);
|
| + return new TestTypeProvider(context);
|
| + }
|
| +
|
| + test_convertFunctionFromSyncToAsync() async {
|
| + String path = '/test.dart';
|
| + addSource(path, 'String f() {}');
|
| +
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| + FunctionDeclaration function = unit.declarations[0];
|
| + FunctionBody body = function.functionExpression.body;
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + (builder as DartFileEditBuilder)
|
| + .convertFunctionFromSyncToAsync(body, typeProvider);
|
| + });
|
| + List<SourceEdit> edits = getEdits(builder);
|
| + expect(edits, hasLength(2));
|
| + expect(edits[0].replacement, equalsIgnoringWhitespace('async'));
|
| + expect(edits[1].replacement, equalsIgnoringWhitespace('Future<String>'));
|
| + }
|
| +
|
| test_createEditBuilder() async {
|
| String path = '/test.dart';
|
| addSource(path, 'library test;');
|
| @@ -825,4 +1163,46 @@ class DartFileEditBuilderImplTest extends AbstractContextTest {
|
| expect(sourceEdit.replacement, isEmpty);
|
| });
|
| }
|
| +
|
| + test_replaceTypeWithFuture() async {
|
| + String path = '/test.dart';
|
| + addSource(path, 'String f() {}');
|
| +
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| + FunctionDeclaration function = unit.declarations[0];
|
| + TypeAnnotation type = function.returnType;
|
| +
|
| + DartChangeBuilderImpl builder = new DartChangeBuilderImpl(driver);
|
| + await builder.addFileEdit(path, 1, (FileEditBuilder builder) {
|
| + (builder as DartFileEditBuilder)
|
| + .replaceTypeWithFuture(type, typeProvider);
|
| + });
|
| + SourceEdit edit = getEdit(builder);
|
| + expect(edit.replacement, equalsIgnoringWhitespace('Future<String>'));
|
| + }
|
| +}
|
| +
|
| +@reflectiveTest
|
| +class DartLinkedEditBuilderImplTest extends AbstractContextTest {
|
| + @override
|
| + bool get enableNewAnalysisDriver => true;
|
| +
|
| + test_addSuperTypesAsSuggestions() async {
|
| + String path = '/test.dart';
|
| + addSource(
|
| + path,
|
| + '''
|
| +class A {}
|
| +class B extends A {}
|
| +class C extends B {}
|
| +''');
|
| + CompilationUnit unit = (await driver.getResult(path))?.unit;
|
| + ClassDeclaration classC = unit.declarations[2];
|
| + DartLinkedEditBuilderImpl builder = new DartLinkedEditBuilderImpl(null);
|
| + builder.addSuperTypesAsSuggestions(classC.element.type);
|
| + List<LinkedEditSuggestion> suggestions = builder.suggestions;
|
| + expect(suggestions, hasLength(4));
|
| + expect(suggestions.map((s) => s.value),
|
| + unorderedEquals(['Object', 'A', 'B', 'C']));
|
| + }
|
| }
|
|
|