Index: pkg/analysis_server/lib/src/services/correction/fix_internal.dart |
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart |
index e4fd8fa16c25aaa144a6c985606d8927e8cd85a5..7b0f8a179eed9b414a9379e03523e84e1627e82f 100644 |
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart |
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart |
@@ -8,15 +8,11 @@ import 'dart:core'; |
import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; |
import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; |
-import 'package:analysis_server/src/protocol_server.dart' |
- show doSourceChange_addElementEdit, doSourceChange_addSourceEdit; |
import 'package:analysis_server/src/services/completion/dart/utilities.dart'; |
import 'package:analysis_server/src/services/correction/fix.dart'; |
import 'package:analysis_server/src/services/correction/flutter_util.dart'; |
import 'package:analysis_server/src/services/correction/levenshtein.dart'; |
-import 'package:analysis_server/src/services/correction/name_suggestion.dart'; |
import 'package:analysis_server/src/services/correction/namespace.dart'; |
-import 'package:analysis_server/src/services/correction/source_buffer.dart'; |
import 'package:analysis_server/src/services/correction/strings.dart'; |
import 'package:analysis_server/src/services/correction/util.dart'; |
import 'package:analysis_server/src/services/search/hierarchy.dart'; |
@@ -118,12 +114,6 @@ class FixProcessor { |
final List<Fix> fixes = <Fix>[]; |
- SourceChange change = new SourceChange('<message>'); |
- final LinkedHashMap<String, LinkedEditGroup> linkedPositionGroups = |
- new LinkedHashMap<String, LinkedEditGroup>(); |
- Position exitPosition = null; |
- Set<Source> librariesToImport = new Set<Source>(); |
- |
CorrectionUtils utils; |
int errorOffset; |
int errorLength; |
@@ -208,7 +198,7 @@ class FixProcessor { |
} |
if (errorCode == |
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) { |
- _addFix_replaceWithConstInstanceCreation(); |
+ await _addFix_replaceWithConstInstanceCreation(); |
} |
if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT || |
errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) { |
@@ -225,7 +215,7 @@ class FixProcessor { |
} else { |
await _addFix_importLibrary_withType(); |
await _addFix_createClass(); |
- _addFix_undefinedClass_useSimilar(); |
+ await _addFix_undefinedClass_useSimilar(); |
} |
} |
} |
@@ -243,17 +233,17 @@ class FixProcessor { |
await _addFix_createConstructorSuperExplicit(); |
} |
if (errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST) { |
- _addFix_createImportUri(); |
- _addFix_createPartUri(); |
+ await _addFix_createImportUri(); |
+ await _addFix_createPartUri(); |
} |
if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) { |
await _addFix_canBeNullAfterNullAware(); |
} |
if (errorCode == HintCode.DEAD_CODE) { |
- _addFix_removeDeadCode(); |
+ await _addFix_removeDeadCode(); |
} |
if (errorCode == HintCode.DIVISION_OPTIMIZATION) { |
- _addFix_useEffectiveIntegerDivision(); |
+ await _addFix_useEffectiveIntegerDivision(); |
} |
if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) { |
await _addFix_isNotNull(); |
@@ -262,34 +252,34 @@ class FixProcessor { |
await _addFix_isNull(); |
} |
if (errorCode == HintCode.UNDEFINED_GETTER) { |
- _addFix_undefinedClassAccessor_useSimilar(); |
+ await _addFix_undefinedClassAccessor_useSimilar(); |
await _addFix_createField(); |
await _addFix_createGetter(); |
} |
if (errorCode == HintCode.UNDEFINED_SETTER) { |
- _addFix_undefinedClassAccessor_useSimilar(); |
+ await _addFix_undefinedClassAccessor_useSimilar(); |
await _addFix_createField(); |
} |
if (errorCode == HintCode.UNNECESSARY_CAST) { |
- _addFix_removeUnnecessaryCast(); |
+ await _addFix_removeUnnecessaryCast(); |
} |
if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) { |
- _addFix_removeUnusedCatchClause(); |
+ await _addFix_removeUnusedCatchClause(); |
} |
if (errorCode == HintCode.UNUSED_CATCH_STACK) { |
- _addFix_removeUnusedCatchStack(); |
+ await _addFix_removeUnusedCatchStack(); |
} |
if (errorCode == HintCode.UNUSED_IMPORT) { |
- _addFix_removeUnusedImport(); |
+ await _addFix_removeUnusedImport(); |
} |
if (errorCode == ParserErrorCode.EXPECTED_TOKEN) { |
await _addFix_insertSemicolon(); |
} |
if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) { |
- _addFix_removeParameters_inGetterDeclaration(); |
+ await _addFix_removeParameters_inGetterDeclaration(); |
} |
if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) { |
- _addFix_replaceVarWithDynamic(); |
+ await _addFix_replaceVarWithDynamic(); |
} |
if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) { |
await _addFix_makeFieldNotFinal(); |
@@ -338,7 +328,7 @@ class FixProcessor { |
errorCode == StaticWarningCode.UNDEFINED_CLASS) { |
await _addFix_importLibrary_withType(); |
await _addFix_createClass(); |
- _addFix_undefinedClass_useSimilar(); |
+ await _addFix_undefinedClass_useSimilar(); |
} |
if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) { |
await _addFix_createConstructor_forUninitializedFinalFields(); |
@@ -347,14 +337,14 @@ class FixProcessor { |
errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 || |
errorCode == |
StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) { |
- _addFix_updateConstructor_forUninitializedFinalFields(); |
+ await _addFix_updateConstructor_forUninitializedFinalFields(); |
} |
if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) { |
- _addFix_undefinedClassAccessor_useSimilar(); |
+ await _addFix_undefinedClassAccessor_useSimilar(); |
await _addFix_createClass(); |
await _addFix_createField(); |
await _addFix_createGetter(); |
- _addFix_createFunction_forFunctionType(); |
+ await _addFix_createFunction_forFunctionType(); |
await _addFix_importLibrary_withType(); |
await _addFix_importLibrary_withTopLevelVariable(); |
await _addFix_createLocalVariable(); |
@@ -363,14 +353,14 @@ class FixProcessor { |
await _addFix_illegalAsyncReturnType(); |
} |
if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) { |
- _addFix_useStaticAccess_method(); |
- _addFix_useStaticAccess_property(); |
+ await _addFix_useStaticAccess_method(); |
+ await _addFix_useStaticAccess_property(); |
} |
if (errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT) { |
await _addFix_changeTypeAnnotation(); |
} |
if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) { |
- _addFix_removeParentheses_inGetterInvocation(); |
+ await _addFix_removeParentheses_inGetterInvocation(); |
} |
if (errorCode == StaticTypeWarningCode.NON_BOOL_CONDITION) { |
await _addFix_nonBoolCondition_addNotNull(); |
@@ -381,71 +371,71 @@ class FixProcessor { |
} |
if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) { |
await _addFix_importLibrary_withFunction(); |
- _addFix_undefinedFunction_useSimilar(); |
- _addFix_undefinedFunction_create(); |
+ await _addFix_undefinedFunction_useSimilar(); |
+ await _addFix_undefinedFunction_create(); |
} |
if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) { |
- _addFix_undefinedClassAccessor_useSimilar(); |
+ await _addFix_undefinedClassAccessor_useSimilar(); |
await _addFix_createField(); |
await _addFix_createGetter(); |
- _addFix_createFunction_forFunctionType(); |
+ await _addFix_createFunction_forFunctionType(); |
} |
if (errorCode == HintCode.UNDEFINED_METHOD || |
errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) { |
await _addFix_importLibrary_withFunction(); |
- _addFix_undefinedMethod_useSimilar(); |
- _addFix_undefinedMethod_create(); |
- _addFix_undefinedFunction_create(); |
+ await _addFix_undefinedMethod_useSimilar(); |
+ await _addFix_undefinedMethod_create(); |
+ await _addFix_undefinedFunction_create(); |
} |
if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) { |
- _addFix_undefinedClassAccessor_useSimilar(); |
+ await _addFix_undefinedClassAccessor_useSimilar(); |
await _addFix_createField(); |
} |
if (errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER || |
errorCode == StaticWarningCode.UNDEFINED_NAMED_PARAMETER) { |
- _addFix_convertFlutterChild(); |
- _addFix_convertFlutterChildren(); |
+ await _addFix_convertFlutterChild(); |
+ await _addFix_convertFlutterChildren(); |
} |
// lints |
if (errorCode is LintCode) { |
if (errorCode.name == LintNames.annotate_overrides) { |
- _addLintFixAddOverrideAnnotation(); |
+ await _addFix_addOverrideAnnotation(); |
} |
if (errorCode.name == LintNames.avoid_annotating_with_dynamic) { |
- _addFix_removeTypeName(); |
+ await _addFix_removeTypeName(); |
} |
if (errorCode.name == LintNames.avoid_init_to_null) { |
- _addFix_removeInitializer(); |
+ await _addFix_removeInitializer(); |
} |
if (errorCode.name == LintNames.avoid_return_types_on_setters) { |
- _addFix_removeTypeName(); |
+ await _addFix_removeTypeName(); |
} |
if (errorCode.name == LintNames.avoid_types_on_closure_parameters) { |
- _addFix_replaceWithIdentifier(); |
+ await _addFix_replaceWithIdentifier(); |
} |
if (errorCode.name == LintNames.await_only_futures) { |
- _addFix_removeAwait(); |
+ await _addFix_removeAwait(); |
} |
if (errorCode.name == LintNames.empty_statements) { |
- _addFix_removeEmptyStatement(); |
+ await _addFix_removeEmptyStatement(); |
} |
if (errorCode.name == LintNames.prefer_collection_literals) { |
- _addFix_replaceWithLiteral(); |
+ await _addFix_replaceWithLiteral(); |
} |
if (errorCode.name == LintNames.prefer_conditional_assignment) { |
- _addFix_replaceWithConditionalAssignment(); |
+ await _addFix_replaceWithConditionalAssignment(); |
} |
if (errorCode.name == LintNames.unnecessary_brace_in_string_interp) { |
- _addLintRemoveInterpolationBraces(); |
+ await _addFix_removeInterpolationBraces(); |
} |
if (errorCode.name == LintNames.unnecessary_lambdas) { |
- _addFix_replaceWithTearOff(); |
+ await _addFix_replaceWithTearOff(); |
} |
if (errorCode.name == LintNames.unnecessary_override) { |
- _addFix_removeMethodDeclaration(); |
+ await _addFix_removeMethodDeclaration(); |
} |
if (errorCode.name == LintNames.unnecessary_this) { |
- _addFix_removeThisExpression(); |
+ await _addFix_removeThisExpression(); |
} |
} |
// done |
@@ -453,41 +443,6 @@ class FixProcessor { |
} |
/** |
- * Adds a new [SourceEdit] to [change]. |
- */ |
- void _addEdit(Element target, SourceEdit edit) { |
- if (target == null) { |
- target = unitElement; |
- } |
- Source source = target.source; |
- if (source.isInSystemLibrary) { |
- return; |
- } |
- doSourceChange_addElementEdit(change, target, edit); |
- } |
- |
- void _addFix(FixKind kind, List args, {bool importsOnly: false}) { |
- if (change.edits.isEmpty && !importsOnly) { |
- return; |
- } |
- // configure Change |
- change.message = formatList(kind.message, args); |
- linkedPositionGroups.values |
- .forEach((group) => change.addLinkedEditGroup(group)); |
- change.selection = exitPosition; |
- // add imports |
- addLibraryImports(change, unitLibraryElement, librariesToImport); |
- // add Fix |
- Fix fix = new Fix(kind, change); |
- fixes.add(fix); |
- // clear |
- change = new SourceChange('<message>'); |
- linkedPositionGroups.clear(); |
- exitPosition = null; |
- librariesToImport.clear(); |
- } |
- |
- /** |
* Returns `true` if the `async` proposal was added. |
*/ |
Future<Null> _addFix_addAsync() async { |
@@ -679,6 +634,32 @@ class FixProcessor { |
} |
} |
+ Future<Null> _addFix_addOverrideAnnotation() async { |
+ ClassMember member = node.getAncestor((n) => n is ClassMember); |
+ if (member == null) { |
+ return; |
+ } |
+ |
+ //TODO(pq): migrate annotation edit building to change_builder |
+ |
+ // Handle doc comments. |
+ Token token = member.beginToken; |
+ if (token is CommentToken) { |
+ token = (token as CommentToken).parent; |
+ } |
+ |
+ Position exitPosition = new Position(file, token.offset - 1); |
+ String indent = utils.getIndent(1); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
scheglov
2017/06/07 21:27:32
1. This code: new DartChangeBuilder(), then "addFi
|
+ (DartFileEditBuilder builder) { |
scheglov
2017/06/07 21:27:32
3. Consider removing DartFileEditBuilder annotatio
|
+ builder.addSimpleReplacement( |
+ range.startLength(token, 0), '@override$eol$indent'); |
+ }); |
+ changeBuilder.setSelection(exitPosition); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.LINT_ADD_OVERRIDE); |
+ } |
+ |
Future<Null> _addFix_boolInsteadOfBoolean() async { |
DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
await changeBuilder.addFileEdit(file, fileStamp, |
@@ -723,55 +704,64 @@ class FixProcessor { |
Expression initializer = coveredNode; |
DartType newType = initializer.bestType; |
if (newType is InterfaceType || newType is FunctionType) { |
- String newTypeSource = |
- utils.getTypeSource(newType, librariesToImport); |
DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
await changeBuilder.addFileEdit(file, fileStamp, |
(DartFileEditBuilder builder) { |
- builder.addSimpleReplacement(range.node(typeNode), newTypeSource); |
+ builder.addReplacement(range.node(typeNode), |
+ (DartEditBuilder builder) { |
+ builder.writeType(newType); |
+ }); |
}); |
_addFixFromBuilder( |
- changeBuilder, DartFixKind.CHANGE_TYPE_ANNOTATION, |
- args: [resolutionMap.typeForTypeName(typeNode), newTypeSource]); |
+ changeBuilder, DartFixKind.CHANGE_TYPE_ANNOTATION, args: [ |
+ resolutionMap.typeForTypeName(typeNode), |
+ newType.displayName |
+ ]); |
} |
} |
} |
} |
} |
- void _addFix_convertFlutterChild() { |
+ Future<Null> _addFix_convertFlutterChild() async { |
NamedExpression namedExp = findFlutterNamedExpression(node, 'child'); |
if (namedExp == null) { |
return; |
} |
InstanceCreationExpression childArg = getChildWidget(namedExp, false); |
if (childArg != null) { |
- convertFlutterChildToChildren( |
- childArg, |
- namedExp, |
- eol, |
- utils.getNodeText, |
- utils.getLinePrefix, |
- utils.getIndent, |
- utils.getText, |
- _addInsertEdit, |
- _addRemoveEdit, |
- _addReplaceEdit, |
- range.node); |
- _addFix(DartFixKind.CONVERT_FLUTTER_CHILD, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ convertFlutterChildToChildren2( |
+ builder, |
+ childArg, |
+ namedExp, |
+ eol, |
+ utils.getNodeText, |
+ utils.getLinePrefix, |
+ utils.getIndent, |
+ utils.getText, |
+ range.node); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD); |
return; |
} |
ListLiteral listArg = getChildList(namedExp); |
if (listArg != null) { |
- _addInsertEdit(namedExp.offset + 'child'.length, 'ren'); |
- if (listArg.typeArguments == null) { |
- _addInsertEdit(listArg.offset, '<Widget>'); |
- } |
- _addFix(DartFixKind.CONVERT_FLUTTER_CHILD, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleInsertion(namedExp.offset + 'child'.length, 'ren'); |
+ if (listArg.typeArguments == null) { |
+ builder.addSimpleInsertion(listArg.offset, '<Widget>'); |
+ } |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD); |
} |
} |
- void _addFix_convertFlutterChildren() { |
+ Future<Null> _addFix_convertFlutterChildren() async { |
// TODO(messick) Implement _addFix_convertFlutterChildren() |
} |
@@ -1039,7 +1029,7 @@ class FixProcessor { |
builder.write('super'); |
if (!isEmpty(constructorName)) { |
builder.write('.'); |
- builder.write(constructorName); |
+ builder.addSimpleLinkedEdit('NAME', constructorName); |
} |
// add arguments |
builder.write('('); |
@@ -1082,30 +1072,9 @@ class FixProcessor { |
continue; |
} |
// prepare parameters and arguments |
- SourceBuilder parametersBuffer = new SourceBuilder.buffer(); |
- SourceBuilder argumentsBuffer = new SourceBuilder.buffer(); |
- bool firstParameter = true; |
- for (ParameterElement parameter in superConstructor.parameters) { |
- // skip non-required parameters |
- if (parameter.parameterKind != ParameterKind.REQUIRED) { |
- break; |
- } |
- // comma |
- if (firstParameter) { |
- firstParameter = false; |
- } else { |
- parametersBuffer.append(', '); |
- argumentsBuffer.append(', '); |
- } |
- // name |
- String parameterName = parameter.displayName; |
- if (parameterName.length > 1 && parameterName.startsWith('_')) { |
- parameterName = parameterName.substring(1); |
- } |
- // parameter & argument |
- _appendParameterSource(parametersBuffer, parameter.type, parameterName); |
- argumentsBuffer.append(parameterName); |
- } |
+ Iterable<ParameterElement> requiredParameters = |
+ superConstructor.parameters.where( |
+ (parameter) => parameter.parameterKind == ParameterKind.REQUIRED); |
// add proposal |
ClassMemberLocation targetLocation = |
utils.prepareNewConstructorLocation(targetClassNode); |
@@ -1114,24 +1083,43 @@ class FixProcessor { |
await changeBuilder.addFileEdit(file, fileStamp, |
(DartFileEditBuilder builder) { |
builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { |
+ void writeParameters(bool includeType) { |
+ bool firstParameter = true; |
+ for (ParameterElement parameter in requiredParameters) { |
+ if (firstParameter) { |
+ firstParameter = false; |
+ } else { |
+ builder.write(', '); |
+ } |
+ String parameterName = parameter.displayName; |
+ if (parameterName.length > 1 && parameterName.startsWith('_')) { |
+ parameterName = parameterName.substring(1); |
+ } |
+ if (includeType && builder.writeType(parameter.type)) { |
+ builder.write(' '); |
+ } |
+ builder.write(parameterName); |
+ } |
+ } |
+ |
builder.write(targetLocation.prefix); |
builder.write(targetClassName); |
if (!constructorName.isEmpty) { |
- builder.addSimpleLinkedEdit('NAME', '.$constructorName'); |
+ builder.write('.'); |
+ builder.addSimpleLinkedEdit('NAME', constructorName); |
} |
builder.write('('); |
- builder.write(parametersBuffer.toString()); |
+ writeParameters(true); |
builder.write(') : super'); |
if (!constructorName.isEmpty) { |
builder.write('.'); |
- builder.write(constructorName); |
+ builder.addSimpleLinkedEdit('NAME', constructorName); |
} |
builder.write('('); |
- builder.write(argumentsBuffer.toString()); |
+ writeParameters(false); |
builder.write(');'); |
builder.write(targetLocation.suffix); |
}); |
- builder.importLibraries(librariesToImport); |
}); |
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_SUPER, |
args: [proposalName]); |
@@ -1214,7 +1202,7 @@ class FixProcessor { |
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FIELD, args: [name]); |
} |
- void _addFix_createFunction_forFunctionType() { |
+ Future<Null> _addFix_createFunction_forFunctionType() async { |
if (node is SimpleIdentifier) { |
SimpleIdentifier nameNode = node as SimpleIdentifier; |
// prepare argument expression (to get parameter) |
@@ -1255,9 +1243,9 @@ class FixProcessor { |
FunctionType functionType = parameterType as FunctionType; |
// add proposal |
if (targetElement != null) { |
- _addProposal_createFunction_method(targetElement, functionType); |
+ await _addProposal_createFunction_method(targetElement, functionType); |
} else { |
- _addProposal_createFunction_function(functionType); |
+ await _addProposal_createFunction_function(functionType); |
} |
} |
} |
@@ -1338,7 +1326,7 @@ class FixProcessor { |
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_GETTER, args: [name]); |
} |
- void _addFix_createImportUri() { |
+ Future<Null> _addFix_createImportUri() async { |
// TODO(brianwilkerson) Generalize this to allow other valid string literals. |
// TODO(brianwilkerson) Support the case where the node's parent is a Configuration. |
if (node is SimpleStringLiteral && node.parent is ImportDirective) { |
@@ -1348,9 +1336,13 @@ class FixProcessor { |
String file = source.fullName; |
if (isAbsolute(file) && AnalysisEngine.isDartFileName(file)) { |
String libName = _computeLibraryName(file); |
- SourceEdit edit = new SourceEdit(0, 0, 'library $libName;$eol$eol'); |
- doSourceChange_addSourceEdit(change, source, edit, isNewFile: true); |
- _addFix(DartFixKind.CREATE_FILE, [source.shortName]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(source.fullName, -1, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleInsertion(0, 'library $libName;$eol$eol'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE, |
+ args: [source.shortName]); |
} |
} |
} |
@@ -1575,16 +1567,21 @@ class FixProcessor { |
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_NO_SUCH_METHOD); |
} |
- void _addFix_createPartUri() { |
+ Future<Null> _addFix_createPartUri() async { |
// TODO(brianwilkerson) Generalize this to allow other valid string literals. |
if (node is SimpleStringLiteral && node.parent is PartDirective) { |
PartDirective partDirective = node.parent; |
Source source = partDirective.uriSource; |
if (source != null) { |
String libName = unitLibraryElement.name; |
- SourceEdit edit = new SourceEdit(0, 0, 'part of $libName;$eol$eol'); |
- doSourceChange_addSourceEdit(change, source, edit, isNewFile: true); |
- _addFix(DartFixKind.CREATE_FILE, [source.shortName]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(source.fullName, -1, |
+ (DartFileEditBuilder builder) { |
+ // TODO(brianwilkerson) Consider using the URI rather than name |
+ builder.addSimpleInsertion(0, 'part of $libName;$eol$eol'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE, |
+ args: [source.shortName]); |
} |
} |
} |
@@ -1601,10 +1598,14 @@ class FixProcessor { |
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE); |
} |
- void _addFix_importLibrary(FixKind kind, Source library) { |
- librariesToImport.add(library); |
+ Future<Null> _addFix_importLibrary(FixKind kind, Source library) async { |
String libraryUri = getLibrarySourceUri(unitLibraryElement, library); |
- _addFix(kind, [libraryUri], importsOnly: true); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.importLibraries([library]); |
+ }); |
+ _addFixFromBuilder(changeBuilder, kind, args: [libraryUri]); |
} |
Future<Null> _addFix_importLibrary_withElement(String name, |
@@ -1632,9 +1633,14 @@ class FixProcessor { |
// may be apply prefix |
PrefixElement prefix = imp.prefix; |
if (prefix != null) { |
- _addReplaceEdit(range.startLength(node, 0), '${prefix.displayName}.'); |
- _addFix(DartFixKind.IMPORT_LIBRARY_PREFIX, |
- [libraryElement.displayName, prefix.displayName]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement( |
+ range.startLength(node, 0), '${prefix.displayName}.'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.IMPORT_LIBRARY_PREFIX, |
+ args: [libraryElement.displayName, prefix.displayName]); |
continue; |
} |
// may be update "show" directive |
@@ -1657,9 +1663,17 @@ class FixProcessor { |
String newShowCode = 'show ${showNames.join(', ')}'; |
int offset = showCombinator.offset; |
int length = showCombinator.end - offset; |
- _addReplaceEdit( |
- new SourceRange(offset, length), newShowCode, unitLibraryElement); |
- _addFix(DartFixKind.IMPORT_LIBRARY_SHOW, [libraryName]); |
+ String libraryFile = unitLibraryElement.source.fullName; |
+ int libraryStamp = unitLibraryElement.context |
+ .getModificationStamp(unitLibraryElement.source); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(libraryFile, libraryStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement( |
+ new SourceRange(offset, length), newShowCode); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.IMPORT_LIBRARY_SHOW, |
+ args: [libraryName]); |
} |
} |
// Find new top-level declarations. |
@@ -1694,7 +1708,7 @@ class FixProcessor { |
fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1; |
} |
// Add the fix. |
- _addFix_importLibrary(fixKind, librarySource); |
+ await _addFix_importLibrary(fixKind, librarySource); |
} |
} |
} |
@@ -1846,23 +1860,31 @@ class FixProcessor { |
_addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL); |
} |
- void _addFix_removeAwait() { |
+ Future<Null> _addFix_removeAwait() async { |
final awaitExpression = node; |
if (awaitExpression is AwaitExpression) { |
final awaitToken = awaitExpression.awaitKeyword; |
- _addRemoveEdit(range.startStart(awaitToken, awaitToken.next)); |
- _addFix(DartFixKind.REMOVE_AWAIT, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.startStart(awaitToken, awaitToken.next)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_AWAIT); |
} |
} |
- void _addFix_removeDeadCode() { |
+ Future<Null> _addFix_removeDeadCode() async { |
AstNode coveringNode = this.coveredNode; |
if (coveringNode is Expression) { |
AstNode parent = coveredNode.parent; |
if (parent is BinaryExpression) { |
if (parent.rightOperand == coveredNode) { |
- _addRemoveEdit(range.endEnd(parent.leftOperand, coveredNode)); |
- _addFix(DartFixKind.REMOVE_DEAD_CODE, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.endEnd(parent.leftOperand, coveredNode)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE); |
} |
} |
} else if (coveringNode is Block) { |
@@ -1876,95 +1898,159 @@ class FixProcessor { |
if (statementsToRemove.isNotEmpty) { |
SourceRange rangeToRemove = |
utils.getLinesRangeStatements(statementsToRemove); |
- _addRemoveEdit(rangeToRemove); |
- _addFix(DartFixKind.REMOVE_DEAD_CODE, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(rangeToRemove); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE); |
} |
} else if (coveringNode is Statement) { |
SourceRange rangeToRemove = |
utils.getLinesRangeStatements(<Statement>[coveringNode]); |
- _addRemoveEdit(rangeToRemove); |
- _addFix(DartFixKind.REMOVE_DEAD_CODE, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(rangeToRemove); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE); |
} |
} |
- void _addFix_removeEmptyStatement() { |
+ Future<Null> _addFix_removeEmptyStatement() async { |
EmptyStatement emptyStatement = node; |
if (emptyStatement.parent is Block) { |
- _addRemoveEdit(utils.getLinesRange(range.node(emptyStatement))); |
- _addFix(DartFixKind.REMOVE_EMPTY_STATEMENT, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(utils.getLinesRange(range.node(emptyStatement))); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_STATEMENT); |
} else { |
- _addReplaceEdit( |
- range.endEnd(emptyStatement.beginToken.previous, emptyStatement), |
- ' {}'); |
- _addFix(DartFixKind.REPLACE_WITH_BRACKETS, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement( |
+ range.endEnd(emptyStatement.beginToken.previous, emptyStatement), |
+ ' {}'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_BRACKETS); |
} |
} |
- void _addFix_removeInitializer() { |
+ Future<Null> _addFix_removeInitializer() async { |
// Retrieve the linted node. |
VariableDeclaration ancestor = |
node.getAncestor((a) => a is VariableDeclaration); |
if (ancestor == null) { |
return; |
} |
- _addRemoveEdit(range.endEnd(ancestor.name, ancestor.initializer)); |
- _addFix(DartFixKind.REMOVE_INITIALIZER, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.endEnd(ancestor.name, ancestor.initializer)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_INITIALIZER); |
+ } |
+ |
+ Future<Null> _addFix_removeInterpolationBraces() async { |
+ AstNode node = this.node; |
+ if (node is InterpolationExpression) { |
+ Token right = node.rightBracket; |
+ if (node.expression != null && right != null) { |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement( |
+ range.startStart(node, node.expression), r'$'); |
+ builder.addDeletion(range.token(right)); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES); |
+ } else {} |
+ } |
} |
- void _addFix_removeMethodDeclaration() { |
+ Future<Null> _addFix_removeMethodDeclaration() async { |
MethodDeclaration declaration = |
node.getAncestor((node) => node is MethodDeclaration); |
if (declaration != null) { |
- _addRemoveEdit(utils.getLinesRange(range.node(declaration))); |
- _addFix(DartFixKind.REMOVE_METHOD_DECLARATION, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(utils.getLinesRange(range.node(declaration))); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_METHOD_DECLARATION); |
} |
} |
- void _addFix_removeParameters_inGetterDeclaration() { |
+ Future<Null> _addFix_removeParameters_inGetterDeclaration() async { |
if (node is MethodDeclaration) { |
MethodDeclaration method = node as MethodDeclaration; |
SimpleIdentifier name = method.name; |
FunctionBody body = method.body; |
if (name != null && body != null) { |
- _addReplaceEdit(range.endStart(name, body), ' '); |
- _addFix(DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement(range.endStart(name, body), ' '); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION); |
} |
} |
} |
- void _addFix_removeParentheses_inGetterInvocation() { |
+ Future<Null> _addFix_removeParentheses_inGetterInvocation() async { |
if (node is SimpleIdentifier && node.parent is MethodInvocation) { |
MethodInvocation invocation = node.parent as MethodInvocation; |
if (invocation.methodName == node && invocation.target != null) { |
- _addRemoveEdit(range.endEnd(node, invocation)); |
- _addFix(DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.endEnd(node, invocation)); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION); |
} |
} |
} |
- void _addFix_removeThisExpression() { |
+ Future<Null> _addFix_removeThisExpression() async { |
final thisExpression = node is ThisExpression |
? node |
: node.getAncestor((node) => node is ThisExpression); |
final parent = thisExpression.parent; |
if (parent is PropertyAccess) { |
- _addRemoveEdit(range.startEnd(parent, parent.operator)); |
- _addFix(DartFixKind.REMOVE_THIS_EXPRESSION, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.startEnd(parent, parent.operator)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION); |
} else if (parent is MethodInvocation) { |
- _addRemoveEdit(range.startEnd(parent, parent.operator)); |
- _addFix(DartFixKind.REMOVE_THIS_EXPRESSION, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.startEnd(parent, parent.operator)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION); |
} |
} |
- void _addFix_removeTypeName() { |
+ Future<Null> _addFix_removeTypeName() async { |
final TypeName type = node.getAncestor((node) => node is TypeName); |
if (type != null) { |
- _addRemoveEdit(range.startStart(type, type.endToken.next)); |
- _addFix(DartFixKind.REMOVE_TYPE_NAME, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.startStart(type, type.endToken.next)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_NAME); |
} |
} |
- void _addFix_removeUnnecessaryCast() { |
+ Future<Null> _addFix_removeUnnecessaryCast() async { |
if (coveredNode is! AsExpression) { |
return; |
} |
@@ -1972,37 +2058,51 @@ class FixProcessor { |
Expression expression = asExpression.expression; |
int expressionPrecedence = getExpressionPrecedence(expression); |
// remove 'as T' from 'e as T' |
- _addRemoveEdit(range.endEnd(expression, asExpression)); |
- _removeEnclosingParentheses(asExpression, expressionPrecedence); |
- // done |
- _addFix(DartFixKind.REMOVE_UNNECESSARY_CAST, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(range.endEnd(expression, asExpression)); |
+ _removeEnclosingParentheses(builder, asExpression, expressionPrecedence); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNNECESSARY_CAST); |
} |
- void _addFix_removeUnusedCatchClause() { |
+ Future<Null> _addFix_removeUnusedCatchClause() async { |
if (node is SimpleIdentifier) { |
AstNode catchClause = node.parent; |
if (catchClause is CatchClause && |
catchClause.exceptionParameter == node) { |
- _addRemoveEdit( |
- range.startStart(catchClause.catchKeyword, catchClause.body)); |
- _addFix(DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion( |
+ range.startStart(catchClause.catchKeyword, catchClause.body)); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE); |
} |
} |
} |
- void _addFix_removeUnusedCatchStack() { |
+ Future<Null> _addFix_removeUnusedCatchStack() async { |
if (node is SimpleIdentifier) { |
AstNode catchClause = node.parent; |
if (catchClause is CatchClause && |
catchClause.stackTraceParameter == node && |
catchClause.exceptionParameter != null) { |
- _addRemoveEdit(range.endEnd(catchClause.exceptionParameter, node)); |
- _addFix(DartFixKind.REMOVE_UNUSED_CATCH_STACK, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder |
+ .addDeletion(range.endEnd(catchClause.exceptionParameter, node)); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_STACK); |
} |
} |
} |
- void _addFix_removeUnusedImport() { |
+ Future<Null> _addFix_removeUnusedImport() async { |
// prepare ImportDirective |
ImportDirective importDirective = |
node.getAncestor((node) => node is ImportDirective); |
@@ -2010,17 +2110,24 @@ class FixProcessor { |
return; |
} |
// remove the whole line with import |
- _addRemoveEdit(utils.getLinesRange(range.node(importDirective))); |
- // done |
- _addFix(DartFixKind.REMOVE_UNUSED_IMPORT, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addDeletion(utils.getLinesRange(range.node(importDirective))); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_IMPORT); |
} |
- void _addFix_replaceVarWithDynamic() { |
- _addReplaceEdit(range.error(error), 'dynamic'); |
- _addFix(DartFixKind.REPLACE_VAR_WITH_DYNAMIC, []); |
+ Future<Null> _addFix_replaceVarWithDynamic() async { |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement(range.error(error), 'dynamic'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_VAR_WITH_DYNAMIC); |
} |
- void _addFix_replaceWithConditionalAssignment() { |
+ Future<Null> _addFix_replaceWithConditionalAssignment() async { |
IfStatement ifStatement = node is IfStatement |
? node |
: node.getAncestor((node) => node is IfStatement); |
@@ -2036,89 +2143,113 @@ class FixProcessor { |
if (thenStatement is ExpressionStatement) { |
final expression = thenStatement.expression.unParenthesized; |
if (expression is AssignmentExpression) { |
- final buffer = new StringBuffer(); |
- buffer.write(utils.getNodeText(expression.leftHandSide)); |
- buffer.write(' ??= '); |
- buffer.write(utils.getNodeText(expression.rightHandSide)); |
- buffer.write(';'); |
- _addReplaceEdit(range.node(ifStatement), buffer.toString()); |
- _addFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addReplacement(range.node(ifStatement), |
+ (DartEditBuilder builder) { |
+ builder.write(utils.getNodeText(expression.leftHandSide)); |
+ builder.write(' ??= '); |
+ builder.write(utils.getNodeText(expression.rightHandSide)); |
+ builder.write(';'); |
+ }); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT); |
} |
} |
} |
- void _addFix_replaceWithConstInstanceCreation() { |
+ Future<Null> _addFix_replaceWithConstInstanceCreation() async { |
if (coveredNode is InstanceCreationExpression) { |
var instanceCreation = coveredNode as InstanceCreationExpression; |
- _addReplaceEdit(range.token(instanceCreation.keyword), 'const'); |
- _addFix(DartFixKind.USE_CONST, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement( |
+ range.token(instanceCreation.keyword), 'const'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.USE_CONST); |
} |
} |
- void _addFix_replaceWithIdentifier() { |
+ Future<Null> _addFix_replaceWithIdentifier() async { |
final FunctionTypedFormalParameter functionTyped = |
node.getAncestor((node) => node is FunctionTypedFormalParameter); |
if (functionTyped != null) { |
- _addReplaceEdit(range.node(functionTyped), |
- utils.getNodeText(functionTyped.identifier)); |
- _addFix(DartFixKind.REPLACE_WITH_IDENTIFIER, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement(range.node(functionTyped), |
+ utils.getNodeText(functionTyped.identifier)); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_IDENTIFIER); |
} else { |
- _addFix_removeTypeName(); |
+ await _addFix_removeTypeName(); |
} |
} |
- void _addFix_replaceWithLiteral() { |
+ Future<Null> _addFix_replaceWithLiteral() async { |
final InstanceCreationExpression instanceCreation = |
node.getAncestor((node) => node is InstanceCreationExpression); |
final InterfaceType type = instanceCreation.staticType; |
- final buffer = new StringBuffer(); |
final generics = instanceCreation.constructorName.type.typeArguments; |
- if (generics != null) { |
- buffer.write(utils.getNodeText(generics)); |
- } |
- if (type.name == 'List') { |
- buffer.write('[]'); |
- } else { |
- buffer.write('{}'); |
- } |
- _addReplaceEdit(range.node(instanceCreation), buffer.toString()); |
- _addFix(DartFixKind.REPLACE_WITH_LITERAL, []); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addReplacement(range.node(instanceCreation), |
+ (DartEditBuilder builder) { |
+ if (generics != null) { |
+ builder.write(utils.getNodeText(generics)); |
+ } |
+ if (type.name == 'List') { |
+ builder.write('[]'); |
+ } else { |
+ builder.write('{}'); |
+ } |
+ }); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_LITERAL); |
} |
- void _addFix_replaceWithTearOff() { |
+ Future<Null> _addFix_replaceWithTearOff() async { |
FunctionExpression ancestor = |
node.getAncestor((a) => a is FunctionExpression); |
if (ancestor == null) { |
return; |
} |
- void addFixOfExpression(InvocationExpression expression) { |
- final buffer = new StringBuffer(); |
- if (expression is MethodInvocation && expression.target != null) { |
- buffer.write(utils.getNodeText(expression.target)); |
- buffer.write('.'); |
- } |
- buffer.write(utils.getNodeText(expression.function)); |
- _addReplaceEdit(range.node(ancestor), buffer.toString()); |
- _addFix(DartFixKind.REPLACE_WITH_TEAR_OFF, []); |
+ Future<Null> addFixOfExpression(InvocationExpression expression) async { |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addReplacement(range.node(ancestor), (DartEditBuilder builder) { |
+ if (expression is MethodInvocation && expression.target != null) { |
+ builder.write(utils.getNodeText(expression.target)); |
+ builder.write('.'); |
+ } |
+ builder.write(utils.getNodeText(expression.function)); |
+ }); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_TEAR_OFF); |
} |
final body = ancestor.body; |
if (body is ExpressionFunctionBody) { |
final expression = body.expression; |
- addFixOfExpression(expression.unParenthesized); |
+ await addFixOfExpression(expression.unParenthesized); |
} else if (body is BlockFunctionBody) { |
final statement = body.block.statements.first; |
if (statement is ExpressionStatement) { |
final expression = statement.expression; |
- addFixOfExpression(expression.unParenthesized); |
+ await addFixOfExpression(expression.unParenthesized); |
} else if (statement is ReturnStatement) { |
final expression = statement.expression; |
- addFixOfExpression(expression.unParenthesized); |
+ await addFixOfExpression(expression.unParenthesized); |
} |
} |
} |
- void _addFix_undefinedClass_useSimilar() { |
+ Future<Null> _addFix_undefinedClass_useSimilar() async { |
AstNode node = this.node; |
// Prepare the optional import prefix name. |
String prefixName = null; |
@@ -2155,16 +2286,20 @@ class FixProcessor { |
// If we have a close enough element, suggest to use it. |
if (finder._element != null) { |
String closestName = finder._element.name; |
- _addReplaceEdit(range.node(node), closestName); |
- // Add proposal. |
if (closestName != null) { |
- _addFix(DartFixKind.CHANGE_TO, [closestName]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement(range.node(node), closestName); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO, |
+ args: [closestName]); |
} |
} |
} |
} |
- void _addFix_undefinedClassAccessor_useSimilar() { |
+ Future<Null> _addFix_undefinedClassAccessor_useSimilar() async { |
AstNode node = this.node; |
if (node is SimpleIdentifier) { |
// prepare target |
@@ -2175,14 +2310,16 @@ class FixProcessor { |
} |
// find getter |
if (node.inGetterContext()) { |
- _addFix_undefinedClassMember_useSimilar(target, (Element element) { |
+ await _addFix_undefinedClassMember_useSimilar(target, |
+ (Element element) { |
return element is PropertyAccessorElement && element.isGetter || |
element is FieldElement && element.getter != null; |
}); |
} |
// find setter |
if (node.inSetterContext()) { |
- _addFix_undefinedClassMember_useSimilar(target, (Element element) { |
+ await _addFix_undefinedClassMember_useSimilar(target, |
+ (Element element) { |
return element is PropertyAccessorElement && element.isSetter || |
element is FieldElement && element.setter != null; |
}); |
@@ -2190,8 +2327,8 @@ class FixProcessor { |
} |
} |
- void _addFix_undefinedClassMember_useSimilar( |
- Expression target, ElementPredicate predicate) { |
+ Future<Null> _addFix_undefinedClassMember_useSimilar( |
+ Expression target, ElementPredicate predicate) async { |
if (node is SimpleIdentifier) { |
String name = (node as SimpleIdentifier).name; |
_ClosestElementFinder finder = |
@@ -2214,13 +2351,18 @@ class FixProcessor { |
// if we have close enough element, suggest to use it |
if (finder._element != null) { |
String closestName = finder._element.name; |
- _addReplaceEdit(range.node(node), closestName); |
- _addFix(DartFixKind.CHANGE_TO, [closestName]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement(range.node(node), closestName); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO, |
+ args: [closestName]); |
} |
} |
} |
- void _addFix_undefinedFunction_create() { |
+ Future<Null> _addFix_undefinedFunction_create() async { |
// should be the name of the invocation |
if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else { |
return; |
@@ -2241,31 +2383,33 @@ class FixProcessor { |
sourcePrefix = '$eol$eol'; |
utils.targetClassElement = null; |
// build method source |
- SourceBuilder sb = new SourceBuilder(file, insertOffset); |
- { |
- sb.append(sourcePrefix); |
- // append return type |
- { |
- DartType type = _inferUndefinedExpressionType(invocation); |
- _appendType(sb, type, groupId: 'RETURN_TYPE'); |
- } |
- // append name |
- { |
- sb.startPosition('NAME'); |
- sb.append(name); |
- sb.endPosition(); |
- } |
- _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList); |
- sb.append(') {$eol}'); |
- } |
- // insert source |
- _insertBuilder(sb, unitElement); |
- _addLinkedPosition('NAME', sb, range.node(node)); |
- // add proposal |
- _addFix(DartFixKind.CREATE_FUNCTION, [name]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addInsertion(insertOffset, (DartEditBuilder builder) { |
+ builder.write(sourcePrefix); |
+ // append return type |
+ { |
+ DartType type = _inferUndefinedExpressionType(invocation); |
+ if (builder.writeType(type, groupName: 'RETURN_TYPE')) { |
+ builder.write(' '); |
+ } |
+ } |
+ // append name |
+ builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) { |
+ builder.write(name); |
+ }); |
+ builder.write('('); |
+ builder.writeParametersMatchingArguments(invocation.argumentList); |
+ builder.write(') {$eol}'); |
+ }); |
+ builder.addLinkedPosition(range.node(node), 'NAME'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION, |
+ args: [name]); |
} |
- void _addFix_undefinedFunction_useSimilar() { |
+ Future<Null> _addFix_undefinedFunction_useSimilar() async { |
AstNode node = this.node; |
if (node is SimpleIdentifier) { |
// Prepare the optional import prefix name. |
@@ -2301,13 +2445,18 @@ class FixProcessor { |
// If we have a close enough element, suggest to use it. |
if (finder._element != null) { |
String closestName = finder._element.name; |
- _addReplaceEdit(range.node(node), closestName); |
- _addFix(DartFixKind.CHANGE_TO, [closestName]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addSimpleReplacement(range.node(node), closestName); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO, |
+ args: [closestName]); |
} |
} |
} |
- void _addFix_undefinedMethod_create() { |
+ Future<Null> _addFix_undefinedMethod_create() async { |
if (node is SimpleIdentifier && node.parent is MethodInvocation) { |
String name = (node as SimpleIdentifier).name; |
MethodInvocation invocation = node.parent as MethodInvocation; |
@@ -2356,69 +2505,47 @@ class FixProcessor { |
ClassMemberLocation targetLocation = |
utils.prepareNewMethodLocation(targetClassNode); |
String targetFile = targetElement.source.fullName; |
+ int targetStamp = |
+ targetElement.context.getModificationStamp(targetElement.source); |
// build method source |
- SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset); |
- { |
- sb.append(targetLocation.prefix); |
- // maybe "static" |
- if (staticModifier) { |
- sb.append('static '); |
- } |
- // append return type |
- { |
- DartType type = _inferUndefinedExpressionType(invocation); |
- _appendType(sb, type, groupId: 'RETURN_TYPE'); |
- } |
- // append name |
- { |
- sb.startPosition('NAME'); |
- sb.append(name); |
- sb.endPosition(); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(targetFile, targetStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { |
+ builder.write(targetLocation.prefix); |
+ // maybe "static" |
+ if (staticModifier) { |
+ builder.write('static '); |
+ } |
+ // append return type |
+ { |
+ DartType type = _inferUndefinedExpressionType(invocation); |
+ if (builder.writeType(type, groupName: 'RETURN_TYPE')) { |
+ builder.write(' '); |
+ } |
+ } |
+ // append name |
+ builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) { |
+ builder.write(name); |
+ }); |
+ builder.write('('); |
+ builder.writeParametersMatchingArguments(invocation.argumentList); |
+ builder.write(') {}'); |
+ builder.write(targetLocation.suffix); |
+ }); |
+ if (targetFile == file) { |
+ builder.addLinkedPosition(range.node(node), 'NAME'); |
} |
- _addFix_undefinedMethod_create_parameters(sb, invocation.argumentList); |
- sb.append(') {}'); |
- sb.append(targetLocation.suffix); |
- } |
- // insert source |
- _insertBuilder(sb, targetElement); |
- // add linked positions |
- if (targetFile == file) { |
- _addLinkedPosition('NAME', sb, range.node(node)); |
- } |
- // add proposal |
- _addFix(DartFixKind.CREATE_METHOD, [name]); |
- } |
- } |
- |
- void _addFix_undefinedMethod_create_parameters( |
- SourceBuilder sb, ArgumentList argumentList) { |
- Set<String> usedNames = new Set<String>(); |
- // append parameters |
- sb.append('('); |
- List<Expression> arguments = argumentList.arguments; |
- bool hasNamedParameters = false; |
- for (int i = 0; i < arguments.length; i++) { |
- Expression argument = arguments[i]; |
- // append separator |
- if (i != 0) { |
- sb.append(', '); |
- } |
- // append parameter |
- if (argument is NamedExpression && !hasNamedParameters) { |
- hasNamedParameters = true; |
- sb.append('{'); |
- } |
- _appendParameterForArgument(sb, usedNames, i, argument); |
- } |
- if (hasNamedParameters) { |
- sb.append('}'); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, |
+ args: [name]); |
} |
} |
- void _addFix_undefinedMethod_useSimilar() { |
+ Future<Null> _addFix_undefinedMethod_useSimilar() async { |
if (node.parent is MethodInvocation) { |
MethodInvocation invocation = node.parent as MethodInvocation; |
- _addFix_undefinedClassMember_useSimilar(invocation.realTarget, |
+ await _addFix_undefinedClassMember_useSimilar(invocation.realTarget, |
(Element element) => element is MethodElement && !element.isOperator); |
} |
} |
@@ -2427,7 +2554,7 @@ class FixProcessor { |
* Here we handle cases when a constructors does not initialize all of the |
* final fields. |
*/ |
- void _addFix_updateConstructor_forUninitializedFinalFields() { |
+ Future<Null> _addFix_updateConstructor_forUninitializedFinalFields() async { |
if (node is! SimpleIdentifier || node.parent is! ConstructorDeclaration) { |
return; |
} |
@@ -2447,34 +2574,42 @@ class FixProcessor { |
lastRequiredParameter = parameter; |
} |
} |
- // append new field formal initializers |
- if (lastRequiredParameter != null) { |
- _addInsertEdit(lastRequiredParameter.end, ', $fieldParametersCode'); |
- } else { |
- int offset = constructor.parameters.leftParenthesis.end; |
- if (parameters.isNotEmpty) { |
- fieldParametersCode += ', '; |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ // append new field formal initializers |
+ if (lastRequiredParameter != null) { |
+ builder.addSimpleInsertion( |
+ lastRequiredParameter.end, ', $fieldParametersCode'); |
+ } else { |
+ int offset = constructor.parameters.leftParenthesis.end; |
+ if (parameters.isNotEmpty) { |
+ fieldParametersCode += ', '; |
+ } |
+ builder.addSimpleInsertion(offset, fieldParametersCode); |
} |
- _addInsertEdit(offset, fieldParametersCode); |
- } |
- // add proposal |
- _addFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, []); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.ADD_FIELD_FORMAL_PARAMETERS); |
} |
- void _addFix_useEffectiveIntegerDivision() { |
+ Future<Null> _addFix_useEffectiveIntegerDivision() async { |
for (AstNode n = node; n != null; n = n.parent) { |
if (n is MethodInvocation && |
n.offset == errorOffset && |
n.length == errorLength) { |
- Expression target = n.target.unParenthesized; |
- // replace "/" with "~/" |
- BinaryExpression binary = target as BinaryExpression; |
- _addReplaceEdit(range.token(binary.operator), '~/'); |
- // remove everything before and after |
- _addRemoveEdit(range.startStart(n, binary.leftOperand)); |
- _addRemoveEdit(range.endEnd(binary.rightOperand, n)); |
- // add proposal |
- _addFix(DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION, []); |
+ Expression target = (n as MethodInvocation).target.unParenthesized; |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ // replace "/" with "~/" |
+ BinaryExpression binary = target as BinaryExpression; |
+ builder.addSimpleReplacement(range.token(binary.operator), '~/'); |
+ // remove everything before and after |
+ builder.addDeletion(range.startStart(n, binary.leftOperand)); |
+ builder.addDeletion(range.endEnd(binary.rightOperand, n)); |
+ }); |
+ _addFixFromBuilder( |
+ changeBuilder, DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION); |
// done |
break; |
} |
@@ -2485,37 +2620,41 @@ class FixProcessor { |
* Adds a fix that replaces [target] with a reference to the class declaring |
* the given [element]. |
*/ |
- void _addFix_useStaticAccess(AstNode target, Element element) { |
+ Future<Null> _addFix_useStaticAccess(AstNode target, Element element) async { |
Element declaringElement = element.enclosingElement; |
if (declaringElement is ClassElement) { |
DartType declaringType = declaringElement.type; |
- String declaringTypeCode = |
- utils.getTypeSource(declaringType, librariesToImport); |
- // replace "target" with class name |
- _addReplaceEdit(range.node(target), declaringTypeCode); |
- // add proposal |
- _addFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, [declaringType]); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(file, fileStamp, |
+ (DartFileEditBuilder builder) { |
+ // replace "target" with class name |
+ builder.addReplacement(range.node(target), (DartEditBuilder builder) { |
+ builder.writeType(declaringType); |
+ }); |
+ }); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO_STATIC_ACCESS, |
+ args: [declaringType]); |
} |
} |
- void _addFix_useStaticAccess_method() { |
+ Future<Null> _addFix_useStaticAccess_method() async { |
if (node is SimpleIdentifier && node.parent is MethodInvocation) { |
MethodInvocation invocation = node.parent as MethodInvocation; |
if (invocation.methodName == node) { |
Expression target = invocation.target; |
Element invokedElement = invocation.methodName.bestElement; |
- _addFix_useStaticAccess(target, invokedElement); |
+ await _addFix_useStaticAccess(target, invokedElement); |
} |
} |
} |
- void _addFix_useStaticAccess_property() { |
+ Future<Null> _addFix_useStaticAccess_property() async { |
if (node is SimpleIdentifier && node.parent is PrefixedIdentifier) { |
PrefixedIdentifier prefixed = node.parent as PrefixedIdentifier; |
if (prefixed.identifier == node) { |
Expression target = prefixed.prefix; |
Element invokedElement = prefixed.identifier.bestElement; |
- _addFix_useStaticAccess(target, invokedElement); |
+ await _addFix_useStaticAccess(target, invokedElement); |
} |
} |
} |
@@ -2531,67 +2670,10 @@ class FixProcessor { |
} |
/** |
- * Adds a new [SourceEdit] to [change]. |
- */ |
- void _addInsertEdit(int offset, String text, [Element target]) { |
- SourceEdit edit = new SourceEdit(offset, 0, text); |
- _addEdit(target, edit); |
- } |
- |
- /** |
- * Adds a single linked position to [groupId]. |
- */ |
- void _addLinkedPosition(String groupId, SourceBuilder sb, SourceRange range) { |
- // prepare offset |
- int offset = range.offset; |
- if (sb.offset <= offset) { |
- int delta = sb.length; |
- offset += delta; |
- } |
- // prepare group |
- LinkedEditGroup group = _getLinkedPosition(groupId); |
- // add position |
- Position position = new Position(file, offset); |
- group.addPosition(position, range.length); |
- } |
- |
- void _addLintFixAddOverrideAnnotation() { |
- ClassMember member = node.getAncestor((n) => n is ClassMember); |
- if (member == null) { |
- return; |
- } |
- |
- //TODO(pq): migrate annotation edit building to change_builder |
- |
- // Handle doc comments. |
- Token token = member.beginToken; |
- if (token is CommentToken) { |
- token = (token as CommentToken).parent; |
- } |
- |
- exitPosition = new Position(file, token.offset - 1); |
- String indent = utils.getIndent(1); |
- _addReplaceEdit(range.startLength(token, 0), '@override$eol$indent'); |
- _addFix(DartFixKind.LINT_ADD_OVERRIDE, []); |
- } |
- |
- void _addLintRemoveInterpolationBraces() { |
- AstNode node = this.node; |
- if (node is InterpolationExpression) { |
- Token right = node.rightBracket; |
- if (node.expression != null && right != null) { |
- _addReplaceEdit(range.startStart(node, node.expression), r'$'); |
- _addRemoveEdit(range.token(right)); |
- _addFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES, []); |
- } |
- } |
- } |
- |
- /** |
* Prepares proposal for creating function corresponding to the given |
* [FunctionType]. |
*/ |
- void _addProposal_createFunction( |
+ Future<DartChangeBuilder> _addProposal_createFunction( |
FunctionType functionType, |
String name, |
Source targetSource, |
@@ -2600,71 +2682,71 @@ class FixProcessor { |
String prefix, |
String sourcePrefix, |
String sourceSuffix, |
- Element target) { |
+ Element target) async { |
// build method source |
String targetFile = targetSource.fullName; |
- SourceBuilder sb = new SourceBuilder(targetFile, insertOffset); |
- { |
- sb.append(sourcePrefix); |
- sb.append(prefix); |
- // may be static |
- if (isStatic) { |
- sb.append('static '); |
- } |
- // append return type |
- _appendType(sb, functionType.returnType, groupId: 'RETURN_TYPE'); |
- // append name |
- { |
- sb.startPosition('NAME'); |
- sb.append(name); |
- sb.endPosition(); |
- } |
- // append parameters |
- sb.append('('); |
- List<ParameterElement> parameters = functionType.parameters; |
- for (int i = 0; i < parameters.length; i++) { |
- ParameterElement parameter = parameters[i]; |
- // append separator |
- if (i != 0) { |
- sb.append(', '); |
+ int timeStamp = target.context.getModificationStamp(targetSource); |
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver); |
+ await changeBuilder.addFileEdit(targetFile, timeStamp, |
+ (DartFileEditBuilder builder) { |
+ builder.addInsertion(insertOffset, (DartEditBuilder builder) { |
+ builder.write(sourcePrefix); |
+ builder.write(prefix); |
+ // may be static |
+ if (isStatic) { |
+ builder.write('static '); |
} |
- // append type name |
- DartType type = parameter.type; |
- if (!type.isDynamic) { |
- String typeSource = utils.getTypeSource(type, librariesToImport); |
- { |
- sb.startPosition('TYPE$i'); |
- sb.append(typeSource); |
- _addSuperTypeProposals(sb, type); |
- sb.endPosition(); |
- } |
- sb.append(' '); |
+ // append return type |
+ if (builder.writeType(functionType.returnType, |
+ groupName: 'RETURN_TYPE')) { |
+ builder.write(' '); |
} |
- // append parameter name |
- { |
- sb.startPosition('ARG$i'); |
- sb.append(parameter.displayName); |
- sb.endPosition(); |
+ // append name |
+ builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) { |
+ builder.write(name); |
+ }); |
+ // append parameters |
+ builder.write('('); |
+ List<ParameterElement> parameters = functionType.parameters; |
+ for (int i = 0; i < parameters.length; i++) { |
+ ParameterElement parameter = parameters[i]; |
+ // append separator |
+ if (i != 0) { |
+ builder.write(', '); |
+ } |
+ // append type name |
+ DartType type = parameter.type; |
+ if (!type.isDynamic) { |
+ builder.addLinkedEdit('TYPE$i', |
+ (DartLinkedEditBuilder innerBuilder) { |
+ builder.writeType(type); |
+ innerBuilder.addSuperTypesAsSuggestions(type); |
+ }); |
+ builder.write(' '); |
+ } |
+ // append parameter name |
+ builder.addLinkedEdit('ARG$i', (DartLinkedEditBuilder builder) { |
+ builder.write(parameter.displayName); |
+ }); |
} |
+ builder.write(')'); |
+ // close method |
+ builder.write(' {$eol$prefix}'); |
+ builder.write(sourceSuffix); |
+ }); |
+ if (targetSource == unitSource) { |
+ builder.addLinkedPosition(range.node(node), 'NAME'); |
} |
- sb.append(')'); |
- // close method |
- sb.append(' {$eol$prefix}'); |
- sb.append(sourceSuffix); |
- } |
- // insert source |
- _insertBuilder(sb, target); |
- // add linked positions |
- if (targetSource == unitSource) { |
- _addLinkedPosition('NAME', sb, range.node(node)); |
- } |
+ }); |
+ return changeBuilder; |
} |
/** |
* Adds proposal for creating method corresponding to the given [FunctionType] in the given |
* [ClassElement]. |
*/ |
- void _addProposal_createFunction_function(FunctionType functionType) { |
+ Future<Null> _addProposal_createFunction_function( |
+ FunctionType functionType) async { |
String name = (node as SimpleIdentifier).name; |
// prepare environment |
int insertOffset = unit.end; |
@@ -2672,18 +2754,26 @@ class FixProcessor { |
String prefix = ''; |
String sourcePrefix = '$eol'; |
String sourceSuffix = eol; |
- _addProposal_createFunction(functionType, name, unitSource, insertOffset, |
- false, prefix, sourcePrefix, sourceSuffix, unitElement); |
- // add proposal |
- _addFix(DartFixKind.CREATE_FUNCTION, [name]); |
+ DartChangeBuilder changeBuilder = await _addProposal_createFunction( |
+ functionType, |
+ name, |
+ unitSource, |
+ insertOffset, |
+ false, |
+ prefix, |
+ sourcePrefix, |
+ sourceSuffix, |
+ unitElement); |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION, |
+ args: [name]); |
} |
/** |
* Adds proposal for creating method corresponding to the given [FunctionType] in the given |
* [ClassElement]. |
*/ |
- void _addProposal_createFunction_method( |
- ClassElement targetClassElement, FunctionType functionType) { |
+ Future<Null> _addProposal_createFunction_method( |
+ ClassElement targetClassElement, FunctionType functionType) async { |
String name = (node as SimpleIdentifier).name; |
// prepare environment |
Source targetSource = targetClassElement.source; |
@@ -2700,7 +2790,7 @@ class FixProcessor { |
sourcePrefix = eol; |
} |
String sourceSuffix = eol; |
- _addProposal_createFunction( |
+ DartChangeBuilder changeBuilder = await _addProposal_createFunction( |
functionType, |
name, |
targetSource, |
@@ -2710,126 +2800,7 @@ class FixProcessor { |
sourcePrefix, |
sourceSuffix, |
targetClassElement); |
- // add proposal |
- _addFix(DartFixKind.CREATE_METHOD, [name]); |
- } |
- |
- /** |
- * Adds a new [Edit] to [edits]. |
- */ |
- void _addRemoveEdit(SourceRange range) { |
- _addReplaceEdit(range, ''); |
- } |
- |
- /** |
- * Adds a new [SourceEdit] to [change]. |
- */ |
- void _addReplaceEdit(SourceRange range, String text, [Element target]) { |
- SourceEdit edit = new SourceEdit(range.offset, range.length, text); |
- _addEdit(target, edit); |
- } |
- |
- void _appendParameterForArgument( |
- SourceBuilder sb, Set<String> excluded, int index, Expression argument) { |
- DartType type = argument.bestType; |
- if (type == null || type.isBottom || type.isDartCoreNull) { |
- type = DynamicTypeImpl.instance; |
- } |
- // append type name |
- String typeSource = utils.getTypeSource(type, librariesToImport); |
- if (typeSource != 'dynamic') { |
- sb.startPosition('TYPE$index'); |
- sb.append(typeSource); |
- _addSuperTypeProposals(sb, type); |
- sb.endPosition(); |
- sb.append(' '); |
- } |
- // append parameter name |
- if (argument is NamedExpression) { |
- sb.append(argument.name.label.name); |
- } else { |
- List<String> suggestions = |
- _getArgumentNameSuggestions(excluded, type, argument, index); |
- String favorite = suggestions[0]; |
- excluded.add(favorite); |
- sb.startPosition('ARG$index'); |
- sb.append(favorite); |
- sb.addSuggestions(LinkedEditSuggestionKind.PARAMETER, suggestions); |
- sb.endPosition(); |
- } |
- } |
- |
- void _appendParameters(SourceBuilder sb, List<ParameterElement> parameters) { |
- sb.append('('); |
- bool firstParameter = true; |
- bool sawNamed = false; |
- bool sawPositional = false; |
- for (ParameterElement parameter in parameters) { |
- if (!firstParameter) { |
- sb.append(', '); |
- } else { |
- firstParameter = false; |
- } |
- // may be optional |
- ParameterKind parameterKind = parameter.parameterKind; |
- if (parameterKind == ParameterKind.NAMED) { |
- if (!sawNamed) { |
- sb.append('{'); |
- sawNamed = true; |
- } |
- } |
- if (parameterKind == ParameterKind.POSITIONAL) { |
- if (!sawPositional) { |
- sb.append('['); |
- sawPositional = true; |
- } |
- } |
- // parameter |
- _appendParameterSource(sb, parameter.type, parameter.name); |
- // default value |
- String defaultCode = parameter.defaultValueCode; |
- if (defaultCode != null) { |
- if (sawPositional) { |
- sb.append(' = '); |
- } else { |
- sb.append(': '); |
- } |
- sb.append(defaultCode); |
- } |
- } |
- // close parameters |
- if (sawNamed) { |
- sb.append('}'); |
- } |
- if (sawPositional) { |
- sb.append(']'); |
- } |
- sb.append(')'); |
- } |
- |
- void _appendParameterSource(SourceBuilder sb, DartType type, String name) { |
- String parameterSource = |
- utils.getParameterSource(type, name, librariesToImport); |
- sb.append(parameterSource); |
- } |
- |
- void _appendType(SourceBuilder sb, DartType type, |
- {String groupId, bool orVar: false, bool trailingSpace: true}) { |
- if (type != null && !type.isDynamic) { |
- String typeSource = utils.getTypeSource(type, librariesToImport); |
- if (groupId != null) { |
- sb.startPosition(groupId); |
- sb.append(typeSource); |
- sb.endPosition(); |
- } else { |
- sb.append(typeSource); |
- } |
- if (trailingSpace) { |
- sb.append(' '); |
- } |
- } else if (orVar) { |
- sb.append('var '); |
- } |
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, args: [name]); |
} |
/** |
@@ -2878,21 +2849,19 @@ class FixProcessor { |
} |
/** |
- * @return the string to display as the name of the given constructor in a proposal name. |
+ * Return the string to display as the name of the given constructor in a |
+ * proposal name. |
*/ |
String _getConstructorProposalName(ConstructorElement constructor) { |
- SourceBuilder proposalNameBuffer = new SourceBuilder.buffer(); |
- proposalNameBuffer.append('super'); |
- // may be named |
+ StringBuffer buffer = new StringBuffer(); |
+ buffer.write('super'); |
String constructorName = constructor.displayName; |
if (!constructorName.isEmpty) { |
- proposalNameBuffer.append('.'); |
- proposalNameBuffer.append(constructorName); |
+ buffer.write('.'); |
+ buffer.write(constructorName); |
} |
- // parameters |
- _appendParameters(proposalNameBuffer, constructor.parameters); |
- // done |
- return proposalNameBuffer.toString(); |
+ buffer.write('(...)'); |
+ return buffer.toString(); |
} |
/** |
@@ -2913,18 +2882,6 @@ class FixProcessor { |
} |
/** |
- * Returns an existing or just added [LinkedEditGroup] with [groupId]. |
- */ |
- LinkedEditGroup _getLinkedPosition(String groupId) { |
- LinkedEditGroup group = linkedPositionGroups[groupId]; |
- if (group == null) { |
- group = new LinkedEditGroup.empty(); |
- linkedPositionGroups[groupId] = group; |
- } |
- return group; |
- } |
- |
- /** |
* Returns an expected [DartType] of [expression], may be `null` if cannot be |
* inferred. |
*/ |
@@ -3051,24 +3008,6 @@ class FixProcessor { |
} |
/** |
- * Inserts the given [SourceBuilder] at its offset. |
- */ |
- void _insertBuilder(SourceBuilder builder, Element target) { |
- String text = builder.toString(); |
- _addInsertEdit(builder.offset, text, target); |
- // add linked positions |
- builder.linkedPositionGroups.forEach((String id, LinkedEditGroup group) { |
- LinkedEditGroup fixGroup = _getLinkedPosition(id); |
- group.positions.forEach((Position position) { |
- fixGroup.addPosition(position, group.length); |
- }); |
- group.suggestions.forEach((LinkedEditSuggestion suggestion) { |
- fixGroup.addSuggestion(suggestion); |
- }); |
- }); |
- } |
- |
- /** |
* Returns `true` if [node] is in static context. |
*/ |
bool _inStaticContext() { |
@@ -3143,15 +3082,16 @@ class FixProcessor { |
* |
* [exprPrecedence] - the effective precedence of [expr]. |
*/ |
- void _removeEnclosingParentheses(Expression expr, int exprPrecedence) { |
+ void _removeEnclosingParentheses( |
+ DartFileEditBuilder builder, Expression expr, int exprPrecedence) { |
while (expr.parent is ParenthesizedExpression) { |
ParenthesizedExpression parenthesized = |
expr.parent as ParenthesizedExpression; |
if (getExpressionParentPrecedence(parenthesized) > exprPrecedence) { |
break; |
} |
- _addRemoveEdit(range.token(parenthesized.leftParenthesis)); |
- _addRemoveEdit(range.token(parenthesized.rightParenthesis)); |
+ builder.addDeletion(range.token(parenthesized.leftParenthesis)); |
+ builder.addDeletion(range.token(parenthesized.rightParenthesis)); |
expr = parenthesized; |
} |
} |
@@ -3164,31 +3104,6 @@ class FixProcessor { |
} |
} |
- static void _addSuperTypeProposals(SourceBuilder sb, DartType type, |
- [Set<DartType> alreadyAdded]) { |
- alreadyAdded ??= new Set<DartType>(); |
- if (type is InterfaceType && alreadyAdded.add(type)) { |
- sb.addSuggestion(LinkedEditSuggestionKind.TYPE, type.displayName); |
- _addSuperTypeProposals(sb, type.superclass, alreadyAdded); |
- for (InterfaceType interfaceType in type.interfaces) { |
- _addSuperTypeProposals(sb, interfaceType, alreadyAdded); |
- } |
- } |
- } |
- |
- /** |
- * @return the suggestions for given [Type] and [DartExpression], not empty. |
- */ |
- static List<String> _getArgumentNameSuggestions( |
- Set<String> excluded, DartType type, Expression expression, int index) { |
- List<String> suggestions = |
- getVariableNameSuggestionsForExpression(type, expression, excluded); |
- if (suggestions.length != 0) { |
- return suggestions; |
- } |
- return <String>['arg$index']; |
- } |
- |
static bool _isNameOfType(String name) { |
if (name.isEmpty) { |
return false; |