Skip to content

Commit

Permalink
Issue 52543. Support for 'remove comparison' fix for IfElement.
Browse files Browse the repository at this point in the history
Bug: #52543
Change-Id: Ibeecc42db2135d507ed8f74f5a4888fb122b131f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306312
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
  • Loading branch information
scheglov authored and Commit Queue committed May 30, 2023
1 parent b930228 commit dfb7e50
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,42 @@ class RemoveComparison extends CorrectionProducer {
(type == TokenType.BAR_BAR && _conditionIsFalse)) {
await _removeOperatorAndOperand(builder, parent);
}
} else if (parent is IfElement) {
await _ifElement(parent, builder);
} else if (parent is IfStatement) {
if (parent.elseStatement == null && _conditionIsTrue) {
await _ifStatement(parent, builder);
}
}
}

Future<void> _ifElement(IfElement node, ChangeBuilder builder) async {
if (_conditionIsTrue) {
await builder.addDartFileEdit(file, (builder) {
final text = _textWithLeadingComments(node.thenElement);
final unIndented = utils.indentLeft(text);
builder.addSimpleReplacement(range.node(node), unIndented);
});
} else if (_conditionIsFalse) {
final elseElement = node.elseElement;
if (elseElement != null) {
await builder.addDartFileEdit(file, (builder) {
final text = _textWithLeadingComments(elseElement);
final unIndented = utils.indentLeft(text);
builder.addSimpleReplacement(range.node(node), unIndented);
});
} else {
final elements = node.parent.containerElements;
if (elements != null) {
await builder.addDartFileEdit(file, (builder) {
final nodeRange = range.nodeInList(elements, node);
builder.addDeletion(nodeRange);
});
}
}
}
}

Future<void> _ifStatement(IfStatement node, ChangeBuilder builder) async {
await builder.addDartFileEdit(file, (builder) {
var nodeRange = utils.getLinesRangeStatements([node]);
Expand Down Expand Up @@ -127,4 +156,20 @@ class RemoveComparison extends CorrectionProducer {
builder.addDeletion(operatorAndOperand);
});
}

String _textWithLeadingComments(AstNode node) {
return utils.getNodeText(node, withLeadingComments: true);
}
}

extension on AstNode? {
NodeList<AstNode>? get containerElements {
final self = this;
if (self is ListLiteral) {
return self.elements;
} else if (self is SetOrMapLiteral) {
return self.elements;
}
return null;
}
}
35 changes: 33 additions & 2 deletions pkg/analysis_server/lib/src/services/correction/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -876,8 +876,17 @@ class CorrectionUtils {
}

/// Returns the text of the given [AstNode] in the unit.
String getNodeText(AstNode node) {
return getText(node.offset, node.length);
String getNodeText(
AstNode node, {
bool withLeadingComments = false,
}) {
final firstToken = withLeadingComments
? node.beginToken.precedingComments ?? node.beginToken
: node.beginToken;
final offset = firstToken.offset;
final end = node.endToken.end;
final length = end - offset;
return getText(offset, length);
}

/// Returns the line prefix consisting of spaces and tabs on the left from the
Expand Down Expand Up @@ -975,6 +984,28 @@ class CorrectionUtils {
throw UnimplementedError('(${type.runtimeType}) $type');
}

/// Splits [text] into lines, and removes one level of indent from each line.
/// Lines that don't start with indentation are left as is.
String indentLeft(String text) {
final buffer = StringBuffer();
final indent = getIndent(1);
final eol = endOfLine;
final lines = text.split(eol);
for (final line in lines) {
if (buffer.isNotEmpty) {
buffer.write(eol);
}
final String updatedLine;
if (line.startsWith(indent)) {
updatedLine = line.substring(indent.length);
} else {
updatedLine = line;
}
buffer.write(updatedLine);
}
return buffer.toString();
}

/// Indents given source left or right.
String indentSourceLeftRight(String source, {bool indentLeft = true}) {
var sb = StringBuffer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,189 @@ void f(String s) {
''');
}

Future<void> test_ifElement_alwaysFalse_hasElse() async {
await resolveTestCode('''
void f(int x) {
[
0,
if (x == null) 1 else -1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
-1,
2,
];
}
''');
}

Future<void> test_ifElement_alwaysFalse_hasElse_withComments() async {
await resolveTestCode('''
void f(int x) {
[
0,
// C1
if (x == null)
// C2
1
else
// C3
-1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
// C1
// C3
-1,
2,
];
}
''');
}

Future<void> test_ifElement_alwaysFalse_noElse_insideList() async {
await resolveTestCode('''
void f(int x) {
[
0,
if (x == null) 1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
2,
];
}
''');
}

Future<void>
test_ifElement_alwaysFalse_noElse_insideList_withComments() async {
await resolveTestCode('''
void f(int x) {
[
0,
// C1
if (x == null)
// C2
1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
2,
];
}
''');
}

Future<void> test_ifElement_alwaysFalse_noElse_insideSet() async {
await resolveTestCode('''
Object f(int x) {
return {
0,
if (x == null) 1,
2,
};
}
''');
await assertHasFix('''
Object f(int x) {
return {
0,
2,
};
}
''');
}

Future<void> test_ifElement_alwaysTrue() async {
await resolveTestCode('''
void f(int x) {
[
0,
if (x != null)
1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
1,
2,
];
}
''');
}

Future<void> test_ifElement_alwaysTrue_hasElse() async {
await resolveTestCode('''
void f(int x) {
[
0,
if (x != null) 1 else -1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
1,
2,
];
}
''');
}

Future<void> test_ifElement_alwaysTrue_withComments() async {
await resolveTestCode('''
void f(int x) {
[
0,
// C1
if (x != null)
// C2
1,
2,
];
}
''');
await assertHasFix('''
void f(int x) {
[
0,
// C1
// C2
1,
2,
];
}
''');
}

Future<void> test_ifStatement_thenBlock() async {
await resolveTestCode('''
void f(String s) {
Expand Down

0 comments on commit dfb7e50

Please sign in to comment.