| // Copyright (c) 2017, 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. |
| |
| // ignore_for_file: camel_case_types |
| |
| import 'package:analyzer/dart/analysis/results.dart'; |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/nullability_suffix.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| import 'package:analyzer/source/source_range.dart'; |
| import 'package:analyzer/src/dart/element/inheritance_manager3.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:analyzer/src/test_utilities/find_node.dart'; |
| import 'package:analyzer/src/test_utilities/package_config_file_builder.dart'; |
| import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; |
| import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart' |
| show DartFileEditBuilderImpl, DartLinkedEditBuilderImpl; |
| import 'package:test/test.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| |
| import '../../../support/abstract_context.dart'; |
| import 'dart/dart_change_builder_mixin.dart'; |
| import 'mocks.dart'; |
| |
| void main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(DartEditBuilderImpl); |
| defineReflectiveTests(DartFileEditBuilderImplTest); |
| defineReflectiveTests(DartLinkedEditBuilderImplTest); |
| defineReflectiveTests(ImportLibraryTest); |
| defineReflectiveTests(WriteOverrideTest); |
| }); |
| } |
| |
| @reflectiveTest |
| class DartEditBuilderImpl extends DartEditBuilderImplTest { |
| Future<void> test_sourceEditDescriptions_delete() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| |
| var builder = await newBuilder(); |
| builder.currentChangeDescription = 'Change Desc'; |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addDeletion(SourceRange(0, 1)); |
| }); |
| |
| expect(builder.sourceChange.edits[0].edits[0].description, 'Change Desc'); |
| } |
| |
| Future<void> test_sourceEditDescriptions_insert() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| |
| var builder = await newBuilder(); |
| builder.currentChangeDescription = 'Change Desc'; |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addSimpleInsertion(0, '_'); |
| builder.addInsertion(0, (builder) => builder.write('_')); |
| }); |
| |
| expect(builder.sourceChange.edits[0].edits[0].description, 'Change Desc'); |
| expect(builder.sourceChange.edits[0].edits[1].description, 'Change Desc'); |
| } |
| |
| Future<void> test_sourceEditDescriptions_replace() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| |
| var builder = await newBuilder(); |
| builder.currentChangeDescription = 'Change Desc'; |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addSimpleReplacement(SourceRange(0, 1), '_'); |
| builder.addReplacement( |
| SourceRange(10, 1), |
| (builder) => builder.write('_'), |
| ); |
| }); |
| |
| expect(builder.sourceChange.edits[0].edits[0].description, 'Change Desc'); |
| expect(builder.sourceChange.edits[0].edits[1].description, 'Change Desc'); |
| } |
| |
| Future<void> test_writeParameter_covariantAndRequired() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a', isCovariant: true, isRequiredNamed: true); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect( |
| edits[0].replacement, equalsIgnoringWhitespace('covariant required a')); |
| } |
| |
| Future<void> test_writeParameter_required_addImport() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a', isRequiredNamed: true); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('required a')); |
| } |
| |
| Future<void> test_writeParameter_required_existingImport() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| var content = ''' |
| import 'package:meta/meta.dart'; |
| |
| class A {} |
| '''; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a', isRequiredNamed: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('required a')); |
| } |
| |
| Future<void> test_writeParameter_required_keyword() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a', isRequiredNamed: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('required a')); |
| } |
| |
| Future<void> test_writeType_function_nullable() async { |
| await _assertWriteType('int Function(double a, String b)?'); |
| } |
| |
| Future<void> test_writeType_Never_none() async { |
| await _assertWriteType('Never'); |
| } |
| |
| Future<void> test_writeType_Never_question() async { |
| await _assertWriteType('Never?'); |
| } |
| |
| Future<void> test_writeType_recordType_mixed() async { |
| await _assertWriteType('(int, {int y})'); |
| } |
| |
| Future<void> test_writeType_recordType_named() async { |
| await _assertWriteType('({int x, int y})'); |
| } |
| |
| Future<void> test_writeType_recordType_nullable() async { |
| await _assertWriteType('(int, {int y})?'); |
| } |
| |
| Future<void> test_writeType_recordType_positional() async { |
| await _assertWriteType('(int, int)'); |
| } |
| } |
| |
| class DartEditBuilderImplTest extends AbstractContextTest |
| with DartChangeBuilderMixin { |
| @override |
| void setUp() { |
| super.setUp(); |
| writeTestPackageConfig( |
| config: PackageConfigFileBuilder(), |
| meta: true, |
| ); |
| } |
| |
| Future<void> test_writeClassDeclaration_interfaces() async { |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| addSource(path, 'class A {}'); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', interfaces: [typeA]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect( |
| edit.replacement, equalsIgnoringWhitespace('class C implements A { }')); |
| } |
| |
| Future<void> test_writeClassDeclaration_isAbstract() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', isAbstract: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('abstract class C { }')); |
| } |
| |
| Future<void> test_writeClassDeclaration_memberWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', membersWriter: () { |
| builder.write('/**/'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('class C { /**/}')); |
| } |
| |
| Future<void> test_writeClassDeclaration_mixins_noSuperclass() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class A {}'); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', mixins: [typeA]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('class C with A { }')); |
| } |
| |
| Future<void> test_writeClassDeclaration_mixins_superclass() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class A {} class B {}'); |
| DartType typeA = await _getType(path, 'A'); |
| DartType typeB = await _getType(path, 'B'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', mixins: [typeB], superclass: typeA); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, |
| equalsIgnoringWhitespace('class C extends A with B { }')); |
| } |
| |
| Future<void> test_writeClassDeclaration_nameGroupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('class C { }')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> test_writeClassDeclaration_superclass() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class B {}'); |
| DartType typeB = await _getType(path, 'B'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeClassDeclaration('C', |
| superclass: typeB, superclassGroupName: 'superclass'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('class C extends B { }')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> test_writeConstructorDeclaration_bodyWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class C {}'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(9, (builder) { |
| builder.writeConstructorDeclaration('A', bodyWriter: () { |
| builder.write(' { print(42); }'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A() { print(42); }')); |
| } |
| |
| Future<void> test_writeConstructorDeclaration_fieldNames() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, r''' |
| class C { |
| final int a; |
| final bool bb; |
| } |
| '''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(42, (builder) { |
| builder.writeConstructorDeclaration('A', fieldNames: ['a', 'bb']); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A(this.a, this.bb);')); |
| } |
| |
| Future<void> test_writeConstructorDeclaration_initializerWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class C {}'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(9, (builder) { |
| builder.writeConstructorDeclaration('A', initializerWriter: () { |
| builder.write('super()'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A() : super();')); |
| } |
| |
| Future<void> test_writeConstructorDeclaration_parameterWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class C {}'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(9, (builder) { |
| builder.writeConstructorDeclaration('A', parameterWriter: () { |
| builder.write('int a, {this.b}'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A(int a, {this.b});')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_initializerWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', initializerWriter: () { |
| builder.write('e'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('var f = e;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_isConst() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', isConst: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('const f;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_isConst_isFinal() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', isConst: true, isFinal: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('const f;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_isConst_type() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', isConst: true, type: typeA); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('const A f;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_isFinal() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', isFinal: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('final f;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_isFinal_type() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', isFinal: true, type: typeA); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('final A f;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_isStatic() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', isStatic: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('static var f;')); |
| } |
| |
| Future<void> test_writeFieldDeclaration_nameGroupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('var f;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| var position = group.positions[0]; |
| expect(position.offset, equals(13)); |
| } |
| |
| Future<void> test_writeFieldDeclaration_type_typeGroupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeFieldDeclaration('f', type: typeA, typeGroupName: 'type'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A f;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| var position = group.positions[0]; |
| expect(position.offset, equals(20)); |
| } |
| |
| Future<void> |
| test_writeFunctionDeclaration_noReturnType_noParams_body() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeFunctionDeclaration('fib', bodyWriter: () { |
| builder.write('{ ... }'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('fib() { ... }')); |
| } |
| |
| Future<void> |
| test_writeFunctionDeclaration_noReturnType_noParams_noBody() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeFunctionDeclaration('fib', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('fib() {}')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 3); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> |
| test_writeFunctionDeclaration_noReturnType_params_noBody() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeFunctionDeclaration('fib', parameterWriter: () { |
| builder.write('p, q, r'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('fib(p, q, r) {}')); |
| } |
| |
| Future<void> |
| test_writeFunctionDeclaration_returnType_noParams_noBody() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeFunctionDeclaration('fib', |
| returnType: typeA, returnTypeGroupName: 'type'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A fib() => null;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> test_writeGetterDeclaration_bodyWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeGetterDeclaration('g', bodyWriter: () { |
| builder.write('{}'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('get g {}')); |
| } |
| |
| Future<void> test_writeGetterDeclaration_isStatic() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeGetterDeclaration('g', isStatic: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('static get g => null;')); |
| } |
| |
| Future<void> test_writeGetterDeclaration_nameGroupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeGetterDeclaration('g', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('get g => null;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| var position = group.positions[0]; |
| expect(position.offset, equals(13)); |
| } |
| |
| Future<void> test_writeGetterDeclaration_returnType() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeGetterDeclaration('g', |
| returnType: typeA, returnTypeGroupName: 'returnType'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A get g => null;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| var position = group.positions[0]; |
| expect(position.offset, equals(20)); |
| } |
| |
| Future<void> test_writeImportedName_hasImport_first() async { |
| // addSource(convertPath('/home/test/lib/foo.dart'), ''); |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''' |
| import 'foo.dart'; |
| '''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeImportedName([ |
| Uri.parse('package:test/foo.dart'), |
| Uri.parse('package:test/bar.dart') |
| ], 'Foo'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('Foo')); |
| } |
| |
| Future<void> test_writeImportedName_hasImport_second() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''' |
| import 'bar.dart'; |
| '''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeImportedName([ |
| Uri.parse('package:test/foo.dart'), |
| Uri.parse('package:test/bar.dart') |
| ], 'Foo'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('Foo')); |
| } |
| |
| Future<void> test_writeImportedName_needsImport_insertion() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeImportedName([ |
| Uri.parse('package:test/foo.dart'), |
| Uri.parse('package:test/bar.dart') |
| ], 'Foo'); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('Foo')); |
| expect(edits[1].replacement, |
| equalsIgnoringWhitespace("import 'package:test/foo.dart';\n")); |
| var result = SourceEdit.applySequence(content, edits); |
| expect(result, ''' |
| import 'package:test/foo.dart'; |
| |
| Foo'''); |
| } |
| |
| Future<void> test_writeImportedName_needsImport_replacement() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'test'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addReplacement(SourceRange(0, 4), (builder) { |
| builder.writeImportedName([ |
| Uri.parse('package:test/foo.dart'), |
| Uri.parse('package:test/bar.dart') |
| ], 'Foo'); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('Foo')); |
| expect(edits[1].replacement, |
| equalsIgnoringWhitespace("import 'package:test/foo.dart';\n")); |
| var result = SourceEdit.applySequence(content, edits); |
| expect(result, ''' |
| import 'package:test/foo.dart'; |
| |
| Foo'''); |
| } |
| |
| Future<void> test_writeLocalVariableDeclaration_noType_initializer() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| }'''; |
| addSource(path, content); |
| await resolveFile(path); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration('foo', initializerWriter: () { |
| builder.write('null'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('var foo = null;')); |
| } |
| |
| Future<void> test_writeLocalVariableDeclaration_noType_noInitializer() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| }'''; |
| addSource(path, content); |
| await resolveFile(path); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration('foo', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('var foo;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 3); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> |
| test_writeLocalVariableDeclaration_noType_noInitializer_const() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| }'''; |
| addSource(path, content); |
| await resolveFile(path); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration('foo', isConst: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('const foo;')); |
| } |
| |
| Future<void> |
| test_writeLocalVariableDeclaration_noType_noInitializer_final() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| }'''; |
| addSource(path, content); |
| await resolveFile(path); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration('foo', isFinal: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('final foo;')); |
| } |
| |
| Future<void> test_writeLocalVariableDeclaration_type_initializer() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| } |
| class MyClass {}'''; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| |
| var A = unit.declarations[1] as ClassDeclaration; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration( |
| 'foo', |
| initializerWriter: () { |
| builder.write('null'); |
| }, |
| type: A.declaredElement?.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| ), |
| ); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo = null;')); |
| } |
| |
| Future<void> test_writeLocalVariableDeclaration_type_noInitializer() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| } |
| class MyClass {}'''; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| |
| var A = unit.declarations[1] as ClassDeclaration; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration( |
| 'foo', |
| type: A.declaredElement?.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| ), |
| typeGroupName: 'type', |
| ); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('MyClass foo;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 7); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> |
| test_writeLocalVariableDeclaration_type_noInitializer_final() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| void f() { |
| |
| } |
| class MyClass {}'''; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| |
| var A = unit.declarations[1] as ClassDeclaration; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(11, (builder) { |
| builder.writeLocalVariableDeclaration( |
| 'foo', |
| isFinal: true, |
| type: A.declaredElement?.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| ), |
| typeGroupName: 'type', |
| ); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('final MyClass foo;')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 7); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> test_writeMixinDeclaration_interfaces() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class A {}'); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeMixinDeclaration('M', interfaces: [typeA]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect( |
| edit.replacement, equalsIgnoringWhitespace('mixin M implements A { }')); |
| } |
| |
| Future<void> |
| test_writeMixinDeclaration_interfacesAndSuperclassConstraints() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class A {} class B {}'); |
| DartType typeA = await _getType(path, 'A'); |
| DartType typeB = await _getType(path, 'B'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeMixinDeclaration('M', |
| interfaces: [typeA], superclassConstraints: [typeB]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, |
| equalsIgnoringWhitespace('mixin M on B implements A { }')); |
| } |
| |
| Future<void> test_writeMixinDeclaration_memberWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeMixinDeclaration('M', membersWriter: () { |
| builder.write('/**/'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('mixin M { /**/}')); |
| } |
| |
| Future<void> test_writeMixinDeclaration_nameGroupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeMixinDeclaration('M', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('mixin M { }')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| } |
| |
| Future<void> test_writeMixinDeclaration_superclassConstraints() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'class A {}'); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeMixinDeclaration('M', superclassConstraints: [typeA]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('mixin M on A { }')); |
| } |
| |
| Future<void> test_writeParameter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('a')); |
| } |
| |
| Future<void> test_writeParameter_covariant() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a', isCovariant: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('covariant a')); |
| } |
| |
| Future<void> test_writeParameter_type() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameter('a', type: typeA); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A a')); |
| } |
| |
| Future<void> test_writeParameterMatchingArgument() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = r''' |
| f() {} |
| g() { |
| f(new A()); |
| } |
| class A {} |
| '''; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| var g = unit.declarations[1] as FunctionDeclaration; |
| var body = g.functionExpression.body as BlockFunctionBody; |
| var statement = body.block.statements[0] as ExpressionStatement; |
| var invocation = statement.expression as MethodInvocation; |
| var argument = invocation.argumentList.arguments[0]; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(2, (builder) { |
| builder.writeParameterMatchingArgument(argument, 0, <String>{}); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A a')); |
| } |
| |
| Future<void> test_writeParameters_named() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'f(int a, {bool b = false, String c}) {}'; |
| addSource(path, content); |
| |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var parameters = f.functionExpression.parameters; |
| var elements = parameters?.parameters.map((p) => p.declaredElement!); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameters(elements!); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, |
| equalsIgnoringWhitespace('(int a, {bool b = false, String c})')); |
| } |
| |
| Future<void> test_writeParameters_noDefaults() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'f(int a, {bool b = false, String c = ""}) {}'; |
| addSource(path, content); |
| |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var parameters = f.functionExpression.parameters; |
| var elements = parameters?.parameters.map((p) => p.declaredElement!); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameters(elements!, includeDefaultValues: false); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, |
| equalsIgnoringWhitespace('(int a, {bool b, String c})')); |
| } |
| |
| Future<void> test_writeParameters_positional() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'f(int a, [bool b = false, String c]) {}'; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var parameters = f.functionExpression.parameters; |
| var elements = parameters?.parameters.map((p) => p.declaredElement!); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameters(elements!); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, |
| equalsIgnoringWhitespace('(int a, [bool b = false, String c])')); |
| } |
| |
| Future<void> test_writeParameters_required() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'f(int i, String s) {}'; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var parameters = f.functionExpression.parameters; |
| var elements = parameters?.parameters.map((p) => p.declaredElement!); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameters(elements!); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('(int i, String s)')); |
| } |
| |
| Future<void> test_writeParameters_requiredTypes() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'void f(e) {}'; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var parameters = f.functionExpression.parameters; |
| var elements = parameters?.parameters.map((p) => p.declaredElement!); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParameters(elements!, requiredTypes: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equals('(dynamic e)')); |
| } |
| |
| Future<void> test_writeParametersMatchingArguments_named() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| f(int i, String s) { |
| g(s, index: i); |
| }'''; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var body = f.functionExpression.body as BlockFunctionBody; |
| var statement = body.block.statements[0] as ExpressionStatement; |
| var invocation = statement.expression as MethodInvocation; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParametersMatchingArguments(invocation.argumentList); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, |
| equalsIgnoringWhitespace('String s, {required int index}')); |
| } |
| |
| Future<void> test_writeParametersMatchingArguments_required() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''' |
| f(int i, String s) { |
| g(s, i); |
| }'''; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| var f = unit.declarations[0] as FunctionDeclaration; |
| var body = f.functionExpression.body as BlockFunctionBody; |
| var statement = body.block.statements[0] as ExpressionStatement; |
| var invocation = statement.expression as MethodInvocation; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeParametersMatchingArguments(invocation.argumentList); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('String s, int i')); |
| } |
| |
| Future<void> test_writeReference_method() async { |
| var aPath = convertPath('$testPackageRootPath/a.dart'); |
| addSource(aPath, r''' |
| class A { |
| void foo() {} |
| } |
| '''); |
| |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| var content = r''' |
| import 'a.dart'; |
| '''; |
| addSource(path, content); |
| |
| var aElement = await _getClassElement(aPath, 'A'); |
| var fooElement = aElement.methods[0]; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeReference(fooElement); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('foo')); |
| } |
| |
| Future<void> test_writeReference_topLevel_hasImport_noPrefix() async { |
| var aPath = convertPath('$testPackageRootPath/lib/a.dart'); |
| addSource(aPath, 'const a = 42;'); |
| |
| var path = convertPath('$testPackageRootPath/lib/test.dart'); |
| var content = r''' |
| import 'a.dart'; |
| '''; |
| addSource(path, content); |
| |
| var aElement = await _getTopLevelAccessorElement(aPath, 'a'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeReference(aElement); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('a')); |
| } |
| |
| Future<void> test_writeReference_topLevel_hasImport_prefix() async { |
| var aPath = convertPath('/home/test/lib/a.dart'); |
| addSource(aPath, 'const a = 42;'); |
| |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = r''' |
| import 'a.dart' as p; |
| '''; |
| addSource(path, content); |
| |
| var aElement = await _getTopLevelAccessorElement(aPath, 'a'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeReference(aElement); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('p.a')); |
| } |
| |
| Future<void> test_writeReference_topLevel_noImport() async { |
| var aPath = convertPath('/home/test/bin/a.dart'); |
| addSource(aPath, 'const a = 42;'); |
| |
| var path = convertPath('/home/test/bin/test.dart'); |
| var content = ''; |
| addSource(path, content); |
| |
| var aElement = await _getTopLevelAccessorElement(aPath, 'a'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeReference(aElement); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('a')); |
| expect(edits[1].replacement, equalsIgnoringWhitespace("import 'a.dart';")); |
| var result = SourceEdit.applySequence(content, edits); |
| expect(result, ''' |
| import 'a.dart'; |
| |
| a'''); |
| } |
| |
| Future<void> test_writeSetterDeclaration_bodyWriter() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeSetterDeclaration('s', bodyWriter: () { |
| builder.write('{/* TODO */}'); |
| }); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('set s(s) {/* TODO */}')); |
| } |
| |
| Future<void> test_writeSetterDeclaration_isStatic() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeSetterDeclaration('s', isStatic: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('static set s(s) {}')); |
| } |
| |
| Future<void> test_writeSetterDeclaration_nameGroupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeSetterDeclaration('s', nameGroupName: 'name'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('set s(s) {}')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| var position = group.positions[0]; |
| expect(position.offset, equals(13)); |
| } |
| |
| Future<void> test_writeSetterDeclaration_parameterType() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeSetterDeclaration('s', |
| parameterType: typeA, parameterTypeGroupName: 'returnType'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('set s(A s) {}')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group.length, 1); |
| expect(group.positions, hasLength(1)); |
| var position = group.positions[0]; |
| expect(position.offset, equals(26)); |
| } |
| |
| Future<void> test_writeType_dynamic() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| var typeProvider = unit.declaredElement!.library.typeProvider; |
| builder.writeType(typeProvider.dynamicType); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('')); |
| } |
| |
| Future<void> test_writeType_function() async { |
| await _assertWriteType('int Function(double a, String b)'); |
| } |
| |
| Future<void> test_writeType_function_generic() async { |
| await _assertWriteType('T Function<T, U>(T a, U b)'); |
| } |
| |
| Future<void> test_writeType_function_noReturnType() async { |
| await _assertWriteType('Function()'); |
| } |
| |
| Future<void> test_writeType_function_parameters_named() async { |
| await _assertWriteType('int Function(int a, {int b, int c})'); |
| } |
| |
| Future<void> test_writeType_function_parameters_noName() async { |
| await _assertWriteType('int Function(double p1, String p2)'); |
| } |
| |
| Future<void> test_writeType_function_parameters_positional() async { |
| await _assertWriteType('int Function(int a, [int b, int c])'); |
| } |
| |
| Future<void> test_writeType_genericType() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B<E> {}'; |
| addSource(path, content); |
| var typeA = await _getType(path, 'A'); |
| var typeBofA = await _getType(path, 'B', typeArguments: [typeA]); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(typeBofA); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('B<A>')); |
| } |
| |
| Future<void> test_writeType_groupName() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B extends A {} class C extends B {}'; |
| addSource(path, content); |
| DartType typeC = await _getType(path, 'C'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(typeC, groupName: 'type'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('C')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| expect(group, isNotNull); |
| } |
| |
| Future<void> test_writeType_groupName_addSupertypeProposals() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B extends A {} class C extends B {}'; |
| addSource(path, content); |
| DartType typeC = await _getType(path, 'C'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(typeC, |
| addSupertypeProposals: true, groupName: 'type'); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('C')); |
| |
| var linkedEditGroups = builder.sourceChange.linkedEditGroups; |
| expect(linkedEditGroups, hasLength(1)); |
| var group = linkedEditGroups[0]; |
| var suggestions = group.suggestions; |
| expect(suggestions, hasLength(4)); |
| var values = suggestions.map((LinkedEditSuggestion suggestion) { |
| expect(suggestion.kind, LinkedEditSuggestionKind.TYPE); |
| return suggestion.value; |
| }); |
| expect(values, contains('Object')); |
| expect(values, contains('A')); |
| expect(values, contains('B')); |
| expect(values, contains('C')); |
| } |
| |
| Future<void> test_writeType_groupName_invalidType() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A<T> {}'; |
| addSource(path, content); |
| |
| var classA = await _getClassElement(path, 'A'); |
| DartType typeT = classA.typeParameters.single.instantiate( |
| nullabilitySuffix: NullabilitySuffix.none, |
| ); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length, (builder) { |
| // "T" cannot be written, because we are outside of "A". |
| // So, we also should not create linked groups. |
| builder.writeType(typeT, groupName: 'type'); |
| }); |
| }); |
| expect(builder.sourceChange.linkedEditGroups, isEmpty); |
| } |
| |
| Future<void> test_writeType_interface_typeArguments() async { |
| await _assertWriteType('Map<int, List<String>>'); |
| } |
| |
| Future<void> test_writeType_interface_typeArguments_allDynamic() async { |
| await _assertWriteType('Map'); |
| } |
| |
| Future<void> test_writeType_null() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(null); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('')); |
| } |
| |
| Future<void> test_writeType_prefixGenerator() async { |
| var aPath = convertPath('/home/test/lib/a.dart'); |
| var bPath = convertPath('/home/test/lib/b.dart'); |
| |
| addSource(aPath, r''' |
| class A1 {} |
| class A2 {} |
| '''); |
| addSource(bPath, r''' |
| class B {} |
| '''); |
| |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = ''; |
| addSource(path, content); |
| |
| var a1 = await _getClassElement(aPath, 'A1'); |
| var a2 = await _getClassElement(aPath, 'A2'); |
| var b = await _getClassElement(bPath, 'B'); |
| |
| var nextPrefixIndex = 0; |
| String prefixGenerator(_) { |
| return '_prefix${nextPrefixIndex++}'; |
| } |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(0, (builder) { |
| builder.writeType(a1.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| )); |
| builder.write(' a1; '); |
| |
| builder.writeType(a2.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| )); |
| builder.write(' a2; '); |
| |
| builder.writeType(b.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| )); |
| builder.write(' b;'); |
| }); |
| }, importPrefixGenerator: prefixGenerator); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| expect( |
| edits[0].replacement, |
| equalsIgnoringWhitespace( |
| '_prefix0.A1 a1; _prefix0.A2 a2; _prefix1.B b;')); |
| expect( |
| edits[1].replacement, |
| equalsIgnoringWhitespace("import 'package:test/a.dart' as _prefix0; " |
| "import 'package:test/b.dart' as _prefix1;")); |
| |
| var resultCode = SourceEdit.applySequence(content, edits); |
| expect(resultCode, r''' |
| import 'package:test/a.dart' as _prefix0; |
| import 'package:test/b.dart' as _prefix1; |
| |
| _prefix0.A1 a1; _prefix0.A2 a2; _prefix1.B b;'''); |
| } |
| |
| Future<void> test_writeType_preserveHiddenTypesA() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class B {} class C {} class D {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' hide C, B, A;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| var typeD = await _getType(aPath, 'D'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeD); |
| builder.write('();'); |
| builder.writeType(typeA); |
| builder.write('();'); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' hide C, B;D();A();")); |
| } |
| |
| Future<void> test_writeType_preserveHiddenTypesB() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class B {} class C {} class D {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' hide C, B, A;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeB = await _getType(aPath, 'B'); |
| var typeD = await _getType(aPath, 'D'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeD); |
| builder.write('();'); |
| builder.writeType(typeB); |
| builder.write('();'); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' hide C, A;D();B();")); |
| } |
| |
| Future<void> test_writeType_preserveHiddenTypesC() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class B {} class C {} class D {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' hide C, B, A;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeC = await _getType(aPath, 'C'); |
| var typeD = await _getType(aPath, 'D'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeD); |
| builder.write('();'); |
| builder.writeType(typeC); |
| builder.write('();'); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' hide B, A;D();C();")); |
| } |
| |
| Future<void> test_writeType_required_dynamic() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| var unit = (await resolveFile(path)).unit; |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| var typeProvider = unit.declaredElement!.library.typeProvider; |
| builder.writeType(typeProvider.dynamicType, required: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('var')); |
| } |
| |
| Future<void> test_writeType_required_notNull() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(typeA, required: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A')); |
| } |
| |
| Future<void> test_writeType_required_null() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(null, required: true); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('var')); |
| } |
| |
| Future<void> test_writeType_shownImport() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class Other {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' show Other;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show A, Other;A")); |
| } |
| |
| Future<void> test_writeType_shownImportUnsorted() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class B {} class C {} class D {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' show C, A;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeB = await _getType(aPath, 'B'); |
| var typeD = await _getType(aPath, 'D'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeD); |
| builder.write('();'); |
| builder.writeType(typeB); |
| builder.write('();'); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show C, A, B, D;D();B();")); |
| } |
| |
| Future<void> test_writeType_shownImportWithCombinatorsOrdering() async { |
| writeTestPackageAnalysisOptionsFile(lints: ['combinators_ordering']); |
| var aPath = convertPath('$testPackageRootPath/lib/test_a.dart'); |
| var aContent = 'class A {} class C {} class Other {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('$testPackageRootPath/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' show C, A;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'Other'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show A, C, Other;Other")); |
| } |
| |
| Future<void> test_writeType_shownImportWithConfiguration() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class Other {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' show Other if (a.b);"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show A, Other if (a.b);A")); |
| } |
| |
| Future<void> test_writeType_shownImportWithHide() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class Other {} class OtherOne {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = |
| "import 'package:test/test_a.dart' show OtherOne hide Other;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show A, OtherOne hide Other;A")); |
| } |
| |
| Future<void> test_writeType_shownImportWithHideSplit() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class Other {} class OtherOne {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = |
| "import 'package:test/test_a.dart' show OtherOne; import 'package:test/test_a.dart' hide Other;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show OtherOne; import 'package:test/test_a.dart' hide Other;A")); |
| } |
| |
| Future<void> test_writeType_shownImportWithMultipleCombinators() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class B {} class C {} class D {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = |
| "import 'package:test/test_a.dart' show B hide C show D hide A;"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(3)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' show B hide C show A, D;A")); |
| } |
| |
| Future<void> test_writeType_shownImportWithPrefix() async { |
| var aPath = convertPath('/home/test/lib/test_a.dart'); |
| var aContent = 'class A {} class Other {}'; |
| addSource(aPath, aContent); |
| var bPath = convertPath('/home/test/lib/test_b.dart'); |
| var bContent = "import 'package:test/test_a.dart' as pack show Other;\n"; |
| addSource(bPath, bContent); |
| |
| var builder = await newBuilder(); |
| var typeA = await _getType(aPath, 'A'); |
| await builder.addDartFileEdit(bPath, (builder) { |
| builder.addInsertion(bContent.length, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| var edited = SourceEdit.applySequence(bContent, edits); |
| expect( |
| edited, |
| equalsIgnoringWhitespace( |
| "import 'package:test/test_a.dart' as pack show Other; import 'package:test/test_a.dart'; A")); |
| } |
| |
| Future<void> test_writeType_simpleType() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(typeA); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A')); |
| } |
| |
| Future<void> test_writeType_typedef_typeArguments() async { |
| await _assertWriteType('F<int, String>', |
| declarations: 'typedef void F<T, U>(T t, U u);'); |
| } |
| |
| Future<void> test_writeType_void() async { |
| await _assertWriteType('void Function()'); |
| } |
| |
| Future<void> test_writeTypes_empty() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeTypes([]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, isEmpty); |
| } |
| |
| Future<void> test_writeTypes_noPrefix() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| DartType typeB = await _getType(path, 'B'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeTypes([typeA, typeB]); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('A, B')); |
| } |
| |
| Future<void> test_writeTypes_null() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {}'; |
| addSource(path, content); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeTypes(null); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, isEmpty); |
| } |
| |
| Future<void> test_writeTypes_prefix() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = 'class A {} class B {}'; |
| addSource(path, content); |
| DartType typeA = await _getType(path, 'A'); |
| DartType typeB = await _getType(path, 'B'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeTypes([typeA, typeB], prefix: 'implements '); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, equalsIgnoringWhitespace('implements A, B')); |
| } |
| |
| Future<void> _assertWriteType(String typeCode, {String? declarations}) async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| var content = '${declarations ?? ''}$typeCode v;'; |
| addSource(path, content); |
| |
| var f = await _getTopLevelAccessorElement(path, 'v'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(content.length - 1, (builder) { |
| builder.writeType(f.returnType); |
| }); |
| }); |
| var edit = getEdit(builder); |
| expect(edit.replacement, typeCode); |
| } |
| |
| Future<ClassElement> _getClassElement(String path, String name) async { |
| var result = (await resolveFile(path)).unit; |
| return result.declaredElement!.getClass(name)!; |
| } |
| |
| Future<PropertyAccessorElement> _getTopLevelAccessorElement( |
| String path, String name) async { |
| var result = (await resolveFile(path)).unit; |
| return result.declaredElement!.accessors.firstWhere((v) => v.name == name); |
| } |
| |
| Future<InterfaceType> _getType( |
| String path, |
| String name, { |
| List<DartType> typeArguments = const [], |
| }) async { |
| var classElement = await _getClassElement(path, name); |
| return classElement.instantiate( |
| typeArguments: typeArguments, |
| nullabilitySuffix: NullabilitySuffix.none, |
| ); |
| } |
| } |
| |
| @reflectiveTest |
| class DartFileEditBuilderImplTest extends AbstractContextTest |
| with DartChangeBuilderMixin { |
| Future<ResolvedUnitResult> resolveContent(String path, String content) async { |
| path = convertPath(path); |
| addSource(path, content); |
| return resolveFile(path); |
| } |
| |
| Future<void> test_convertFunctionFromSyncToAsync_closure() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, '''var f = () {}'''); |
| |
| var resolvedUnit = await resolveFile(path); |
| var findNode = FindNode(resolvedUnit.content, resolvedUnit.unit); |
| var body = findNode.functionBody('{}'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.convertFunctionFromSyncToAsync( |
| body: body, |
| typeSystem: resolvedUnit.typeSystem, |
| typeProvider: resolvedUnit.typeProvider, |
| ); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('async')); |
| } |
| |
| Future<void> test_convertFunctionFromSyncToAsync_topLevelFunction() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'String f() {}'); |
| |
| var resolvedUnit = await resolveFile(path); |
| var findNode = FindNode(resolvedUnit.content, resolvedUnit.unit); |
| var body = findNode.functionBody('{}'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.convertFunctionFromSyncToAsync( |
| body: body, |
| typeSystem: resolvedUnit.typeSystem, |
| typeProvider: resolvedUnit.typeProvider, |
| ); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(2)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('async')); |
| expect(edits[1].replacement, equalsIgnoringWhitespace('Future<String>')); |
| } |
| |
| Future<void> test_fileHeader_emptyFile() async { |
| var initialCode = ''' |
| '''; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.fileHeader = ''' |
| // File header |
| '''; |
| }); |
| |
| var edits = getEdits(builder); |
| var resultCode = SourceEdit.applySequence(initialCode, edits); |
| expect(resultCode, r''' |
| // File header |
| |
| '''); |
| } |
| |
| Future<void> test_fileHeader_withImports() async { |
| var initialCode = ''' |
| class C {} |
| '''; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.fileHeader = ''' |
| // File header |
| '''; |
| builder.importLibrary(Uri.parse('package:p/p.dart')); |
| }); |
| |
| var edits = getEdits(builder); |
| var resultCode = SourceEdit.applySequence(initialCode, edits); |
| expect(resultCode, r''' |
| // File header |
| |
| import 'package:p/p.dart'; |
| |
| class C {} |
| '''); |
| } |
| |
| Future<void> test_fileHeader_withoutImports() async { |
| var initialCode = ''' |
| class C {} |
| '''; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.fileHeader = ''' |
| // File header |
| '''; |
| }); |
| |
| var edits = getEdits(builder); |
| var resultCode = SourceEdit.applySequence(initialCode, edits); |
| expect(resultCode, r''' |
| // File header |
| |
| class C {} |
| '''); |
| } |
| |
| Future<void> test_format_hasEdits() async { |
| var initialCode = r''' |
| void functionBefore() { |
| 1 + 2; |
| } |
| |
| void foo() { |
| 1 + 2; |
| 42; |
| 3 + 4; |
| } |
| |
| void functionAfter() { |
| 1 + 2; |
| } |
| '''; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addInsertion(34, (builder) { |
| builder.writeln(' 3 + 4;'); |
| }); |
| builder.addSimpleReplacement(SourceRange(62, 2), '1 + 2 + 3'); |
| builder.addInsertion(112, (builder) { |
| builder.writeln(' 3 + 4;'); |
| }); |
| builder.format(SourceRange(48, 29)); |
| }); |
| |
| var edits = getEdits(builder); |
| var resultCode = SourceEdit.applySequence(initialCode, edits); |
| expect(resultCode, r''' |
| void functionBefore() { |
| 1 + 2; |
| 3 + 4; |
| } |
| |
| void foo() { |
| 1 + 2; |
| 1 + 2 + 3; |
| 3 + 4; |
| } |
| |
| void functionAfter() { |
| 1 + 2; |
| 3 + 4; |
| } |
| '''); |
| } |
| |
| Future<void> test_format_noEdits() async { |
| var initialCode = r''' |
| void functionBefore() { |
| 1 + 2; |
| } |
| |
| void foo() { |
| 1 + 2; |
| 3; |
| 4 + 5; |
| } |
| |
| void functionAfter() { |
| 1 + 2; |
| } |
| '''; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.format(SourceRange(37, 39)); |
| }); |
| |
| var edits = getEdits(builder); |
| var resultCode = SourceEdit.applySequence(initialCode, edits); |
| expect(resultCode, r''' |
| void functionBefore() { |
| 1 + 2; |
| } |
| |
| void foo() { |
| 1 + 2; |
| 3; |
| 4 + 5; |
| } |
| |
| void functionAfter() { |
| 1 + 2; |
| } |
| '''); |
| } |
| |
| Future<void> test_importElementLibrary_libElement() async { |
| var resolvedUnit = await resolveContent('/home/test/lib/test.dart', ''); |
| |
| var resolvedLibUnit = |
| await resolveContent('/home/test/lib/a.dart', 'class A {}'); |
| |
| var findNode = FindNode(resolvedLibUnit.content, resolvedLibUnit.unit); |
| var classElement = findNode.classDeclaration('A').declaredElement!; |
| var cache = <Element, LibraryElement?>{}; |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(resolvedUnit.path, (builder) async { |
| var builderImpl = builder as DartFileEditBuilderImpl; |
| await builderImpl.importElementLibrary(classElement, resultCache: cache); |
| }); |
| |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect(edits[0].replacement, |
| equalsIgnoringWhitespace("import 'package:test/a.dart';\n")); |
| expect(cache[classElement], resolvedLibUnit.libraryElement); |
| } |
| |
| Future<void> test_importElementLibrary_sdkElement() async { |
| var resolvedUnit = await resolveContent('/home/test/lib/test.dart', ''); |
| |
| var futureOrElement = resolvedUnit.typeProvider.futureOrElement; |
| var cache = <Element, LibraryElement?>{}; |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(resolvedUnit.path, (builder) async { |
| var builderImpl = builder as DartFileEditBuilderImpl; |
| await builderImpl.importElementLibrary(futureOrElement, |
| resultCache: cache); |
| }); |
| |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect( |
| edits[0].replacement, equalsIgnoringWhitespace("import 'dart:async';")); |
| expect(cache[futureOrElement], futureOrElement.library); |
| } |
| |
| Future<void> test_importElementLibrary_srcElement() async { |
| var resolvedUnit = await resolveContent('/home/test/lib/test.dart', ''); |
| |
| var resolvedSrcUnit = |
| await resolveContent('/home/test/lib/src/a.dart', 'class A {}'); |
| |
| var resolvedExportUnit = |
| await resolveContent('/home/test/lib/a.dart', "export 'src/a.dart'"); |
| |
| var findNode = FindNode(resolvedSrcUnit.content, resolvedSrcUnit.unit); |
| var classElement = findNode.classDeclaration('A').declaredElement!; |
| var cache = <Element, LibraryElement?>{}; |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(resolvedUnit.path, (builder) async { |
| var builderImpl = builder as DartFileEditBuilderImpl; |
| await builderImpl.importElementLibrary(classElement, resultCache: cache); |
| }); |
| |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect(edits[0].replacement, |
| equalsIgnoringWhitespace("import 'package:test/a.dart';\n")); |
| expect(cache[classElement], resolvedExportUnit.libraryElement); |
| } |
| |
| Future<void> test_importElementLibrary_usesCache() async { |
| var resolvedUnit = await resolveContent('/home/test/lib/test.dart', ''); |
| |
| // Create a fake file to put into the cache to verify it's being used. |
| var resolvedFakeUnit = await resolveContent('/home/test/lib/fake.dart', ''); |
| |
| var futureOrElement = resolvedUnit.typeProvider.futureOrElement; |
| var cache = <Element, LibraryElement?>{ |
| futureOrElement: resolvedFakeUnit.libraryElement, |
| }; |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(resolvedUnit.path, (builder) async { |
| var builderImpl = builder as DartFileEditBuilderImpl; |
| await builderImpl.importElementLibrary(futureOrElement, |
| resultCache: cache); |
| }); |
| |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect(edits[0].replacement, |
| equalsIgnoringWhitespace("import 'package:test/fake.dart';")); |
| expect(cache[futureOrElement], resolvedFakeUnit.libraryElement); |
| } |
| |
| /// Test that importing elements where the library is already imported |
| /// (without a show/hide combinator) produces no additional edits. |
| Future<void> test_importElementLibrary_useShow_existingImport() async { |
| var content = ''' |
| import 'package:test/a.dart'; |
| '''; |
| var otherContent = ''' |
| class A {} |
| class B {} |
| class C {} |
| '''; |
| var otherUnit = await resolveContent('/home/test/lib/a.dart', otherContent); |
| var unit = await resolveContent('/home/test/lib/test.dart', content); |
| |
| var edits = await _getClassImportEdits( |
| destinationUnit: unit, |
| importedUnit: otherUnit, |
| classNames: {'A', 'B'}, |
| useShow: true, |
| ); |
| expect(edits, isEmpty); |
| } |
| |
| /// Test that importing elements where the library is already imported but |
| /// hides the element causes the element to be shown. |
| Future<void> |
| test_importElementLibrary_useShow_existingImport_hidesElement() async { |
| var content = ''' |
| import 'package:test/a.dart' hide A; |
| '''; |
| var otherContent = ''' |
| class A {} |
| class B {} |
| class C {} |
| '''; |
| var otherUnit = await resolveContent('/home/test/lib/a.dart', otherContent); |
| var unit = await resolveContent('/home/test/lib/test.dart', content); |
| |
| var edits = await _getClassImportEdits( |
| destinationUnit: unit, |
| importedUnit: otherUnit, |
| classNames: {'A', 'B'}, |
| useShow: true, |
| ); |
| var resultContent = SourceEdit.applySequence(content, edits); |
| expect( |
| resultContent, |
| equals( |
| ''' |
| import 'package:test/a.dart'; |
| ''', |
| )); |
| } |
| |
| /// Test that importing elements where the library is already imported and |
| /// already shows the elements produces no edits. |
| Future<void> |
| test_importElementLibrary_useShow_existingImport_showsElement() async { |
| var content = ''' |
| import 'package:test/a.dart' show A, B, C; |
| '''; |
| var otherContent = ''' |
| class A {} |
| class B {} |
| class C {} |
| '''; |
| var otherUnit = await resolveContent('/home/test/lib/a.dart', otherContent); |
| var unit = await resolveContent('/home/test/lib/test.dart', content); |
| |
| var edits = await _getClassImportEdits( |
| destinationUnit: unit, |
| importedUnit: otherUnit, |
| classNames: {'A', 'B'}, |
| useShow: true, |
| ); |
| expect(edits, isEmpty); |
| } |
| |
| /// Test that importing elements where the library is already imported but it |
| /// only shows other elements results in the element being shown. |
| Future<void> |
| test_importElementLibrary_useShow_existingImport_showsOthers() async { |
| var content = ''' |
| import 'package:test/a.dart' show C; |
| '''; |
| var otherContent = ''' |
| class A {} |
| class B {} |
| class C {} |
| '''; |
| var otherUnit = await resolveContent('/home/test/lib/a.dart', otherContent); |
| var unit = await resolveContent('/home/test/lib/test.dart', content); |
| |
| var edits = await _getClassImportEdits( |
| destinationUnit: unit, |
| importedUnit: otherUnit, |
| classNames: {'A', 'B'}, |
| useShow: true, |
| ); |
| var resultContent = SourceEdit.applySequence(content, edits); |
| expect( |
| resultContent, |
| equals( |
| ''' |
| import 'package:test/a.dart' show A, B, C; |
| ''', |
| )); |
| } |
| |
| /// Test that that we can add a new import elements using 'show'. |
| Future<void> test_importElementLibrary_useShow_newImport() async { |
| var otherUnit = await resolveContent( |
| '/home/test/lib/a.dart', |
| ''' |
| class A {} |
| class B {} |
| ''', |
| ); |
| var unit = await resolveContent( |
| '/home/test/lib/test.dart', |
| '', |
| ); |
| |
| var edits = await _getClassImportEdits( |
| destinationUnit: unit, |
| importedUnit: otherUnit, |
| classNames: {'A', 'B'}, |
| useShow: true, |
| ); |
| expect(edits, hasLength(1)); |
| expect( |
| edits[0].replacement, |
| equals( |
| '''import 'package:test/a.dart' show A, B; |
| ''', |
| )); |
| } |
| |
| Future<void> test_multipleEdits_concurrently() async { |
| var initialCode = '00'; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| var future = Future.wait([ |
| builder.addDartFileEdit(path, (builder) { |
| builder.addSimpleInsertion(0, '11'); |
| }), |
| builder.addDartFileEdit(path, (builder) { |
| builder.addSimpleInsertion(2, '22'); |
| }), |
| ]); |
| |
| expect(future, throwsA(TypeMatcher<StateError>())); |
| } |
| |
| Future<void> test_multipleEdits_sequentially() async { |
| var initialCode = '00'; |
| var path = convertPath('/home/test/lib/test.dart'); |
| newFile(path, initialCode); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addSimpleInsertion(0, '11'); |
| }); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.addSimpleInsertion(2, '22'); |
| }); |
| |
| var edits = getEdits(builder); |
| var resultCode = SourceEdit.applySequence(initialCode, edits); |
| expect(resultCode, '110022'); |
| } |
| |
| Future<void> test_replaceTypeWithFuture() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, 'String f() {}'); |
| |
| var resolvedUnit = await resolveFile(path); |
| var findNode = FindNode(resolvedUnit.content, resolvedUnit.unit); |
| var type = findNode.typeAnnotation('String'); |
| |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(path, (builder) { |
| builder.replaceTypeWithFuture( |
| typeAnnotation: type, |
| typeProvider: resolvedUnit.typeProvider, |
| typeSystem: resolvedUnit.typeSystem, |
| ); |
| }); |
| var edits = getEdits(builder); |
| expect(edits, hasLength(1)); |
| expect(edits[0].replacement, equalsIgnoringWhitespace('Future<String>')); |
| } |
| |
| /// Computes edits to import the class [className] from [importedUnit] into |
| /// [destinationUnit]. |
| /// |
| /// If [useShow] is set, will try to add a show combinator for this class. |
| Future<List<SourceEdit>> _getClassImportEdits({ |
| required ResolvedUnitResult destinationUnit, |
| required ResolvedUnitResult importedUnit, |
| required Set<String> classNames, |
| bool useShow = false, |
| }) async { |
| var findNode = FindNode(importedUnit.content, importedUnit.unit); |
| var builder = await newBuilder(); |
| await builder.addDartFileEdit(destinationUnit.path, (builder) async { |
| var builderImpl = builder as DartFileEditBuilderImpl; |
| for (var className in classNames) { |
| var classElement = |
| findNode.classDeclaration(className).declaredElement!; |
| await builderImpl.importElementLibrary(classElement, useShow: useShow); |
| } |
| }); |
| |
| return getEdits(builder); |
| } |
| } |
| |
| @reflectiveTest |
| class DartLinkedEditBuilderImplTest extends AbstractContextTest { |
| Future<void> test_addSuperTypesAsSuggestions_noneSuffix() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''' |
| class A {} |
| class B extends A {} |
| class C extends B {} |
| '''); |
| var unit = (await resolveFile(path)).unit; |
| var classC = unit.declarations[2] as ClassDeclaration; |
| var builder = DartLinkedEditBuilderImpl(MockDartEditBuilderImpl()); |
| builder.addSuperTypesAsSuggestions( |
| classC.declaredElement?.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.none, |
| ), |
| ); |
| var suggestions = builder.suggestions; |
| expect(suggestions, hasLength(4)); |
| expect(suggestions.map((s) => s.value), |
| unorderedEquals(['Object', 'A', 'B', 'C'])); |
| } |
| |
| Future<void> test_addSuperTypesAsSuggestions_questionSuffix() async { |
| var path = convertPath('/home/test/lib/test.dart'); |
| addSource(path, ''' |
| class A {} |
| class B extends A {} |
| class C extends B {} |
| '''); |
| var unit = (await resolveFile(path)).unit; |
| var classC = unit.declarations[2] as ClassDeclaration; |
| var builder = DartLinkedEditBuilderImpl(MockDartEditBuilderImpl()); |
| builder.addSuperTypesAsSuggestions( |
| classC.declaredElement?.instantiate( |
| typeArguments: [], |
| nullabilitySuffix: NullabilitySuffix.question, |
| ), |
| ); |
| var suggestions = builder.suggestions; |
| expect(suggestions, hasLength(4)); |
| expect(suggestions.map((s) => s.value), |
| unorderedEquals(['Object?', 'A?', 'B?', 'C?'])); |
| } |
| } |
| |
| @reflectiveTest |
| class ImportLibraryTest extends AbstractContextTest |
| with DartChangeBuilderMixin { |
| Future<void> test_dart_afterDart_last() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'dart:aaa'; |
| |
| class A {} |
| ''', |
| uriList: ['dart:bbb'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import 'dart:bbb'; |
| |
| class A {} |
| ''', |
| ); |
| } |
| |
| Future<void> test_dart_beforeDart() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'dart:aaa'; |
| import 'dart:ccc'; |
| ''', |
| uriList: ['dart:bbb'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import 'dart:bbb'; |
| import 'dart:ccc'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_dart_beforeDart_first() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'dart:bbb'; |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import 'dart:bbb'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_dart_beforeExport() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| export 'dart:aaa'; |
| ''', |
| uriList: ['dart:bbb'], |
| expectedCode: ''' |
| import 'dart:bbb'; |
| |
| export 'dart:aaa'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_dart_beforePackage() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'package:foo/foo.dart'; |
| ''', |
| uriList: ['dart:async'], |
| expectedCode: ''' |
| import 'dart:async'; |
| |
| import 'package:foo/foo.dart'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_default_quote() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_directive_adjacent_strings() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'dart:' "async"; |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import 'dart:' "async"; |
| ''', |
| ); |
| } |
| |
| Future<void> test_directive_common_double_quote() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import "dart:async"; |
| import "dart:math"; |
| import 'dart:bbb'; |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import "dart:aaa"; |
| import "dart:async"; |
| import "dart:math"; |
| import 'dart:bbb'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_directive_common_single_quote() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import "dart:math"; |
| import 'dart:bbb'; |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import "dart:math"; |
| import 'dart:bbb'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_directive_double_quote() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import "dart:bbb"; |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import "dart:aaa"; |
| import "dart:bbb"; |
| ''', |
| ); |
| } |
| |
| Future<void> test_directive_single_quote() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'dart:bbb'; |
| ''', |
| uriList: ['dart:aaa'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import 'dart:bbb'; |
| ''', |
| ); |
| } |
| |
| Future<void> test_multiple_dart_then_package() async { |
| await _assertImportLibrary( |
| initialCode: ''' |
| import 'dart:aaa'; |
| import 'dart:ccc'; |
| |
| import 'package:aaa/aaa.dart'; |
| import 'package:ccc/ccc.dart'; |
| ''', |
| uriList: ['dart:bbb', 'package:bbb/bbb.dart'], |
| expectedCode: ''' |
| import 'dart:aaa'; |
| import 'dart:bbb'; |
| import 'dart:ccc'; |
| |
| import 'package:aaa/aaa.dart'; |
| import 'package:bbb/bbb.dart'; |
|