Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Unified Diff: pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Issue 2916923002: Update a few more methods in FixProcessor, and fix some bugs in ChangeBuilder (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/correction/fix_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 77d91014e401b00f7c50605de72d9d8974b6cd91..4f4a0506dbf37cac3b44a2bdbf08e69afbb0d358 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -210,7 +210,8 @@ class FixProcessor {
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
_addFix_replaceWithConstInstanceCreation();
}
- if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT) {
+ if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT ||
+ errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) {
await _addFix_addAsync();
}
if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION) {
@@ -255,10 +256,10 @@ class FixProcessor {
_addFix_useEffectiveIntegerDivision();
}
if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
- _addFix_isNotNull();
+ await _addFix_isNotNull();
}
if (errorCode == HintCode.TYPE_CHECK_IS_NULL) {
- _addFix_isNull();
+ await _addFix_isNull();
}
if (errorCode == HintCode.UNDEFINED_GETTER) {
_addFix_undefinedClassAccessor_useSimilar();
@@ -282,7 +283,7 @@ class FixProcessor {
_addFix_removeUnusedImport();
}
if (errorCode == ParserErrorCode.EXPECTED_TOKEN) {
- _addFix_insertSemicolon();
+ await _addFix_insertSemicolon();
}
if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) {
_addFix_removeParameters_inGetterDeclaration();
@@ -294,7 +295,7 @@ class FixProcessor {
await _addFix_makeFieldNotFinal();
}
if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) {
- _addFix_makeEnclosingClassAbstract();
+ await _addFix_makeEnclosingClassAbstract();
}
if (errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS ||
errorCode ==
@@ -326,10 +327,10 @@ class FixProcessor {
StaticWarningCode
.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
// make class abstract
- _addFix_makeEnclosingClassAbstract();
+ await _addFix_makeEnclosingClassAbstract();
await _addFix_createNoSuchMethod();
// implement methods
- _addFix_createMissingOverrides();
+ await _addFix_createMissingOverrides();
}
if (errorCode == CompileTimeErrorCode.UNDEFINED_CLASS ||
errorCode == StaticWarningCode.CAST_TO_NON_TYPE ||
@@ -358,11 +359,8 @@ class FixProcessor {
await _addFix_importLibrary_withTopLevelVariable();
await _addFix_createLocalVariable();
}
- if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) {
- await _addFix_addAsync();
- }
if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) {
- _addFix_illegalAsyncReturnType();
+ await _addFix_illegalAsyncReturnType();
}
if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
_addFix_useStaticAccess_method();
@@ -375,7 +373,7 @@ class FixProcessor {
_addFix_removeParentheses_inGetterInvocation();
}
if (errorCode == StaticTypeWarningCode.NON_BOOL_CONDITION) {
- _addFix_nonBoolCondition_addNotNull();
+ await _addFix_nonBoolCondition_addNotNull();
}
if (errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT) {
await _addFix_importLibrary_withType();
@@ -1202,35 +1200,24 @@ class FixProcessor {
ClassMemberLocation targetLocation =
utils.prepareNewFieldLocation(targetClassNode);
// build method source
- String targetFile = targetClassElement.source.fullName;
- SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
- {
- sb.append(targetLocation.prefix);
- // maybe "static"
- if (staticModifier) {
- sb.append('static ');
- }
- // append type
+ Source targetSource = targetClassElement.source;
+ String targetFile = targetSource.fullName;
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(targetFile, targetSource.modificationStamp,
+ (DartFileEditBuilder builder) {
Expression fieldTypeNode = climbPropertyAccess(nameNode);
DartType fieldType = _inferUndefinedExpressionType(fieldTypeNode);
- _appendType(sb, fieldType, groupId: 'TYPE', orVar: true);
- // append name
- {
- sb.startPosition('NAME');
- sb.append(name);
- sb.endPosition();
- }
- sb.append(';');
- sb.append(targetLocation.suffix);
- }
- // insert source
- _insertBuilder(sb, targetClassElement);
- // add linked positions
- if (targetFile == file) {
- _addLinkedPosition('NAME', sb, range.node(node));
- }
- // add proposal
- _addFix(DartFixKind.CREATE_FIELD, [name]);
+ builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+ builder.write(targetLocation.prefix);
+ builder.writeFieldDeclaration(name,
+ isStatic: staticModifier,
+ nameGroupName: 'NAME',
+ type: fieldType,
+ typeGroupName: 'TYPE');
+ builder.write(targetLocation.suffix);
+ });
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FIELD, args: [name]);
}
void _addFix_createFunction_forFunctionType() {
@@ -1428,7 +1415,7 @@ class FixProcessor {
args: [name]);
}
- void _addFix_createMissingOverrides() {
+ Future<Null> _addFix_createMissingOverrides() async {
// prepare target
ClassDeclaration targetClass = node.parent as ClassDeclaration;
ClassElement targetClassElement = targetClass.element;
@@ -1452,60 +1439,65 @@ class FixProcessor {
}
return 1;
});
- // prepare SourceBuilder
+ int numElements = elements.length;
int insertOffset = targetClass.end - 1;
- SourceBuilder sb = new SourceBuilder(file, insertOffset);
- // EOL management
- bool isFirst = true;
- void addEolIfNotFirst() {
- if (!isFirst || utils.isClassWithEmptyBody(targetClass)) {
- sb.append(eol);
- }
- isFirst = false;
- }
-
- // merge getter/setter pairs into fields
String prefix = utils.getIndent(1);
- int numElements = elements.length;
- for (int i = 0; i < elements.length; i++) {
- ExecutableElement element = elements[i];
- if (element.kind == ElementKind.GETTER && i + 1 < elements.length) {
- ExecutableElement nextElement = elements[i + 1];
- if (nextElement.kind == ElementKind.SETTER) {
- // remove this and the next elements, adjust iterator
- elements.removeAt(i + 1);
- elements.removeAt(i);
- i--;
- numElements--;
- // separator
- addEolIfNotFirst();
- // @override
- {
- sb.append(prefix);
- sb.append('@override');
- sb.append(eol);
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder.addInsertion(insertOffset, (DartEditBuilder builder) {
+ // TODO(brianwilkerson) Compare with builder.writeOverrideOfInheritedMember
+ // The builder method doesn't merge getter/setter pairs into fields.
+ // EOL management
+ bool isFirst = true;
+ void addEolIfNotFirst() {
+ if (!isFirst || utils.isClassWithEmptyBody(targetClass)) {
+ builder.write(eol);
}
- // add field
- sb.append(prefix);
- _appendType(sb, element.type.returnType, orVar: true);
- sb.append(element.name);
- sb.append(';');
- sb.append(eol);
+ isFirst = false;
}
- }
- }
- // add elements
- for (ExecutableElement element in elements) {
- addEolIfNotFirst();
- _addFix_createMissingOverrides_single(sb, targetClass, element);
- }
- // add proposal
- exitPosition = new Position(file, insertOffset);
- _insertBuilder(sb, unitElement);
- _addFix(DartFixKind.CREATE_MISSING_OVERRIDES, [numElements]);
+
+ // merge getter/setter pairs into fields
+ for (int i = 0; i < elements.length; i++) {
+ ExecutableElement element = elements[i];
+ if (element.kind == ElementKind.GETTER && i + 1 < elements.length) {
+ ExecutableElement nextElement = elements[i + 1];
+ if (nextElement.kind == ElementKind.SETTER) {
+ // remove this and the next elements, adjust iterator
+ elements.removeAt(i + 1);
+ elements.removeAt(i);
+ i--;
+ numElements--;
+ // separator
+ addEolIfNotFirst();
+ // @override
+ builder.write(prefix);
+ builder.write('@override');
+ builder.write(eol);
+ // add field
+ builder.write(prefix);
+ builder.writeType(element.type.returnType, required: true);
+ builder.write(' ');
+ builder.write(element.name);
+ builder.write(';');
+ builder.write(eol);
+ }
+ }
+ }
+ // add elements
+ for (ExecutableElement element in elements) {
+ addEolIfNotFirst();
+ _addFix_createMissingOverridesForBuilder(
+ builder, targetClass, element);
+ }
+ });
+ });
+ changeBuilder.setSelection(new Position(file, insertOffset));
+ _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MISSING_OVERRIDES,
+ args: [numElements]);
}
- void _addFix_createMissingOverrides_single(SourceBuilder sb,
+ void _addFix_createMissingOverridesForBuilder(DartEditBuilder builder,
ClassDeclaration targetClass, ExecutableElement element) {
utils.targetExecutableElement = element;
// prepare environment
@@ -1517,50 +1509,51 @@ class FixProcessor {
bool isSetter = elementKind == ElementKind.SETTER;
bool isMethod = elementKind == ElementKind.METHOD;
bool isOperator = isMethod && (element as MethodElement).isOperator;
- sb.append(prefix);
+ builder.write(prefix);
if (isGetter) {
- sb.append('// TODO: implement ${element.displayName}');
- sb.append(eol);
- sb.append(prefix);
+ builder.write('// TODO: implement ${element.displayName}');
+ builder.write(eol);
+ builder.write(prefix);
}
// @override
- {
- sb.append('@override');
- sb.append(eol);
- sb.append(prefix);
- }
+ builder.write('@override');
+ builder.write(eol);
+ builder.write(prefix);
// return type
if (!isSetter) {
- _appendType(sb, element.type.returnType);
+ if (builder.writeType(element.type.returnType,
+ methodBeingCopied: element)) {
+ builder.write(' ');
+ }
}
// keyword
if (isGetter) {
- sb.append('get ');
+ builder.write('get ');
} else if (isSetter) {
- sb.append('set ');
+ builder.write('set ');
} else if (isOperator) {
- sb.append('operator ');
+ builder.write('operator ');
}
// name
- sb.append(element.displayName);
- _appendTypeParameters(sb, element.typeParameters);
+ builder.write(element.displayName);
+ builder.writeTypeParameters(element.typeParameters);
// parameters + body
if (isGetter) {
- sb.append(' => null;');
+ builder.write(' => null;');
} else {
List<ParameterElement> parameters = element.parameters;
- _appendParameters(sb, parameters);
- sb.append(' {');
+ builder.writeParameters(parameters, methodBeingCopied: element);
+ builder.write(' {');
// TO-DO
- sb.append(eol);
- sb.append(prefix2);
- sb.append('// TODO: implement ${element.displayName}');
- sb.append(eol);
+ builder.write(eol);
+ builder.write(prefix2);
+ builder.write('// TODO: implement ${element.displayName}');
+ builder.write(eol);
// close method
- sb.append(prefix);
- sb.append('}');
+ builder.write(prefix);
+ builder.write('}');
}
- sb.append(eol);
+ builder.write(eol);
utils.targetExecutableElement = null;
}
@@ -1602,12 +1595,16 @@ class FixProcessor {
}
}
- void _addFix_illegalAsyncReturnType() {
+ Future<Null> _addFix_illegalAsyncReturnType() async {
// prepare the existing type
TypeAnnotation typeName = node.getAncestor((n) => n is TypeAnnotation);
- _replaceTypeWithFuture(typeName, typeProvider);
- // add proposal
- _addFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, []);
+ TypeProvider typeProvider = this.typeProvider;
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder.replaceTypeWithFuture(typeName, typeProvider);
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE);
}
void _addFix_importLibrary(FixKind kind, Source library) {
@@ -1739,44 +1736,72 @@ class FixProcessor {
}
}
- void _addFix_insertSemicolon() {
+ Future<Null> _addFix_insertSemicolon() async {
if (error.message.contains("';'")) {
if (_isAwaitNode()) {
return;
}
int insertOffset = error.offset + error.length;
- _addInsertEdit(insertOffset, ';');
- _addFix(DartFixKind.INSERT_SEMICOLON, []);
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder.addInsertion(insertOffset, (DartEditBuilder builder) {
scheglov 2017/06/01 16:57:51 addSimpleInsertion() here and in several methods b
Brian Wilkerson 2017/06/01 22:30:29 Done
+ builder.write(';');
+ });
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.INSERT_SEMICOLON);
}
}
- void _addFix_isNotNull() {
+ Future<Null> _addFix_isNotNull() async {
if (coveredNode is IsExpression) {
IsExpression isExpression = coveredNode as IsExpression;
- _addReplaceEdit(
- range.endEnd(isExpression.expression, isExpression), ' != null');
- _addFix(DartFixKind.USE_NOT_EQ_NULL, []);
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder
+ .addReplacement(range.endEnd(isExpression.expression, isExpression),
+ (DartEditBuilder builder) {
+ builder.write(' != null');
+ });
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.USE_NOT_EQ_NULL);
}
}
- void _addFix_isNull() {
+ Future<Null> _addFix_isNull() async {
if (coveredNode is IsExpression) {
IsExpression isExpression = coveredNode as IsExpression;
- _addReplaceEdit(
- range.endEnd(isExpression.expression, isExpression), ' == null');
- _addFix(DartFixKind.USE_EQ_EQ_NULL, []);
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder
+ .addReplacement(range.endEnd(isExpression.expression, isExpression),
+ (DartEditBuilder builder) {
+ builder.write(' == null');
+ });
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.USE_EQ_EQ_NULL);
}
}
- void _addFix_makeEnclosingClassAbstract() {
+ Future<Null> _addFix_makeEnclosingClassAbstract() async {
ClassDeclaration enclosingClass =
node.getAncestor((node) => node is ClassDeclaration);
if (enclosingClass == null) {
return;
}
String className = enclosingClass.name.name;
- _addInsertEdit(enclosingClass.classKeyword.offset, 'abstract ');
- _addFix(DartFixKind.MAKE_CLASS_ABSTRACT, [className]);
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder.addInsertion(enclosingClass.classKeyword.offset,
+ (DartEditBuilder builder) {
+ builder.write('abstract ');
+ });
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_CLASS_ABSTRACT,
+ args: [className]);
}
Future<Null> _addFix_makeFieldNotFinal() async {
@@ -1799,23 +1824,39 @@ class FixProcessor {
Token keywordToken = declarationList.keyword;
if (declarationList.variables.length == 1 &&
keywordToken.keyword == Keyword.FINAL) {
- if (declarationList.type != null) {
- _addRemoveEdit(
- range.startStart(keywordToken, declarationList.type));
- } else {
- _addReplaceEdit(range.startStart(keywordToken, variable), 'var ');
- }
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ if (declarationList.type != null) {
+ builder.addReplacement(
+ range.startStart(keywordToken, declarationList.type),
+ (DartEditBuilder builder) {});
+ } else {
+ builder.addReplacement(range.startStart(keywordToken, variable),
+ (DartEditBuilder builder) {
+ builder.write('var ');
+ });
+ }
+ });
String fieldName = getter.variable.displayName;
- _addFix(DartFixKind.MAKE_FIELD_NOT_FINAL, [fieldName]);
+ _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_FIELD_NOT_FINAL,
+ args: [fieldName]);
}
}
}
}
}
- void _addFix_nonBoolCondition_addNotNull() {
- _addInsertEdit(error.offset + error.length, ' != null');
- _addFix(DartFixKind.ADD_NE_NULL, []);
+ Future<Null> _addFix_nonBoolCondition_addNotNull() async {
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(driver);
+ await changeBuilder.addFileEdit(file, fileStamp,
+ (DartFileEditBuilder builder) {
+ builder.addInsertion(error.offset + error.length,
+ (DartEditBuilder builder) {
+ builder.write(' != null');
+ });
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL);
}
void _addFix_removeAwait() {
@@ -2804,31 +2845,6 @@ class FixProcessor {
}
}
- void _appendTypeParameter(
- SourceBuilder sb, TypeParameterElement typeParameter) {
- sb.append(typeParameter.name);
- if (typeParameter.bound != null) {
- sb.append(' extends ');
- _appendType(sb, typeParameter.bound, trailingSpace: false);
- }
- }
-
- void _appendTypeParameters(
- SourceBuilder sb, List<TypeParameterElement> typeParameters) {
- if (typeParameters.isNotEmpty) {
- sb.append('<');
- bool isFirst = true;
- for (TypeParameterElement typeParameter in typeParameters) {
- if (!isFirst) {
- sb.append(', ');
- }
- isFirst = false;
- _appendTypeParameter(sb, typeParameter);
- }
- sb.append('>');
- }
- }
-
/**
* Computes the name of the library at the given [path].
* See https://www.dartlang.org/articles/style-guide/#names for conventions.
@@ -3153,29 +3169,6 @@ class FixProcessor {
}
}
- void _replaceTypeWithFuture(
- TypeAnnotation typeName, TypeProvider typeProvider) {
- InterfaceType futureType = typeProvider.futureType;
- // validate the type
- DartType type = typeName?.type;
- if (type == null ||
- type.isDynamic ||
- type is InterfaceType && type.element == futureType.element) {
- return;
- }
- // prepare code for the types
- String futureTypeCode = utils.getTypeSource(futureType, librariesToImport);
- String nodeCode = utils.getNodeText(typeName);
- // wrap the existing type with Future
- String returnTypeCode;
- if (nodeCode == 'void') {
- returnTypeCode = futureTypeCode;
- } else {
- returnTypeCode = '$futureTypeCode<$nodeCode>';
- }
- _addReplaceEdit(range.node(typeName), returnTypeCode);
- }
-
void _updateFinderWithClassMembers(
_ClosestElementFinder finder, ClassElement clazz) {
if (clazz != null) {
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/correction/fix_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698