Migrate several lib/src/services/correction/dart/
R=brianwilkerson@google.com Change-Id: I7957e3fa724e618e6cf8c6a94344b0b4057aa080 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195041 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
c1339411bb
commit
81be9be4a6
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analysis_server/src/services/correction/util.dart';
|
||||
@@ -16,7 +14,7 @@ import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class RenameToCamelCase extends CorrectionProducer {
|
||||
/// The camel-case version of the name.
|
||||
String _newName;
|
||||
String _newName = '';
|
||||
|
||||
@override
|
||||
List<Object> get fixArguments => [_newName];
|
||||
@@ -29,10 +27,10 @@ class RenameToCamelCase extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
if (node is! SimpleIdentifier) {
|
||||
var identifier = node;
|
||||
if (identifier is! SimpleIdentifier) {
|
||||
return;
|
||||
}
|
||||
SimpleIdentifier identifier = node;
|
||||
|
||||
// Prepare the new name.
|
||||
var words = identifier.name.split('_');
|
||||
@@ -42,17 +40,21 @@ class RenameToCamelCase extends CorrectionProducer {
|
||||
_newName = words.first + words.skip(1).map((w) => capitalize(w)).join();
|
||||
|
||||
// Find references to the identifier.
|
||||
List<SimpleIdentifier> references;
|
||||
List<SimpleIdentifier>? references;
|
||||
var element = identifier.staticElement;
|
||||
if (element is LocalVariableElement) {
|
||||
AstNode root = node.thisOrAncestorOfType<Block>();
|
||||
references = findLocalElementReferences(root, element);
|
||||
var root = node.thisOrAncestorOfType<Block>();
|
||||
if (root != null) {
|
||||
references = findLocalElementReferences(root, element);
|
||||
}
|
||||
} else if (element is ParameterElement) {
|
||||
if (!element.isNamed) {
|
||||
var root = node.thisOrAncestorMatching((node) =>
|
||||
node.parent is ClassOrMixinDeclaration ||
|
||||
node.parent is CompilationUnit);
|
||||
references = findLocalElementReferences(root, element);
|
||||
if (root != null) {
|
||||
references = findLocalElementReferences(root, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (references == null) {
|
||||
@@ -60,8 +62,9 @@ class RenameToCamelCase extends CorrectionProducer {
|
||||
}
|
||||
|
||||
// Compute the change.
|
||||
var references_final = references;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
for (var reference in references) {
|
||||
for (var reference in references_final) {
|
||||
builder.addSimpleReplacement(range.node(reference), _newName);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
@@ -19,8 +18,13 @@ class ReplaceBooleanWithBool extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
final analysisError = diagnostic;
|
||||
if (analysisError is! AnalysisError) {
|
||||
return;
|
||||
}
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.error(diagnostic), 'bool');
|
||||
builder.addSimpleReplacement(range.error(analysisError), 'bool');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+16
-12
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -31,29 +29,35 @@ class ReplaceCascadeWithDot extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var node = this.node;
|
||||
if (node is CascadeExpression) {
|
||||
var sections = node.cascadeSections;
|
||||
if (sections.length == 1) {
|
||||
await _replaceFor(builder, sections[0]);
|
||||
}
|
||||
final cascadeExpression = node;
|
||||
if (cascadeExpression is! CascadeExpression) {
|
||||
return;
|
||||
}
|
||||
|
||||
var sections = cascadeExpression.cascadeSections;
|
||||
if (sections.length == 1) {
|
||||
await _replaceFor(builder, sections[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _replaceFor(ChangeBuilder builder, Expression section) async {
|
||||
Future<void> _replaceFor(ChangeBuilder builder, Expression? section) async {
|
||||
if (section is AssignmentExpression) {
|
||||
return _replaceFor(builder, section.leftHandSide);
|
||||
}
|
||||
|
||||
if (section is IndexExpression) {
|
||||
if (section.period != null) {
|
||||
return _replaceToken(builder, section.period, _indexReplacement);
|
||||
var period = section.period;
|
||||
if (period != null) {
|
||||
return _replaceToken(builder, period, _indexReplacement);
|
||||
}
|
||||
return _replaceFor(builder, section.target);
|
||||
}
|
||||
|
||||
if (section is MethodInvocation) {
|
||||
return _replaceToken(builder, section.operator, _propertyReplacement);
|
||||
var operator = section.operator;
|
||||
if (operator != null) {
|
||||
return _replaceToken(builder, operator, _propertyReplacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (section is PropertyAccess) {
|
||||
|
||||
+12
-7
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,12 +18,19 @@ class ReplaceColonWithEquals extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
if (node is DefaultFormalParameter) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(
|
||||
range.token((node as DefaultFormalParameter).separator), ' =');
|
||||
});
|
||||
final node = this.node;
|
||||
if (node is! DefaultFormalParameter) {
|
||||
return;
|
||||
}
|
||||
|
||||
var separator = node.separator;
|
||||
if (separator == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.token(separator), ' =');
|
||||
});
|
||||
}
|
||||
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
|
||||
+84
-75
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
@@ -18,58 +16,98 @@ class ReplaceConditionalWithIfElse extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
ConditionalExpression conditional;
|
||||
// may be on Statement with Conditional
|
||||
var statement = node.thisOrAncestorOfType<Statement>();
|
||||
if (statement == null) {
|
||||
return;
|
||||
}
|
||||
// variable declaration
|
||||
var inVariable = false;
|
||||
if (statement is VariableDeclarationStatement) {
|
||||
var variableStatement = statement;
|
||||
for (var variable in variableStatement.variables.variables) {
|
||||
if (variable.initializer is ConditionalExpression) {
|
||||
conditional = variable.initializer as ConditionalExpression;
|
||||
inVariable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// assignment
|
||||
var inAssignment = false;
|
||||
if (statement is ExpressionStatement) {
|
||||
var exprStmt = statement;
|
||||
if (exprStmt.expression is AssignmentExpression) {
|
||||
var assignment = exprStmt.expression as AssignmentExpression;
|
||||
if (assignment.operator.type == TokenType.EQ &&
|
||||
assignment.rightHandSide is ConditionalExpression) {
|
||||
conditional = assignment.rightHandSide as ConditionalExpression;
|
||||
inAssignment = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// return
|
||||
var inReturn = false;
|
||||
if (statement is ReturnStatement) {
|
||||
var returnStatement = statement;
|
||||
if (returnStatement.expression is ConditionalExpression) {
|
||||
conditional = returnStatement.expression as ConditionalExpression;
|
||||
inReturn = true;
|
||||
}
|
||||
}
|
||||
// prepare environment
|
||||
var indent = utils.getIndent(1);
|
||||
var prefix = utils.getNodePrefix(statement);
|
||||
|
||||
if (inVariable || inAssignment || inReturn) {
|
||||
// Type v = conditional;
|
||||
if (statement is VariableDeclarationStatement) {
|
||||
return _variableDeclarationStatement(builder, statement);
|
||||
}
|
||||
|
||||
// v = conditional;
|
||||
if (statement is ExpressionStatement) {
|
||||
var expression = statement.expression;
|
||||
if (expression is AssignmentExpression) {
|
||||
return _assignmentExpression(builder, statement, expression);
|
||||
}
|
||||
}
|
||||
|
||||
// return conditional;
|
||||
if (statement is ReturnStatement) {
|
||||
return _returnStatement(builder, statement);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _assignmentExpression(
|
||||
ChangeBuilder builder,
|
||||
ExpressionStatement statement,
|
||||
AssignmentExpression assignment,
|
||||
) async {
|
||||
var conditional = assignment.rightHandSide;
|
||||
if (assignment.operator.type == TokenType.EQ &&
|
||||
conditional is ConditionalExpression) {
|
||||
var indent = utils.getIndent(1);
|
||||
var prefix = utils.getNodePrefix(statement);
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
// Type v = Conditional;
|
||||
if (inVariable) {
|
||||
var leftSide = assignment.leftHandSide;
|
||||
var conditionSrc = utils.getNodeText(conditional.condition);
|
||||
var thenSrc = utils.getNodeText(conditional.thenExpression);
|
||||
var elseSrc = utils.getNodeText(conditional.elseExpression);
|
||||
var name = utils.getNodeText(leftSide);
|
||||
var src = '';
|
||||
src += 'if ($conditionSrc) {' + eol;
|
||||
src += prefix + indent + '$name = $thenSrc;' + eol;
|
||||
src += prefix + '} else {' + eol;
|
||||
src += prefix + indent + '$name = $elseSrc;' + eol;
|
||||
src += prefix + '}';
|
||||
builder.addSimpleReplacement(range.node(statement), src);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _returnStatement(
|
||||
ChangeBuilder builder,
|
||||
ReturnStatement statement,
|
||||
) async {
|
||||
var conditional = statement.expression;
|
||||
if (conditional is ConditionalExpression) {
|
||||
var indent = utils.getIndent(1);
|
||||
var prefix = utils.getNodePrefix(statement);
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
var conditionSrc = utils.getNodeText(conditional.condition);
|
||||
var thenSrc = utils.getNodeText(conditional.thenExpression);
|
||||
var elseSrc = utils.getNodeText(conditional.elseExpression);
|
||||
var src = '';
|
||||
src += 'if ($conditionSrc) {' + eol;
|
||||
src += prefix + indent + 'return $thenSrc;' + eol;
|
||||
src += prefix + '} else {' + eol;
|
||||
src += prefix + indent + 'return $elseSrc;' + eol;
|
||||
src += prefix + '}';
|
||||
builder.addSimpleReplacement(range.node(statement), src);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _variableDeclarationStatement(
|
||||
ChangeBuilder builder,
|
||||
VariableDeclarationStatement statement,
|
||||
) async {
|
||||
for (var variable in statement.variables.variables) {
|
||||
var conditional = variable.initializer;
|
||||
if (conditional is ConditionalExpression) {
|
||||
var indent = utils.getIndent(1);
|
||||
var prefix = utils.getNodePrefix(statement);
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
var variable = conditional.parent as VariableDeclaration;
|
||||
var variableList = variable.parent as VariableDeclarationList;
|
||||
if (variableList.type == null) {
|
||||
var type = variable.declaredElement.type;
|
||||
var type = variable.declaredElement!.type;
|
||||
var keyword = variableList.keyword;
|
||||
if (keyword != null && keyword.keyword == Keyword.VAR) {
|
||||
builder.addReplacement(range.token(keyword), (builder) {
|
||||
@@ -94,37 +132,8 @@ class ReplaceConditionalWithIfElse extends CorrectionProducer {
|
||||
src += prefix + indent + '$name = $elseSrc;' + eol;
|
||||
src += prefix + '}';
|
||||
builder.addSimpleReplacement(range.endLength(statement, 0), src);
|
||||
}
|
||||
// v = Conditional;
|
||||
if (inAssignment) {
|
||||
var assignment = conditional.parent as AssignmentExpression;
|
||||
var leftSide = assignment.leftHandSide;
|
||||
var conditionSrc = utils.getNodeText(conditional.condition);
|
||||
var thenSrc = utils.getNodeText(conditional.thenExpression);
|
||||
var elseSrc = utils.getNodeText(conditional.elseExpression);
|
||||
var name = utils.getNodeText(leftSide);
|
||||
var src = '';
|
||||
src += 'if ($conditionSrc) {' + eol;
|
||||
src += prefix + indent + '$name = $thenSrc;' + eol;
|
||||
src += prefix + '} else {' + eol;
|
||||
src += prefix + indent + '$name = $elseSrc;' + eol;
|
||||
src += prefix + '}';
|
||||
builder.addSimpleReplacement(range.node(statement), src);
|
||||
}
|
||||
// return Conditional;
|
||||
if (inReturn) {
|
||||
var conditionSrc = utils.getNodeText(conditional.condition);
|
||||
var thenSrc = utils.getNodeText(conditional.thenExpression);
|
||||
var elseSrc = utils.getNodeText(conditional.elseExpression);
|
||||
var src = '';
|
||||
src += 'if ($conditionSrc) {' + eol;
|
||||
src += prefix + indent + 'return $thenSrc;' + eol;
|
||||
src += prefix + '} else {' + eol;
|
||||
src += prefix + indent + 'return $elseSrc;' + eol;
|
||||
src += prefix + '}';
|
||||
builder.addSimpleReplacement(range.node(statement), src);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,11 +18,14 @@ class ReplaceFinalWithConst extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
final node = this.node;
|
||||
if (node is VariableDeclarationList) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(
|
||||
range.token((node as VariableDeclarationList).keyword), 'const');
|
||||
});
|
||||
var keyword = node.keyword;
|
||||
if (keyword != null) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.token(keyword), 'const');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,11 +18,12 @@ class ReplaceFinalWithVar extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var target = node;
|
||||
if (target is VariableDeclarationList) {
|
||||
if (target.type == null) {
|
||||
final node = this.node;
|
||||
if (node is VariableDeclarationList) {
|
||||
var keyword = node.keyword;
|
||||
if (keyword != null && node.type == null) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.token(target.keyword), 'var');
|
||||
builder.addSimpleReplacement(range.token(keyword), 'var');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,7 +18,7 @@ class ReplaceNewWithConst extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var node = this.node;
|
||||
AstNode? node = this.node;
|
||||
if (node is ConstructorName) {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
+15
-13
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -22,13 +20,14 @@ class ReplaceNullWithClosure extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
AstNode nodeToFix;
|
||||
AstNode? nodeToFix;
|
||||
var parameters = const <ParameterElement>[];
|
||||
|
||||
final coveredNode = this.coveredNode;
|
||||
if (coveredNode is NamedExpression) {
|
||||
NamedExpression namedExpression = coveredNode;
|
||||
var expression = namedExpression.expression;
|
||||
var expression = coveredNode.expression;
|
||||
if (expression is NullLiteral) {
|
||||
var element = namedExpression.element;
|
||||
var element = coveredNode.element;
|
||||
if (element is ParameterElement) {
|
||||
var type = element.type;
|
||||
if (type is FunctionType) {
|
||||
@@ -41,14 +40,17 @@ class ReplaceNullWithClosure extends CorrectionProducer {
|
||||
nodeToFix = coveredNode;
|
||||
}
|
||||
|
||||
if (nodeToFix != null) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addReplacement(range.node(nodeToFix), (builder) {
|
||||
builder.writeParameters(parameters);
|
||||
builder.write(' => null');
|
||||
});
|
||||
});
|
||||
if (nodeToFix == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final nodeToFix_final = nodeToFix;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addReplacement(range.node(nodeToFix_final), (builder) {
|
||||
builder.writeParameters(parameters);
|
||||
builder.write(' => null');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
|
||||
+4
-3
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -18,7 +16,10 @@ class ReplaceReturnTypeFuture extends CorrectionProducer {
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
// prepare the existing type
|
||||
var typeName = node.thisOrAncestorOfType<TypeAnnotation>();
|
||||
var typeProvider = this.typeProvider;
|
||||
if (typeName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.replaceTypeWithFuture(typeName, typeProvider);
|
||||
});
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
@@ -16,9 +15,12 @@ class ReplaceVarWithDynamic extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.error(diagnostic), 'dynamic');
|
||||
});
|
||||
final diagnostic = this.diagnostic;
|
||||
if (diagnostic is AnalysisError) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.error(diagnostic), 'dynamic');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
|
||||
+10
-11
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -21,20 +19,14 @@ class ReplaceWithConditionalAssignment extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
IfStatement ifStatement =
|
||||
var node = this.node;
|
||||
var ifStatement =
|
||||
node is IfStatement ? node : node.thisOrAncestorOfType<IfStatement>();
|
||||
if (ifStatement == null) {
|
||||
return;
|
||||
}
|
||||
var thenStatement = ifStatement.thenStatement;
|
||||
Statement uniqueStatement(Statement statement) {
|
||||
if (statement is Block) {
|
||||
return uniqueStatement(statement.statements.first);
|
||||
}
|
||||
return statement;
|
||||
}
|
||||
|
||||
thenStatement = uniqueStatement(thenStatement);
|
||||
var thenStatement = _uniqueStatement(ifStatement.thenStatement);
|
||||
if (thenStatement is ExpressionStatement) {
|
||||
final expression = thenStatement.expression.unParenthesized;
|
||||
if (expression is AssignmentExpression) {
|
||||
@@ -53,4 +45,11 @@ class ReplaceWithConditionalAssignment extends CorrectionProducer {
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
static ReplaceWithConditionalAssignment newInstance() =>
|
||||
ReplaceWithConditionalAssignment();
|
||||
|
||||
static Statement _uniqueStatement(Statement statement) {
|
||||
if (statement is Block) {
|
||||
return _uniqueStatement(statement.statements.first);
|
||||
}
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -13,7 +11,7 @@ import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class ReplaceWithEightDigitHex extends CorrectionProducer {
|
||||
/// The replacement text, used as an argument to the fix message.
|
||||
String _replacement;
|
||||
String _replacement = '';
|
||||
|
||||
@override
|
||||
List<Object> get fixArguments => [_replacement];
|
||||
@@ -33,6 +31,9 @@ class ReplaceWithEightDigitHex extends CorrectionProducer {
|
||||
return;
|
||||
}
|
||||
var value = (node as IntegerLiteral).value;
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
_replacement = '0x' + value.toRadixString(16).padLeft(8, '0');
|
||||
//
|
||||
// Build the edit.
|
||||
|
||||
+2
-4
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -12,7 +10,7 @@ import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class ReplaceWithExtensionName extends CorrectionProducer {
|
||||
String _extensionName;
|
||||
String _extensionName = '';
|
||||
|
||||
@override
|
||||
List<Object> get fixArguments => [_extensionName];
|
||||
@@ -35,7 +33,7 @@ class ReplaceWithExtensionName extends CorrectionProducer {
|
||||
}
|
||||
}
|
||||
|
||||
AstNode _getTarget(AstNode invocation) {
|
||||
AstNode? _getTarget(AstNode? invocation) {
|
||||
if (invocation is MethodInvocation && node == invocation.methodName) {
|
||||
return invocation.target;
|
||||
} else if (invocation is PropertyAccess &&
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
|
||||
+18
-16
@@ -2,16 +2,14 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/src/dart/ast/extensions.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
class ReplaceWithInterpolation extends CorrectionProducer {
|
||||
@override
|
||||
@@ -22,9 +20,9 @@ class ReplaceWithInterpolation extends CorrectionProducer {
|
||||
//
|
||||
// Validate the fix.
|
||||
//
|
||||
BinaryExpression binary;
|
||||
var candidate = node;
|
||||
while (_isStringConcatenation(candidate)) {
|
||||
BinaryExpression? binary;
|
||||
AstNode? candidate = node;
|
||||
while (candidate is BinaryExpression && _isStringConcatenation(candidate)) {
|
||||
binary = candidate;
|
||||
candidate = candidate.parent;
|
||||
}
|
||||
@@ -43,8 +41,9 @@ class ReplaceWithInterpolation extends CorrectionProducer {
|
||||
//
|
||||
// Build the edit.
|
||||
//
|
||||
final binary_final = binary;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.node(binary), interpolation);
|
||||
builder.addSimpleReplacement(range.node(binary_final), interpolation);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,9 +81,11 @@ class ReplaceWithInterpolation extends CorrectionProducer {
|
||||
return leftStyle;
|
||||
}
|
||||
return leftStyle == rightStyle ? leftStyle : _StringStyle.invalid;
|
||||
} else if (expression is MethodInvocation &&
|
||||
expression.methodName.name == 'toString') {
|
||||
return _extractComponentsInto(expression.target, components);
|
||||
} else if (expression is MethodInvocation) {
|
||||
var target = expression.target;
|
||||
if (target != null && expression.methodName.name == 'toString') {
|
||||
return _extractComponentsInto(target, components);
|
||||
}
|
||||
} else if (expression is ParenthesizedExpression) {
|
||||
return _extractComponentsInto(expression.expression, components);
|
||||
}
|
||||
@@ -95,8 +96,8 @@ class ReplaceWithInterpolation extends CorrectionProducer {
|
||||
bool _isStringConcatenation(AstNode node) =>
|
||||
node is BinaryExpression &&
|
||||
node.operator.type == TokenType.PLUS &&
|
||||
node.leftOperand.staticType.isDartCoreString &&
|
||||
node.rightOperand.staticType.isDartCoreString;
|
||||
node.leftOperand.typeOrThrow.isDartCoreString &&
|
||||
node.rightOperand.typeOrThrow.isDartCoreString;
|
||||
|
||||
String _mergeComponents(_StringStyle style, List<AstNode> components) {
|
||||
var quotes = style.quotes;
|
||||
@@ -161,10 +162,11 @@ class _StringStyle {
|
||||
|
||||
final int state;
|
||||
|
||||
factory _StringStyle(
|
||||
{@required bool multiline,
|
||||
@required bool raw,
|
||||
@required bool singleQuoted}) {
|
||||
factory _StringStyle({
|
||||
required bool multiline,
|
||||
required bool raw,
|
||||
required bool singleQuoted,
|
||||
}) {
|
||||
return _StringStyle._((multiline ? multilineBit : 0) +
|
||||
(raw ? rawBit : 0) +
|
||||
(singleQuoted ? singleQuotedBit : 0));
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -14,106 +12,28 @@ import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class ReplaceWithIsEmpty extends CorrectionProducer {
|
||||
@override
|
||||
FixKind fixKind;
|
||||
FixKind fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
|
||||
|
||||
@override
|
||||
FixKind multiFixKind;
|
||||
FixKind multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
/// Return the value of an integer literal or prefix expression with a
|
||||
/// minus and then an integer literal. For anything else, returns `null`.
|
||||
int getIntValue(Expression expressions) {
|
||||
// Copied from package:linter/src/rules/prefer_is_empty.dart.
|
||||
if (expressions is IntegerLiteral) {
|
||||
return expressions.value;
|
||||
} else if (expressions is PrefixExpression) {
|
||||
var operand = expressions.operand;
|
||||
if (expressions.operator.type == TokenType.MINUS &&
|
||||
operand is IntegerLiteral) {
|
||||
return -operand.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Return the expression producing the object on which `length` is being
|
||||
/// invoked, or `null` if there is no such expression.
|
||||
Expression getLengthTarget(Expression expression) {
|
||||
if (expression is PropertyAccess &&
|
||||
expression.propertyName.name == 'length') {
|
||||
return expression.target;
|
||||
} else if (expression is PrefixedIdentifier &&
|
||||
expression.identifier.name == 'length') {
|
||||
return expression.prefix;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
var binary = node.thisOrAncestorOfType<BinaryExpression>();
|
||||
var operator = binary.operator.type;
|
||||
String getter;
|
||||
Expression lengthTarget;
|
||||
var rightValue = getIntValue(binary.rightOperand);
|
||||
if (rightValue != null) {
|
||||
lengthTarget = getLengthTarget(binary.leftOperand);
|
||||
if (rightValue == 0) {
|
||||
if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
|
||||
getter = 'isEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
|
||||
} else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
|
||||
getter = 'isNotEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
|
||||
}
|
||||
} else if (rightValue == 1) {
|
||||
// 'length >= 1' is same as 'isNotEmpty',
|
||||
// and 'length < 1' is same as 'isEmpty'
|
||||
if (operator == TokenType.GT_EQ) {
|
||||
getter = 'isNotEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
|
||||
} else if (operator == TokenType.LT) {
|
||||
getter = 'isEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var leftValue = getIntValue(binary.leftOperand);
|
||||
if (leftValue != null) {
|
||||
lengthTarget = getLengthTarget(binary.rightOperand);
|
||||
if (leftValue == 0) {
|
||||
if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
|
||||
getter = 'isEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
|
||||
} else if (operator == TokenType.LT ||
|
||||
operator == TokenType.BANG_EQ) {
|
||||
getter = 'isNotEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
|
||||
}
|
||||
} else if (leftValue == 1) {
|
||||
// '1 <= length' is same as 'isNotEmpty',
|
||||
// and '1 > length' is same as 'isEmpty'
|
||||
if (operator == TokenType.LT_EQ) {
|
||||
getter = 'isNotEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI;
|
||||
} else if (operator == TokenType.GT) {
|
||||
getter = 'isEmpty';
|
||||
fixKind = DartFixKind.REPLACE_WITH_IS_EMPTY;
|
||||
multiFixKind = DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lengthTarget == null || getter == null || fixKind == null) {
|
||||
if (binary == null) {
|
||||
return;
|
||||
}
|
||||
var target = utils.getNodeText(lengthTarget);
|
||||
|
||||
var replacement = _analyzeBinaryExpression(binary);
|
||||
if (replacement == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
fixKind = replacement.fixKind;
|
||||
multiFixKind = replacement.multiFixKind;
|
||||
|
||||
var target = utils.getNodeText(replacement.lengthTarget);
|
||||
var getter = replacement.getter;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.node(binary), '$target.$getter');
|
||||
});
|
||||
@@ -121,4 +41,117 @@ class ReplaceWithIsEmpty extends CorrectionProducer {
|
||||
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
static ReplaceWithIsEmpty newInstance() => ReplaceWithIsEmpty();
|
||||
|
||||
static _Replacement? _analyzeBinaryExpression(BinaryExpression binary) {
|
||||
var operator = binary.operator.type;
|
||||
var rightValue = _getIntValue(binary.rightOperand);
|
||||
if (rightValue != null) {
|
||||
var lengthTarget = _getLengthTarget(binary.leftOperand);
|
||||
if (lengthTarget == null) {
|
||||
return null;
|
||||
}
|
||||
if (rightValue == 0) {
|
||||
if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
|
||||
return _Replacement.isEmpty(lengthTarget);
|
||||
} else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
|
||||
return _Replacement.isNotEmpty(lengthTarget);
|
||||
}
|
||||
} else if (rightValue == 1) {
|
||||
// 'length >= 1' is same as 'isNotEmpty',
|
||||
// and 'length < 1' is same as 'isEmpty'
|
||||
if (operator == TokenType.GT_EQ) {
|
||||
return _Replacement.isNotEmpty(lengthTarget);
|
||||
} else if (operator == TokenType.LT) {
|
||||
return _Replacement.isEmpty(lengthTarget);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var leftValue = _getIntValue(binary.leftOperand);
|
||||
if (leftValue != null) {
|
||||
var lengthTarget = _getLengthTarget(binary.rightOperand);
|
||||
if (lengthTarget == null) {
|
||||
return null;
|
||||
}
|
||||
if (leftValue == 0) {
|
||||
if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
|
||||
return _Replacement.isEmpty(lengthTarget);
|
||||
} else if (operator == TokenType.LT ||
|
||||
operator == TokenType.BANG_EQ) {
|
||||
return _Replacement.isNotEmpty(lengthTarget);
|
||||
}
|
||||
} else if (leftValue == 1) {
|
||||
// '1 <= length' is same as 'isNotEmpty',
|
||||
// and '1 > length' is same as 'isEmpty'
|
||||
if (operator == TokenType.LT_EQ) {
|
||||
return _Replacement.isNotEmpty(lengthTarget);
|
||||
} else if (operator == TokenType.GT) {
|
||||
return _Replacement.isEmpty(lengthTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Return the value of an integer literal or prefix expression with a
|
||||
/// minus and then an integer literal. For anything else, returns `null`.
|
||||
static int? _getIntValue(Expression expressions) {
|
||||
// Copied from package:linter/src/rules/prefer_is_empty.dart.
|
||||
if (expressions is IntegerLiteral) {
|
||||
return expressions.value;
|
||||
} else if (expressions is PrefixExpression) {
|
||||
var operand = expressions.operand;
|
||||
if (expressions.operator.type == TokenType.MINUS &&
|
||||
operand is IntegerLiteral) {
|
||||
var value = operand.value;
|
||||
if (value != null) {
|
||||
return -value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Return the expression producing the object on which `length` is being
|
||||
/// invoked, or `null` if there is no such expression.
|
||||
static Expression? _getLengthTarget(Expression expression) {
|
||||
if (expression is PropertyAccess &&
|
||||
expression.propertyName.name == 'length') {
|
||||
return expression.target;
|
||||
} else if (expression is PrefixedIdentifier &&
|
||||
expression.identifier.name == 'length') {
|
||||
return expression.prefix;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _Replacement {
|
||||
final FixKind fixKind;
|
||||
final FixKind multiFixKind;
|
||||
final String getter;
|
||||
final Expression lengthTarget;
|
||||
|
||||
_Replacement.isEmpty(Expression lengthTarget)
|
||||
: this._(
|
||||
fixKind: DartFixKind.REPLACE_WITH_IS_EMPTY,
|
||||
multiFixKind: DartFixKind.REPLACE_WITH_IS_EMPTY_MULTI,
|
||||
getter: 'isEmpty',
|
||||
lengthTarget: lengthTarget,
|
||||
);
|
||||
|
||||
_Replacement.isNotEmpty(Expression lengthTarget)
|
||||
: this._(
|
||||
fixKind: DartFixKind.REPLACE_WITH_IS_NOT_EMPTY,
|
||||
multiFixKind: DartFixKind.REPLACE_WITH_IS_NOT_EMPTY_MULTI,
|
||||
getter: 'isNotEmpty',
|
||||
lengthTarget: lengthTarget,
|
||||
);
|
||||
|
||||
_Replacement._({
|
||||
required this.fixKind,
|
||||
required this.multiFixKind,
|
||||
required this.getter,
|
||||
required this.lengthTarget,
|
||||
});
|
||||
}
|
||||
|
||||
+14
-12
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -14,7 +12,7 @@ import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class ReplaceWithNotNullAware extends CorrectionProducer {
|
||||
/// The operator that will replace the existing operator.
|
||||
String _newOperator;
|
||||
String _newOperator = '';
|
||||
|
||||
@override
|
||||
List<Object> get fixArguments => [_newOperator];
|
||||
@@ -26,11 +24,13 @@ class ReplaceWithNotNullAware extends CorrectionProducer {
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var node = coveredNode;
|
||||
if (node is MethodInvocation) {
|
||||
_newOperator =
|
||||
node.operator.type == TokenType.QUESTION_PERIOD ? '.' : '..';
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.token(node.operator), _newOperator);
|
||||
});
|
||||
var operator = node.operator;
|
||||
if (operator != null) {
|
||||
_newOperator = operator.type == TokenType.QUESTION_PERIOD ? '.' : '..';
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.token(operator), _newOperator);
|
||||
});
|
||||
}
|
||||
} else if (node is PropertyAccess) {
|
||||
_newOperator =
|
||||
node.operator.type == TokenType.QUESTION_PERIOD ? '.' : '..';
|
||||
@@ -38,15 +38,17 @@ class ReplaceWithNotNullAware extends CorrectionProducer {
|
||||
builder.addSimpleReplacement(range.token(node.operator), _newOperator);
|
||||
});
|
||||
} else if (node is IndexExpression) {
|
||||
if (node.period != null) {
|
||||
var period = node.period;
|
||||
var question = node.question;
|
||||
if (period != null) {
|
||||
_newOperator = '..';
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.token(node.period), '..');
|
||||
builder.addSimpleReplacement(range.token(period), '..');
|
||||
});
|
||||
} else if (node.question != null) {
|
||||
} else if (question != null) {
|
||||
_newOperator = '[';
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addDeletion(range.token(node.question));
|
||||
builder.addDeletion(range.token(question));
|
||||
});
|
||||
}
|
||||
} else if (node is SpreadElement) {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -19,18 +17,22 @@ class ReplaceWithNullAware extends CorrectionProducer {
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var node = coveredNode;
|
||||
if (node is Expression) {
|
||||
final node_final = node;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
var parent = node.parent;
|
||||
var parent = node_final.parent;
|
||||
while (parent != null) {
|
||||
if (parent is MethodInvocation && parent.target == node) {
|
||||
builder.addSimpleReplacement(range.token(parent.operator), '?.');
|
||||
var operator = parent.operator;
|
||||
if (operator != null) {
|
||||
builder.addSimpleReplacement(range.token(operator), '?.');
|
||||
}
|
||||
} else if (parent is PropertyAccess && parent.target == node) {
|
||||
builder.addSimpleReplacement(range.token(parent.operator), '?.');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
node = parent;
|
||||
parent = node.parent;
|
||||
parent = node?.parent;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -24,16 +22,22 @@ class ReplaceWithTearOff extends CorrectionProducer {
|
||||
if (ancestor == null) {
|
||||
return;
|
||||
}
|
||||
Future<void> addFixOfExpression(InvocationExpression expression) async {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addReplacement(range.node(ancestor), (builder) {
|
||||
if (expression is MethodInvocation && expression.target != null) {
|
||||
builder.write(utils.getNodeText(expression.target));
|
||||
builder.write('.');
|
||||
}
|
||||
builder.write(utils.getNodeText(expression.function));
|
||||
|
||||
Future<void> addFixOfExpression(Expression? expression) async {
|
||||
if (expression is InvocationExpression) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addReplacement(range.node(ancestor), (builder) {
|
||||
if (expression is MethodInvocation) {
|
||||
var target = expression.target;
|
||||
if (target != null) {
|
||||
builder.write(utils.getNodeText(target));
|
||||
builder.write('.');
|
||||
}
|
||||
}
|
||||
builder.write(utils.getNodeText(expression.function));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
final body = ancestor.body;
|
||||
@@ -47,7 +51,7 @@ class ReplaceWithTearOff extends CorrectionProducer {
|
||||
await addFixOfExpression(expression.unParenthesized);
|
||||
} else if (statement is ReturnStatement) {
|
||||
final expression = statement.expression;
|
||||
await addFixOfExpression(expression.unParenthesized);
|
||||
await addFixOfExpression(expression?.unParenthesized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/src/dart/ast/extensions.dart';
|
||||
import 'package:analyzer_plugin/utilities/assist/assist.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
@@ -44,25 +43,28 @@ class ReplaceWithVar extends CorrectionProducer {
|
||||
return;
|
||||
}
|
||||
var initializer = variables[0].initializer;
|
||||
String typeArgumentsText;
|
||||
int typeArgumentsOffset;
|
||||
if (type is NamedType && type.typeArguments != null) {
|
||||
if (initializer is CascadeExpression) {
|
||||
initializer = (initializer as CascadeExpression).target;
|
||||
}
|
||||
if (initializer is TypedLiteral) {
|
||||
if (initializer.typeArguments == null) {
|
||||
typeArgumentsText = utils.getNodeText(type.typeArguments);
|
||||
if (initializer is ListLiteral) {
|
||||
typeArgumentsOffset = initializer.leftBracket.offset;
|
||||
} else if (initializer is SetOrMapLiteral) {
|
||||
typeArgumentsOffset = initializer.leftBracket.offset;
|
||||
}
|
||||
String? typeArgumentsText;
|
||||
int? typeArgumentsOffset;
|
||||
if (type is NamedType) {
|
||||
var typeArguments = type.typeArguments;
|
||||
if (typeArguments != null) {
|
||||
if (initializer is CascadeExpression) {
|
||||
initializer = initializer.target;
|
||||
}
|
||||
} else if (initializer is InstanceCreationExpression) {
|
||||
if (initializer.constructorName.type.typeArguments == null) {
|
||||
typeArgumentsText = utils.getNodeText(type.typeArguments);
|
||||
typeArgumentsOffset = initializer.constructorName.type.end;
|
||||
if (initializer is TypedLiteral) {
|
||||
if (initializer.typeArguments == null) {
|
||||
typeArgumentsText = utils.getNodeText(typeArguments);
|
||||
if (initializer is ListLiteral) {
|
||||
typeArgumentsOffset = initializer.leftBracket.offset;
|
||||
} else if (initializer is SetOrMapLiteral) {
|
||||
typeArgumentsOffset = initializer.leftBracket.offset;
|
||||
}
|
||||
}
|
||||
} else if (initializer is InstanceCreationExpression) {
|
||||
if (initializer.constructorName.type.typeArguments == null) {
|
||||
typeArgumentsText = utils.getNodeText(typeArguments);
|
||||
typeArgumentsOffset = initializer.constructorName.type.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,19 +82,22 @@ class ReplaceWithVar extends CorrectionProducer {
|
||||
} else {
|
||||
builder.addSimpleReplacement(range.node(type), 'var');
|
||||
}
|
||||
if (typeArgumentsText != null) {
|
||||
if (typeArgumentsText != null && typeArgumentsOffset != null) {
|
||||
builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
|
||||
}
|
||||
});
|
||||
} else if (parent is DeclaredIdentifier &&
|
||||
grandparent is ForEachPartsWithDeclaration) {
|
||||
String typeArgumentsText;
|
||||
int typeArgumentsOffset;
|
||||
if (type is NamedType && type.typeArguments != null) {
|
||||
var iterable = grandparent.iterable;
|
||||
if (iterable is TypedLiteral && iterable.typeArguments == null) {
|
||||
typeArgumentsText = utils.getNodeText(type.typeArguments);
|
||||
typeArgumentsOffset = iterable.offset;
|
||||
String? typeArgumentsText;
|
||||
int? typeArgumentsOffset;
|
||||
if (type is NamedType) {
|
||||
var typeArguments = type.typeArguments;
|
||||
if (typeArguments != null) {
|
||||
var iterable = grandparent.iterable;
|
||||
if (iterable is TypedLiteral && iterable.typeArguments == null) {
|
||||
typeArgumentsText = utils.getNodeText(typeArguments);
|
||||
typeArgumentsOffset = iterable.offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
@@ -101,7 +106,7 @@ class ReplaceWithVar extends CorrectionProducer {
|
||||
} else {
|
||||
builder.addSimpleReplacement(range.node(type), 'var');
|
||||
}
|
||||
if (typeArgumentsText != null) {
|
||||
if (typeArgumentsText != null && typeArgumentsOffset != null) {
|
||||
builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
|
||||
}
|
||||
});
|
||||
@@ -110,7 +115,7 @@ class ReplaceWithVar extends CorrectionProducer {
|
||||
|
||||
/// Return `true` if the type in the [node] can be replaced with `var`.
|
||||
bool _canConvertVariableDeclarationList(VariableDeclarationList node) {
|
||||
final staticType = node?.type?.type;
|
||||
final staticType = node.type?.type;
|
||||
if (staticType == null || staticType.isDynamic) {
|
||||
return false;
|
||||
}
|
||||
@@ -137,10 +142,10 @@ class ReplaceWithVar extends CorrectionProducer {
|
||||
if (staticType == null || staticType.isDynamic) {
|
||||
return false;
|
||||
}
|
||||
final iterableType = parent.iterable.staticType;
|
||||
final iterableType = parent.iterable.typeOrThrow;
|
||||
var instantiatedType =
|
||||
iterableType.asInstanceOf(typeProvider.iterableElement);
|
||||
if (instantiatedType?.typeArguments?.first == staticType) {
|
||||
if (instantiatedType?.typeArguments.first == staticType) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -152,7 +157,7 @@ class ReplaceWithVar extends CorrectionProducer {
|
||||
|
||||
/// Using the [node] as a starting point, return the type annotation that is
|
||||
/// to be replaced, or `null` if there is no type annotation.
|
||||
TypeAnnotation _findType(AstNode node) {
|
||||
TypeAnnotation? _findType(AstNode node) {
|
||||
if (node is VariableDeclarationList) {
|
||||
return node.type;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,34 +18,45 @@ class ShadowField extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
final node = this.node;
|
||||
if (node is! SimpleIdentifier) {
|
||||
return;
|
||||
}
|
||||
var element = (node as SimpleIdentifier).writeOrReadElement;
|
||||
if (element is! PropertyAccessorElement) {
|
||||
|
||||
var accessor = node.writeOrReadElement;
|
||||
if (accessor is! PropertyAccessorElement) {
|
||||
return;
|
||||
}
|
||||
var accessor = element as PropertyAccessorElement;
|
||||
|
||||
if (!accessor.isGetter || accessor.enclosingElement is! ClassElement) {
|
||||
// TODO(brianwilkerson) Should we also require that the getter be synthetic?
|
||||
return;
|
||||
}
|
||||
|
||||
var statement = _getStatement();
|
||||
if (statement == null) {
|
||||
return;
|
||||
}
|
||||
if (statement.parent is! Block) {
|
||||
|
||||
var enclosingBlock = statement.parent;
|
||||
if (enclosingBlock is! Block) {
|
||||
// TODO(brianwilkerson) Support adding a block between the statement and
|
||||
// its parent (where the parent will be something like a while or if
|
||||
// statement). Also support the case where the parent is a case clause.
|
||||
return;
|
||||
}
|
||||
var enclosingBlock = statement.parent as Block;
|
||||
var finder = _ReferenceFinder(accessor.correspondingSetter);
|
||||
|
||||
var correspondingSetter = accessor.correspondingSetter;
|
||||
if (correspondingSetter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var finder = _ReferenceFinder(correspondingSetter);
|
||||
enclosingBlock.accept(finder);
|
||||
if (finder.hasSetterReference) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fieldName = accessor.name;
|
||||
var offset = statement.offset;
|
||||
var prefix = utils.getLinePrefix(offset);
|
||||
@@ -74,13 +83,13 @@ class ShadowField extends CorrectionProducer {
|
||||
|
||||
/// Return the statement immediately enclosing the [node] that would promote
|
||||
/// the type of the field if it were replaced by a local variable.
|
||||
Statement _getStatement() {
|
||||
Statement? _getStatement() {
|
||||
var parent = node.parent;
|
||||
|
||||
Statement enclosingIf(Expression expression) {
|
||||
Statement? enclosingIf(Expression expression) {
|
||||
var parent = expression.parent;
|
||||
while (parent is BinaryExpression) {
|
||||
var opType = (parent as BinaryExpression).operator.type;
|
||||
var opType = parent.operator.type;
|
||||
if (opType != TokenType.AMPERSAND_AMPERSAND) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
@@ -32,13 +30,12 @@ class SortChildPropertyLast extends CorrectionProducer {
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = childProp.parent?.parent;
|
||||
if (parent is! InstanceCreationExpression ||
|
||||
!flutter.isWidgetCreation(parent)) {
|
||||
var creationExpression = childProp.parent?.parent;
|
||||
if (creationExpression is! InstanceCreationExpression ||
|
||||
!flutter.isWidgetCreation(creationExpression)) {
|
||||
return;
|
||||
}
|
||||
|
||||
InstanceCreationExpression creationExpression = parent;
|
||||
var args = creationExpression.argumentList;
|
||||
|
||||
var last = args.arguments.last;
|
||||
@@ -48,10 +45,10 @@ class SortChildPropertyLast extends CorrectionProducer {
|
||||
}
|
||||
|
||||
await builder.addDartFileEdit(file, (fileEditBuilder) {
|
||||
var hasTrailingComma = last.endToken.next.type == TokenType.COMMA;
|
||||
var hasTrailingComma = last.endToken.next!.type == TokenType.COMMA;
|
||||
|
||||
var childStart = childProp.beginToken.previous.end;
|
||||
var childEnd = childProp.endToken.next.end;
|
||||
var childStart = childProp.beginToken.previous!.end;
|
||||
var childEnd = childProp.endToken.next!.end;
|
||||
var childRange = range.startOffsetEndOffset(childStart, childEnd);
|
||||
|
||||
var deletionRange = childRange;
|
||||
@@ -69,7 +66,7 @@ class SortChildPropertyLast extends CorrectionProducer {
|
||||
|
||||
var insertionPoint = last.end;
|
||||
if (hasTrailingComma) {
|
||||
insertionPoint = last.endToken.next.end;
|
||||
insertionPoint = last.endToken.next!.end;
|
||||
} else if (childStart == childProp.offset) {
|
||||
childText = ', $childText';
|
||||
} else {
|
||||
@@ -85,7 +82,7 @@ class SortChildPropertyLast extends CorrectionProducer {
|
||||
|
||||
/// Using the [node] as the starting point, find the named expression that is
|
||||
/// for either the `child` or `children` parameter.
|
||||
NamedExpression _findNamedExpression(AstNode node) {
|
||||
NamedExpression? _findNamedExpression(AstNode node) {
|
||||
if (node is NamedExpression) {
|
||||
var name = node.name.label.name;
|
||||
if (name == 'child' || name == 'children') {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/util.dart';
|
||||
@@ -20,10 +18,10 @@ class SplitAndCondition extends CorrectionProducer {
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
// check that user invokes quick assist on binary expression
|
||||
if (node is! BinaryExpression) {
|
||||
var binaryExpression = node;
|
||||
if (binaryExpression is! BinaryExpression) {
|
||||
return;
|
||||
}
|
||||
var binaryExpression = node as BinaryExpression;
|
||||
// prepare operator position
|
||||
if (!isOperatorSelected(binaryExpression)) {
|
||||
return;
|
||||
@@ -33,11 +31,10 @@ class SplitAndCondition extends CorrectionProducer {
|
||||
return;
|
||||
}
|
||||
// prepare "if"
|
||||
var statement = node.thisOrAncestorOfType<Statement>();
|
||||
if (statement is! IfStatement) {
|
||||
var ifStatement = node.thisOrAncestorOfType<Statement>();
|
||||
if (ifStatement is! IfStatement) {
|
||||
return;
|
||||
}
|
||||
var ifStatement = statement as IfStatement;
|
||||
// no support "else"
|
||||
if (ifStatement.elseStatement != null) {
|
||||
return;
|
||||
|
||||
+13
-11
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
@@ -18,16 +16,20 @@ class SplitVariableDeclaration extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var variableList = node?.thisOrAncestorOfType<VariableDeclarationList>();
|
||||
|
||||
// Must be a local variable declaration.
|
||||
if (variableList?.parent is! VariableDeclarationStatement) {
|
||||
var variableList = node.thisOrAncestorOfType<VariableDeclarationList>();
|
||||
if (variableList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Must be a local variable declaration.
|
||||
var statement = variableList.parent;
|
||||
if (statement is! VariableDeclarationStatement) {
|
||||
return;
|
||||
}
|
||||
VariableDeclarationStatement statement = variableList.parent;
|
||||
|
||||
// Cannot be `const` or `final`.
|
||||
var keywordKind = variableList.keyword?.keyword;
|
||||
var keyword = variableList.keyword;
|
||||
var keywordKind = keyword?.keyword;
|
||||
if (keywordKind == Keyword.CONST || keywordKind == Keyword.FINAL) {
|
||||
return;
|
||||
}
|
||||
@@ -50,9 +52,9 @@ class SplitVariableDeclaration extends CorrectionProducer {
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
if (variableList.type == null) {
|
||||
final type = variable.declaredElement.type;
|
||||
if (!type.isDynamic) {
|
||||
builder.addReplacement(range.token(variableList.keyword), (builder) {
|
||||
final type = variable.declaredElement!.type;
|
||||
if (!type.isDynamic && keyword != null) {
|
||||
builder.addReplacement(range.token(keyword), (builder) {
|
||||
builder.writeType(type);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
@@ -25,32 +23,25 @@ class UpdateSdkConstraints extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
var context = resourceProvider.pathContext;
|
||||
File pubspecFile;
|
||||
var folder = resourceProvider.getFolder(context.dirname(file));
|
||||
while (folder != null) {
|
||||
pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
|
||||
if (pubspecFile.exists) {
|
||||
break;
|
||||
}
|
||||
pubspecFile = null;
|
||||
folder = folder.parent2;
|
||||
}
|
||||
var pubspecFile = _findPubspecFile();
|
||||
if (pubspecFile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var extractor = SdkConstraintExtractor(pubspecFile);
|
||||
var text = extractor.constraintText();
|
||||
var offset = extractor.constraintOffset();
|
||||
if (text == null || offset < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var length = text.length;
|
||||
String newText;
|
||||
var spaceOffset = text.indexOf(' ');
|
||||
if (spaceOffset >= 0) {
|
||||
length = spaceOffset;
|
||||
}
|
||||
|
||||
String? newText;
|
||||
if (text == 'any') {
|
||||
newText = '^$_minimumVersion';
|
||||
} else if (text.startsWith('^')) {
|
||||
@@ -63,11 +54,23 @@ class UpdateSdkConstraints extends CorrectionProducer {
|
||||
if (newText == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final newText_final = newText;
|
||||
await builder.addGenericFileEdit(pubspecFile.path, (builder) {
|
||||
builder.addSimpleReplacement(SourceRange(offset, length), newText);
|
||||
builder.addSimpleReplacement(SourceRange(offset, length), newText_final);
|
||||
});
|
||||
}
|
||||
|
||||
File? _findPubspecFile() {
|
||||
var file = resourceProvider.getFile(this.file);
|
||||
for (var folder in file.parent2.withAncestors) {
|
||||
var pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
|
||||
if (pubspecFile.exists) {
|
||||
return pubspecFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an instance of this class that will update the SDK constraints to
|
||||
/// '2.1.0'. Used as a tear-off in `FixProcessor`.
|
||||
static UpdateSdkConstraints version_2_1_0() => UpdateSdkConstraints('2.1.0');
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,12 +18,12 @@ class UseConst extends CorrectionProducer {
|
||||
if (coveredNode is InstanceCreationExpression) {
|
||||
var instanceCreation = coveredNode as InstanceCreationExpression;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
if (instanceCreation.keyword == null) {
|
||||
var keyword = instanceCreation.keyword;
|
||||
if (keyword == null) {
|
||||
builder.addSimpleInsertion(
|
||||
instanceCreation.constructorName.offset, 'const');
|
||||
} else {
|
||||
builder.addSimpleReplacement(
|
||||
range.token(instanceCreation.keyword), 'const');
|
||||
builder.addSimpleReplacement(range.token(keyword), 'const');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/assist.dart';
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
@@ -37,9 +35,12 @@ class UseCurlyBraces extends CorrectionProducer {
|
||||
} else if (parent is ForStatement) {
|
||||
return _forStatement(builder, parent);
|
||||
} else if (statement is IfStatement) {
|
||||
if (statement.elseKeyword != null &&
|
||||
range.token(statement.elseKeyword).contains(selectionOffset)) {
|
||||
return _ifStatement(builder, statement, statement.elseStatement);
|
||||
var elseKeyword = statement.elseKeyword;
|
||||
var elseStatement = statement.elseStatement;
|
||||
if (elseKeyword != null &&
|
||||
elseStatement != null &&
|
||||
range.token(elseKeyword).contains(selectionOffset)) {
|
||||
return _ifStatement(builder, statement, elseStatement);
|
||||
} else {
|
||||
return _ifStatement(builder, statement, null);
|
||||
}
|
||||
@@ -88,21 +89,22 @@ class UseCurlyBraces extends CorrectionProducer {
|
||||
}
|
||||
|
||||
Future<void> _ifStatement(
|
||||
ChangeBuilder builder, IfStatement node, Statement thenOrElse) async {
|
||||
ChangeBuilder builder, IfStatement node, Statement? thenOrElse) async {
|
||||
var prefix = utils.getLinePrefix(node.offset);
|
||||
var indent = prefix + utils.getIndent(1);
|
||||
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
var thenStatement = node.thenStatement;
|
||||
var elseKeyword = node.elseKeyword;
|
||||
if (thenStatement is! Block &&
|
||||
(thenOrElse == null || thenOrElse == thenStatement)) {
|
||||
builder.addSimpleReplacement(
|
||||
range.endStart(node.rightParenthesis, thenStatement),
|
||||
' {$eol$indent',
|
||||
);
|
||||
if (node.elseKeyword != null) {
|
||||
if (elseKeyword != null) {
|
||||
builder.addSimpleReplacement(
|
||||
range.endStart(thenStatement, node.elseKeyword),
|
||||
range.endStart(thenStatement, elseKeyword),
|
||||
'$eol$prefix} ',
|
||||
);
|
||||
} else {
|
||||
@@ -111,11 +113,12 @@ class UseCurlyBraces extends CorrectionProducer {
|
||||
}
|
||||
|
||||
var elseStatement = node.elseStatement;
|
||||
if (elseStatement != null &&
|
||||
if (elseKeyword != null &&
|
||||
elseStatement != null &&
|
||||
elseStatement is! Block &&
|
||||
(thenOrElse == null || thenOrElse == elseStatement)) {
|
||||
builder.addSimpleReplacement(
|
||||
range.endStart(node.elseKeyword, elseStatement),
|
||||
range.endStart(elseKeyword, elseStatement),
|
||||
' {$eol$indent',
|
||||
);
|
||||
builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
|
||||
|
||||
+19
-17
@@ -2,10 +2,9 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analysis_server/src/utilities/extensions/ast.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
@@ -17,21 +16,24 @@ class UseEffectiveIntegerDivision extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
for (var n = node; n != null; n = n.parent) {
|
||||
if (n is MethodInvocation &&
|
||||
n.offset == errorOffset &&
|
||||
n.length == errorLength) {
|
||||
var target = (n as MethodInvocation).target.unParenthesized;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
// replace "/" with "~/"
|
||||
var 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));
|
||||
});
|
||||
// done
|
||||
break;
|
||||
for (var n in node.withParents) {
|
||||
if (n is MethodInvocation) {
|
||||
if (n.offset == errorOffset && n.length == errorLength) {
|
||||
var target = n.target;
|
||||
if (target != null) {
|
||||
target = target.unParenthesized;
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
// replace "/" with "~/"
|
||||
var 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));
|
||||
});
|
||||
}
|
||||
// done
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -21,10 +19,10 @@ class UseIsNotEmpty extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
if (node is! PrefixExpression) {
|
||||
var prefixExpression = node;
|
||||
if (prefixExpression is! PrefixExpression) {
|
||||
return;
|
||||
}
|
||||
PrefixExpression prefixExpression = node;
|
||||
var negation = prefixExpression.operator;
|
||||
if (negation.type != TokenType.BANG) {
|
||||
return;
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
@@ -20,6 +18,7 @@ class UseRethrow extends CorrectionProducer {
|
||||
|
||||
@override
|
||||
Future<void> compute(ChangeBuilder builder) async {
|
||||
final coveredNode = this.coveredNode;
|
||||
if (coveredNode is ThrowExpression) {
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(range.node(coveredNode), 'rethrow');
|
||||
|
||||
@@ -2,20 +2,16 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
|
||||
import 'package:analysis_server/src/services/correction/fix.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/src/dart/ast/extensions.dart';
|
||||
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
|
||||
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
|
||||
import 'package:analyzer_plugin/utilities/range_factory.dart';
|
||||
|
||||
class WrapInText extends CorrectionProducer {
|
||||
ParameterElement _parameterElement;
|
||||
Expression _stringExpression;
|
||||
|
||||
@override
|
||||
FixKind get fixKind => DartFixKind.WRAP_IN_TEXT;
|
||||
|
||||
@@ -24,43 +20,55 @@ class WrapInText extends CorrectionProducer {
|
||||
//
|
||||
// Extract the information needed to build the edit.
|
||||
//
|
||||
_extractContextInformation(node);
|
||||
if (_parameterElement == null || _stringExpression == null) {
|
||||
var context = _extractContextInformation(node);
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
if (!flutter.isWidgetType(_parameterElement.type)) {
|
||||
if (!flutter.isWidgetType(context.parameterElement.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract the information needed to build the edit.
|
||||
//
|
||||
var stringExpressionCode = utils.getNodeText(_stringExpression);
|
||||
var stringExpressionCode = utils.getNodeText(context.stringExpression);
|
||||
|
||||
//
|
||||
// Build the edit.
|
||||
//
|
||||
await builder.addDartFileEdit(file, (builder) {
|
||||
builder.addSimpleReplacement(
|
||||
range.node(_stringExpression),
|
||||
range.node(context.stringExpression),
|
||||
'Text($stringExpressionCode)',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Set the `String` typed named expression to [_stringExpression], and the
|
||||
/// corresponding parameter to [_parameterElement]. Leave the fields `null`
|
||||
/// if not a named argument, or not a `String` typed expression.
|
||||
void _extractContextInformation(AstNode node) {
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
static WrapInText newInstance() => WrapInText();
|
||||
|
||||
static _Context? _extractContextInformation(AstNode node) {
|
||||
if (node is NamedExpression) {
|
||||
var expression = node.expression;
|
||||
if (expression.staticType.isDartCoreString) {
|
||||
_parameterElement = node.name.label.staticElement;
|
||||
_stringExpression = expression;
|
||||
if (expression.typeOrThrow.isDartCoreString) {
|
||||
var parameterElement = node.name.label.staticElement;
|
||||
if (parameterElement is ParameterElement) {
|
||||
return _Context(
|
||||
stringExpression: expression,
|
||||
parameterElement: parameterElement,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
|
||||
static WrapInText newInstance() => WrapInText();
|
||||
}
|
||||
|
||||
class _Context {
|
||||
final Expression stringExpression;
|
||||
final ParameterElement parameterElement;
|
||||
|
||||
_Context({
|
||||
required this.stringExpression,
|
||||
required this.parameterElement,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -429,7 +429,7 @@ Expression? getQualifiedPropertyTarget(AstNode node) {
|
||||
|
||||
/// Returns the given [statement] if not a block, or the first child statement
|
||||
/// if a block, or `null` if more than one child.
|
||||
Statement? getSingleStatement(Statement statement) {
|
||||
Statement? getSingleStatement(Statement? statement) {
|
||||
if (statement is Block) {
|
||||
List<Statement> blockStatements = statement.statements;
|
||||
if (blockStatements.length != 1) {
|
||||
|
||||
Reference in New Issue
Block a user