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 17c7822649c962ded4c1e1a764a52d0303d1e66a..b64f4289f66c8c1fade91fcb0184cd1e52ed53ee 100644 |
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart |
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart |
@@ -697,14 +697,12 @@ class FixProcessor { |
} |
} |
// prepare location for a new constructor |
- _ConstructorLocation targetLocation = |
+ _ClassMemberLocation targetLocation = |
_prepareNewConstructorLocation(classDeclaration); |
// build constructor source |
SourceBuilder sb = new SourceBuilder(file, targetLocation.offset); |
{ |
- String indent = ' '; |
sb.append(targetLocation.prefix); |
- sb.append(indent); |
sb.append(classDeclaration.name.name); |
sb.append('('); |
sb.append(fieldNames.map((name) => 'this.$name').join(', ')); |
@@ -743,19 +741,17 @@ class FixProcessor { |
if (targetTypeNode is! ClassDeclaration) { |
return; |
} |
- _ConstructorLocation targetLocation = |
+ _ClassMemberLocation targetLocation = |
_prepareNewConstructorLocation(targetTypeNode); |
String targetFile = targetElement.source.fullName; |
// build method source |
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset); |
{ |
- String indent = ' '; |
sb.append(targetLocation.prefix); |
- sb.append(indent); |
sb.append(targetElement.name); |
_addFix_undefinedMethod_create_parameters( |
sb, instanceCreation.argumentList); |
- sb.append(') {$eol$indent}'); |
+ sb.append(');'); |
sb.append(targetLocation.suffix); |
} |
// insert source |
@@ -801,15 +797,13 @@ class FixProcessor { |
if (targetTypeNode is! ClassDeclaration) { |
return; |
} |
- _ConstructorLocation targetLocation = |
+ _ClassMemberLocation targetLocation = |
_prepareNewConstructorLocation(targetTypeNode); |
String targetFile = targetElement.source.fullName; |
// build method source |
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset); |
{ |
- String indent = ' '; |
sb.append(targetLocation.prefix); |
- sb.append(indent); |
sb.append(targetElement.name); |
sb.append('.'); |
// append name |
@@ -820,7 +814,7 @@ class FixProcessor { |
} |
_addFix_undefinedMethod_create_parameters( |
sb, instanceCreation.argumentList); |
- sb.append(') {$eol$indent}'); |
+ sb.append(');'); |
sb.append(targetLocation.suffix); |
} |
// insert source |
@@ -941,13 +935,11 @@ class FixProcessor { |
argumentsBuffer.append(parameterName); |
} |
// add proposal |
- _ConstructorLocation targetLocation = |
+ _ClassMemberLocation targetLocation = |
_prepareNewConstructorLocation(targetClassNode); |
SourceBuilder sb = new SourceBuilder(file, targetLocation.offset); |
{ |
- String indent = utils.getIndent(1); |
sb.append(targetLocation.prefix); |
- sb.append(indent); |
sb.append(targetClassName); |
if (!constructorName.isEmpty) { |
sb.startPosition('NAME'); |
@@ -1025,7 +1017,8 @@ class FixProcessor { |
} |
ClassDeclaration targetClassNode = targetTypeNode; |
// prepare location |
- _FieldLocation targetLocation = _prepareNewFieldLocation(targetClassNode); |
+ _ClassMemberLocation targetLocation = |
+ _prepareNewFieldLocation(targetClassNode); |
// build method source |
String targetFile = targetClassElement.source.fullName; |
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset); |
@@ -1157,7 +1150,8 @@ class FixProcessor { |
} |
ClassDeclaration targetClassNode = targetTypeNode; |
// prepare location |
- _FieldLocation targetLocation = _prepareNewGetterLocation(targetClassNode); |
+ _ClassMemberLocation targetLocation = |
+ _prepareNewGetterLocation(targetClassNode); |
// build method source |
String targetFile = targetClassElement.source.fullName; |
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset); |
@@ -1284,7 +1278,7 @@ class FixProcessor { |
// EOL management |
bool isFirst = true; |
void addEolIfNotFirst() { |
- if (!isFirst || !targetClass.members.isEmpty) { |
+ if (!isFirst || _isClassWithEmptyBody(targetClass)) { |
sb.append(eol); |
} |
isFirst = false; |
@@ -2739,74 +2733,62 @@ class FixProcessor { |
return node is SimpleIdentifier && node.name == 'await'; |
} |
- _ConstructorLocation _prepareNewConstructorLocation( |
- ClassDeclaration classDeclaration) { |
- List<ClassMember> members = classDeclaration.members; |
- // find the last field/constructor |
- ClassMember lastFieldOrConstructor = null; |
- for (ClassMember member in members) { |
- if (member is FieldDeclaration || member is ConstructorDeclaration) { |
- lastFieldOrConstructor = member; |
- } else { |
- break; |
- } |
- } |
- // after the last field/constructor |
- if (lastFieldOrConstructor != null) { |
- return new _ConstructorLocation( |
- eol + eol, lastFieldOrConstructor.end, ''); |
- } |
- // at the beginning of the class |
- String suffix = members.isEmpty ? '' : eol; |
- return new _ConstructorLocation( |
- eol, classDeclaration.leftBracket.end, suffix); |
+ /** |
+ * Return `true` if the given [classDeclaration] has open '{' and close '}' |
+ * at the same line, e.g. `class X {}`. |
+ */ |
+ bool _isClassWithEmptyBody(ClassDeclaration classDeclaration) { |
+ return utils.getLineThis(classDeclaration.leftBracket.offset) == |
+ utils.getLineThis(classDeclaration.rightBracket.offset); |
} |
- _FieldLocation _prepareNewFieldLocation(ClassDeclaration classDeclaration) { |
+ _ClassMemberLocation _prepareNewClassMemberLocation( |
+ ClassDeclaration classDeclaration, |
+ bool shouldSkip(ClassMember existingMember)) { |
String indent = utils.getIndent(1); |
- // find the last field |
- ClassMember lastFieldOrConstructor = null; |
+ // Find the last target member. |
+ ClassMember targetMember = null; |
List<ClassMember> members = classDeclaration.members; |
for (ClassMember member in members) { |
- if (member is FieldDeclaration) { |
- lastFieldOrConstructor = member; |
+ if (shouldSkip(member)) { |
+ targetMember = member; |
} else { |
break; |
} |
} |
- // after the last field |
- if (lastFieldOrConstructor != null) { |
- return new _FieldLocation( |
- eol + eol + indent, lastFieldOrConstructor.end, ''); |
+ // After the last target member. |
+ if (targetMember != null) { |
+ return new _ClassMemberLocation(eol + eol + indent, targetMember.end, ''); |
} |
- // at the beginning of the class |
- String suffix = members.isEmpty ? '' : eol; |
- return new _FieldLocation( |
+ // At the beginning of the class. |
+ String suffix = members.isNotEmpty || |
+ _isClassWithEmptyBody(classDeclaration) ? eol : ''; |
+ return new _ClassMemberLocation( |
eol + indent, classDeclaration.leftBracket.end, suffix); |
} |
- _FieldLocation _prepareNewGetterLocation(ClassDeclaration classDeclaration) { |
- String indent = utils.getIndent(1); |
- // find an existing target member |
- ClassMember prevMember = null; |
- List<ClassMember> members = classDeclaration.members; |
- for (ClassMember member in members) { |
- if (member is FieldDeclaration || |
- member is ConstructorDeclaration || |
- member is MethodDeclaration && member.isGetter) { |
- prevMember = member; |
- } else { |
- break; |
- } |
- } |
- // after the last field/getter |
- if (prevMember != null) { |
- return new _FieldLocation(eol + eol + indent, prevMember.end, ''); |
- } |
- // at the beginning of the class |
- String suffix = members.isEmpty ? '' : eol; |
- return new _FieldLocation( |
- eol + indent, classDeclaration.leftBracket.end, suffix); |
+ _ClassMemberLocation _prepareNewConstructorLocation( |
+ ClassDeclaration classDeclaration) { |
+ return _prepareNewClassMemberLocation( |
+ classDeclaration, |
+ (member) => |
+ member is FieldDeclaration || member is ConstructorDeclaration); |
+ } |
+ |
+ _ClassMemberLocation _prepareNewFieldLocation( |
+ ClassDeclaration classDeclaration) { |
+ return _prepareNewClassMemberLocation( |
+ classDeclaration, (member) => member is FieldDeclaration); |
+ } |
+ |
+ _ClassMemberLocation _prepareNewGetterLocation( |
+ ClassDeclaration classDeclaration) { |
+ return _prepareNewClassMemberLocation( |
+ classDeclaration, |
+ (member) => |
+ member is FieldDeclaration || |
+ member is ConstructorDeclaration || |
+ member is MethodDeclaration && member.isGetter); |
} |
/** |
@@ -2928,6 +2910,17 @@ class LintNames { |
} |
/** |
+ * Describes the location for a newly created [ClassMember]. |
+ */ |
+class _ClassMemberLocation { |
+ final String prefix; |
+ final int offset; |
+ final String suffix; |
+ |
+ _ClassMemberLocation(this.prefix, this.offset, this.suffix); |
+} |
+ |
+/** |
* Helper for finding [Element] with name closest to the given. |
*/ |
class _ClosestElementFinder { |
@@ -2955,25 +2948,3 @@ class _ClosestElementFinder { |
} |
} |
} |
- |
-/** |
- * Describes the location for a newly created [ConstructorDeclaration]. |
- */ |
-class _ConstructorLocation { |
- final String prefix; |
- final int offset; |
- final String suffix; |
- |
- _ConstructorLocation(this.prefix, this.offset, this.suffix); |
-} |
- |
-/** |
- * Describes the location for a newly created [FieldDeclaration]. |
- */ |
-class _FieldLocation { |
- final String prefix; |
- final int offset; |
- final String suffix; |
- |
- _FieldLocation(this.prefix, this.offset, this.suffix); |
-} |