mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 12:47:14 +00:00
Issue 26335. Insert an empty line if the class body is a single line.
R=brianwilkerson@google.com BUG= https://github.com/dart-lang/sdk/issues/26335 Review URL: https://codereview.chromium.org/2256463002 .
This commit is contained in:
parent
462204e557
commit
010578b88a
|
@ -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(
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
_ClassMemberLocation _prepareNewClassMemberLocation(
|
||||
ClassDeclaration classDeclaration,
|
||||
bool shouldSkip(ClassMember existingMember)) {
|
||||
String indent = utils.getIndent(1);
|
||||
// Find the last target member.
|
||||
ClassMember targetMember = null;
|
||||
List<ClassMember> members = classDeclaration.members;
|
||||
for (ClassMember member in members) {
|
||||
if (shouldSkip(member)) {
|
||||
targetMember = member;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 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.isNotEmpty ||
|
||||
_isClassWithEmptyBody(classDeclaration) ? eol : '';
|
||||
return new _ClassMemberLocation(
|
||||
eol + indent, classDeclaration.leftBracket.end, suffix);
|
||||
}
|
||||
|
||||
_ClassMemberLocation _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 _prepareNewClassMemberLocation(
|
||||
classDeclaration,
|
||||
(member) =>
|
||||
member is FieldDeclaration || member is ConstructorDeclaration);
|
||||
}
|
||||
|
||||
_FieldLocation _prepareNewFieldLocation(ClassDeclaration classDeclaration) {
|
||||
String indent = utils.getIndent(1);
|
||||
// find the last field
|
||||
ClassMember lastFieldOrConstructor = null;
|
||||
List<ClassMember> members = classDeclaration.members;
|
||||
for (ClassMember member in members) {
|
||||
if (member is FieldDeclaration) {
|
||||
lastFieldOrConstructor = member;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// after the last field
|
||||
if (lastFieldOrConstructor != null) {
|
||||
return new _FieldLocation(
|
||||
eol + eol + indent, lastFieldOrConstructor.end, '');
|
||||
}
|
||||
// at the beginning of the class
|
||||
String suffix = members.isEmpty ? '' : eol;
|
||||
return new _FieldLocation(
|
||||
eol + indent, classDeclaration.leftBracket.end, suffix);
|
||||
_ClassMemberLocation _prepareNewFieldLocation(
|
||||
ClassDeclaration classDeclaration) {
|
||||
return _prepareNewClassMemberLocation(
|
||||
classDeclaration, (member) => member is FieldDeclaration);
|
||||
}
|
||||
|
||||
_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 _prepareNewGetterLocation(
|
||||
ClassDeclaration classDeclaration) {
|
||||
return _prepareNewClassMemberLocation(
|
||||
classDeclaration,
|
||||
(member) =>
|
||||
member is FieldDeclaration ||
|
||||
member is ConstructorDeclaration ||
|
||||
member is MethodDeclaration && member.isGetter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2927,6 +2909,17 @@ class LintNames {
|
|||
static const String annotate_overrides = 'annotate_overrides';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -1011,8 +1011,7 @@ main() {
|
|||
class A {
|
||||
int field;
|
||||
|
||||
A(int i, double d) {
|
||||
}
|
||||
A(int i, double d);
|
||||
|
||||
method() {}
|
||||
}
|
||||
|
@ -1035,8 +1034,7 @@ main() {
|
|||
DartFixKind.CREATE_CONSTRUCTOR,
|
||||
'''
|
||||
class A {
|
||||
A.named(int i, double d) {
|
||||
}
|
||||
A.named(int i, double d);
|
||||
|
||||
method() {}
|
||||
}
|
||||
|
@ -1047,6 +1045,26 @@ main() {
|
|||
_assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
|
||||
}
|
||||
|
||||
test_createConstructor_named_emptyClassBody() async {
|
||||
resolveTestUnit('''
|
||||
class A {}
|
||||
main() {
|
||||
new A.named(1);
|
||||
}
|
||||
''');
|
||||
await assertHasFix(
|
||||
DartFixKind.CREATE_CONSTRUCTOR,
|
||||
'''
|
||||
class A {
|
||||
A.named(int i);
|
||||
}
|
||||
main() {
|
||||
new A.named(1);
|
||||
}
|
||||
''');
|
||||
_assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
|
||||
}
|
||||
|
||||
test_createConstructorForFinalFields_inTopLevelMethod() async {
|
||||
resolveTestUnit('''
|
||||
main() {
|
||||
|
@ -2569,6 +2587,30 @@ class B extends A {
|
|||
}
|
||||
}
|
||||
|
||||
test_createMissingOverrides_method_emptyClassBody() async {
|
||||
resolveTestUnit('''
|
||||
abstract class A {
|
||||
void foo();
|
||||
}
|
||||
|
||||
class B extends A {}
|
||||
''');
|
||||
await assertHasFix(
|
||||
DartFixKind.CREATE_MISSING_OVERRIDES,
|
||||
'''
|
||||
abstract class A {
|
||||
void foo();
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
@override
|
||||
void foo() {
|
||||
// TODO: implement foo
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
test_createMissingOverrides_operator() async {
|
||||
resolveTestUnit('''
|
||||
abstract class A {
|
||||
|
|
Loading…
Reference in a new issue