Migrate CorrectionProducer and two producers.
I decided against landing https://dart-review.googlesource.com/c/sdk/+/194321
It gets too bulky.
So, we will migrate producers, and only then tests, and will know
our null safety mistakes.
Change-Id: I7b358549fc33c9d9a02aef80f30a676c7875f85a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194326
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 42230fe..b5a1027 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -180,15 +180,13 @@
return assists;
}
- var context = CorrectionProducerContext(
+ var context = CorrectionProducerContext.create(
selectionOffset: selectionOffset,
selectionLength: selectionLength,
resolvedResult: resolvedResult,
workspace: workspace,
);
-
- var setupSuccess = context.setupCompute();
- if (!setupSuccess) {
+ if (context == null) {
return assists;
}
@@ -233,16 +231,14 @@
}
Future<void> _addFromProducers() async {
- var context = CorrectionProducerContext(
+ var context = CorrectionProducerContext.create(
selectionOffset: selectionOffset,
selectionLength: selectionLength,
resolvedResult: resolvedResult,
workspace: workspace,
);
-
- var setupSuccess = context.setupCompute();
- if (!setupSuccess) {
- return;
+ if (context == null) {
+ return assists;
}
Future<void> compute(CorrectionProducer producer) async {
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index 0750898..25b6c84 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.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/util.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
@@ -31,18 +29,18 @@
final ResolvedUnitResult resolvedResult;
final ChangeWorkspace workspace;
- AstNode node;
+ AstNode? node;
BaseProcessor({
this.selectionOffset = -1,
this.selectionLength = 0,
- @required this.resolvedResult,
- @required this.workspace,
- }) : file = resolvedResult.path,
+ required this.resolvedResult,
+ required this.workspace,
+ }) : file = resolvedResult.path!,
session = resolvedResult.session,
sessionHelper = AnalysisSessionHelper(resolvedResult.session),
typeProvider = resolvedResult.typeProvider,
- selectionEnd = (selectionOffset ?? 0) + (selectionLength ?? 0),
+ selectionEnd = selectionOffset + selectionLength,
utils = CorrectionUtils(resolvedResult);
Flutter get flutter => Flutter.instance;
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 093355b..9b3dba2 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -263,7 +263,7 @@
(name) => [],
);
- var context = CorrectionProducerContext(
+ var context = CorrectionProducerContext.create(
applyingBulkFixes: true,
dartFixContext: fixContext,
diagnostic: diagnostic,
@@ -272,6 +272,9 @@
selectionLength: diagnostic.length,
workspace: workspace,
);
+ if (context == null) {
+ return;
+ }
for (final multiGenerator in multiGenerators) {
final multiProducer = multiGenerator();
@@ -314,7 +317,7 @@
ResolvedUnitResult result,
AnalysisError diagnostic,
TransformOverrideSet overrideSet) async {
- var context = CorrectionProducerContext(
+ var context = CorrectionProducerContext.create(
applyingBulkFixes: true,
dartFixContext: fixContext,
diagnostic: diagnostic,
@@ -324,9 +327,7 @@
selectionLength: diagnostic.length,
workspace: workspace,
);
-
- var setupSuccess = context.setupCompute();
- if (!setupSuccess) {
+ if (context == null) {
return;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 6bef12b..425dc82 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/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 'dart:math' as math;
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
@@ -31,7 +29,6 @@
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
-import 'package:meta/meta.dart';
/// An object that can compute a correction (fix or assist) in a Dart file.
abstract class CorrectionProducer extends SingleCorrectionProducer {
@@ -56,28 +53,30 @@
Future<void> compute(ChangeBuilder builder);
/// Return the class, enum or mixin declaration for the given [element].
- Future<ClassOrMixinDeclaration> getClassOrMixinDeclaration(
+ Future<ClassOrMixinDeclaration?> getClassOrMixinDeclaration(
ClassElement element) async {
var result = await sessionHelper.getElementDeclaration(element);
- if (result.node is ClassOrMixinDeclaration) {
- return result.node;
+ var node = result?.node;
+ if (node is ClassOrMixinDeclaration) {
+ return node;
}
return null;
}
/// Return the extension declaration for the given [element].
- Future<ExtensionDeclaration> getExtensionDeclaration(
+ Future<ExtensionDeclaration?> getExtensionDeclaration(
ExtensionElement element) async {
var result = await sessionHelper.getElementDeclaration(element);
- if (result.node is ExtensionDeclaration) {
- return result.node;
+ var node = result?.node;
+ if (node is ExtensionDeclaration) {
+ return node;
}
return null;
}
/// Return the class element associated with the [target], or `null` if there
/// is no such class element.
- ClassElement getTargetClassElement(Expression target) {
+ ClassElement? getTargetClassElement(Expression target) {
var type = target.staticType;
if (type is InterfaceType) {
return type.element;
@@ -92,7 +91,7 @@
/// Returns an expected [DartType] of [expression], may be `null` if cannot be
/// inferred.
- DartType inferUndefinedExpressionType(Expression expression) {
+ DartType? inferUndefinedExpressionType(Expression expression) {
var parent = expression.parent;
// myFunction();
if (parent is ExpressionStatement) {
@@ -120,9 +119,7 @@
var assignment = parent;
if (assignment.leftHandSide == expression) {
var rhs = assignment.rightHandSide;
- if (rhs != null) {
- return rhs.staticType;
- }
+ return rhs.staticType;
}
}
// v = myFunction();
@@ -227,47 +224,72 @@
final AnalysisSessionHelper sessionHelper;
final ResolvedUnitResult resolvedResult;
final ChangeWorkspace workspace;
- final DartFixContext dartFixContext;
+
+ /// TODO(migration) Make it non-nullable, specialize "fix" context?
+ final DartFixContext? dartFixContext;
/// A flag indicating whether the correction producers will be run in the
/// context of applying bulk fixes.
final bool applyingBulkFixes;
- final Diagnostic diagnostic;
+ final Diagnostic? diagnostic;
- final TransformOverrideSet overrideSet;
+ final TransformOverrideSet? overrideSet;
- AstNode _node;
+ final AstNode node;
- CorrectionProducerContext({
- @required this.resolvedResult,
- @required this.workspace,
+ CorrectionProducerContext._({
+ required this.resolvedResult,
+ required this.workspace,
this.applyingBulkFixes = false,
this.dartFixContext,
this.diagnostic,
+ required this.node,
this.overrideSet,
this.selectionOffset = -1,
this.selectionLength = 0,
- }) : file = resolvedResult.path,
+ }) : file = resolvedResult.path!,
session = resolvedResult.session,
sessionHelper = AnalysisSessionHelper(resolvedResult.session),
typeProvider = resolvedResult.typeProvider,
- selectionEnd = (selectionOffset ?? 0) + (selectionLength ?? 0),
- unit = resolvedResult.unit,
+ selectionEnd = selectionOffset + selectionLength,
+ unit = resolvedResult.unit!,
utils = CorrectionUtils(resolvedResult);
- AstNode get node => _node;
-
/// Return `true` if the lint with the given [name] is enabled.
bool isLintEnabled(String name) {
var analysisOptions = session.analysisContext.analysisOptions;
return analysisOptions.isLintEnabled(name);
}
- bool setupCompute() {
- final locator = NodeLocator(selectionOffset, selectionEnd);
- _node = locator.searchWithin(resolvedResult.unit);
- return _node != null;
+ static CorrectionProducerContext? create({
+ required ResolvedUnitResult resolvedResult,
+ required ChangeWorkspace workspace,
+ bool applyingBulkFixes = false,
+ DartFixContext? dartFixContext,
+ Diagnostic? diagnostic,
+ TransformOverrideSet? overrideSet,
+ int selectionOffset = -1,
+ int selectionLength = 0,
+ }) {
+ var selectionEnd = selectionOffset + selectionLength;
+ var locator = NodeLocator(selectionOffset, selectionEnd);
+ var node = locator.searchWithin(resolvedResult.unit);
+ if (node == null) {
+ return null;
+ }
+
+ return CorrectionProducerContext._(
+ resolvedResult: resolvedResult,
+ workspace: workspace,
+ node: node,
+ applyingBulkFixes: applyingBulkFixes,
+ dartFixContext: dartFixContext,
+ diagnostic: diagnostic,
+ overrideSet: overrideSet,
+ selectionOffset: selectionOffset,
+ selectionLength: selectionLength,
+ );
}
}
@@ -283,53 +305,54 @@
/// Return the arguments that should be used when composing the message for an
/// assist, or `null` if the assist message has no parameters or if this
/// producer doesn't support assists.
- List<Object> get assistArguments => null;
+ List<Object>? get assistArguments => null;
/// Return the assist kind that should be used to build an assist, or `null`
/// if this producer doesn't support assists.
- AssistKind get assistKind => null;
+ AssistKind? get assistKind => null;
/// Return the length of the error message being fixed, or `null` if there is
/// no diagnostic.
- int get errorLength => diagnostic?.problemMessage?.length;
+ int? get errorLength => diagnostic?.problemMessage.length;
/// Return the text of the error message being fixed, or `null` if there is
/// no diagnostic.
- String get errorMessage => diagnostic?.problemMessage?.message;
+ String? get errorMessage => diagnostic?.problemMessage.message;
/// Return the offset of the error message being fixed, or `null` if there is
/// no diagnostic.
- int get errorOffset => diagnostic?.problemMessage?.offset;
+ int? get errorOffset => diagnostic?.problemMessage.offset;
/// Return the arguments that should be used when composing the message for a
/// fix, or `null` if the fix message has no parameters or if this producer
/// doesn't support fixes.
- List<Object> get fixArguments => null;
+ List<Object>? get fixArguments => null;
/// Return the fix kind that should be used to build a fix, or `null` if this
/// producer doesn't support fixes.
- FixKind get fixKind => null;
+ FixKind? get fixKind => null;
/// Return the arguments that should be used when composing the message for a
/// multi-fix, or `null` if the fix message has no parameters or if this
/// producer doesn't support multi-fixes.
- List<Object> get multiFixArguments => null;
+ List<Object>? get multiFixArguments => null;
/// Return the fix kind that should be used to build a multi-fix, or `null` if
/// this producer doesn't support multi-fixes.
- FixKind get multiFixKind => null;
+ FixKind? get multiFixKind => null;
}
/// The behavior shared by [CorrectionProducer] and [MultiCorrectionProducer].
abstract class _AbstractCorrectionProducer {
/// The context used to produce corrections.
- CorrectionProducerContext _context;
+ /// TODO(migration) Make it not `late`, require in constructor.
+ late CorrectionProducerContext _context;
/// The most deeply nested node that completely covers the highlight region of
/// the diagnostic, or `null` if there is no diagnostic, such a node does not
/// exist, or if it hasn't been computed yet. Use [coveredNode] to access this
/// field.
- AstNode _coveredNode;
+ AstNode? _coveredNode;
/// Initialize a newly created producer.
_AbstractCorrectionProducer();
@@ -340,7 +363,7 @@
/// The most deeply nested node that completely covers the highlight region of
/// the diagnostic, or `null` if there is no diagnostic or if such a node does
/// not exist.
- AstNode get coveredNode {
+ AstNode? get coveredNode {
// TODO(brianwilkerson) Consider renaming this to `coveringNode`.
if (_coveredNode == null) {
var diagnostic = this.diagnostic;
@@ -358,7 +381,7 @@
/// Return the diagnostic being fixed, or `null` if this producer is being
/// used to produce an assist.
- Diagnostic get diagnostic => _context.diagnostic;
+ Diagnostic? get diagnostic => _context.diagnostic;
/// Returns the EOL to use for this [CompilationUnit].
String get eol => utils.endOfLine;
@@ -375,7 +398,7 @@
/// Return the set of overrides to be applied to the transform set when
/// running tests, or `null` if there are no overrides to apply.
- TransformOverrideSet get overrideSet => _context.overrideSet;
+ TransformOverrideSet? get overrideSet => _context.overrideSet;
ResolvedUnitResult get resolvedResult => _context.resolvedResult;
@@ -413,7 +436,7 @@
/// Return the function body of the most deeply nested method or function that
/// encloses the [node], or `null` if the node is not in a method or function.
- FunctionBody getEnclosingFunctionBody() {
+ FunctionBody? getEnclosingFunctionBody() {
var closure = node.thisOrAncestorOfType<FunctionExpression>();
if (closure != null) {
return closure.body;
@@ -441,7 +464,7 @@
/// Return the top-level declarations with the [name] in libraries that are
/// available to this context.
List<TopLevelDeclaration> getTopLevelDeclarations(String name) =>
- _context.dartFixContext.getTopLevelDeclarations(name);
+ _context.dartFixContext!.getTopLevelDeclarations(name);
/// Return `true` the lint with the given [name] is enabled.
bool isLintEnabled(String name) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
index 79c8f63..289a537 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_async.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_async.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';
@@ -27,21 +25,22 @@
Future<void> compute(ChangeBuilder builder) async {
if (isForMissingReturn) {
var parent = node.parent;
- DartType returnType;
- FunctionBody body;
+ FunctionBody? body;
+ DartType? returnType;
if (parent is FunctionDeclaration) {
- returnType = parent.declaredElement.returnType;
body = parent.functionExpression.body;
+ returnType = parent.declaredElement!.returnType;
} else if (parent is MethodDeclaration) {
- returnType = parent.declaredElement.returnType;
body = parent.body;
+ returnType = parent.declaredElement!.returnType;
}
- if (body == null) {
+ if (body == null || returnType == null) {
return;
}
if (_isFutureVoid(returnType) && _hasNoReturns(body)) {
+ var final_body = body;
await builder.addDartFileEdit(file, (builder) {
- builder.addSimpleInsertion(body.offset, 'async ');
+ builder.addSimpleInsertion(final_body.offset, 'async ');
});
}
} else {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
index 794bb72..c1892ff 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/wrap_in_future.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,21 +18,26 @@
//
// Extract the information needed to build the edit.
//
- Expression expression;
+ Expression? expression;
+ var node = this.node;
if (node is ReturnStatement) {
- expression = (node as ReturnStatement).expression;
+ expression = node.expression;
} else if (node is Expression) {
expression = node;
- } else {
+ }
+ if (expression == null) {
return;
}
var value = utils.getNodeText(expression);
//
// Build the edit.
//
+ var final_expression = expression;
await builder.addDartFileEdit(file, (builder) {
builder.addSimpleReplacement(
- range.node(expression), 'Future.value($value)');
+ range.node(final_expression),
+ 'Future.value($value)',
+ );
});
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index dfc9b79..e8795a1f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -210,16 +210,19 @@
var workspace = context.workspace;
var resolveResult = context.resolveResult;
- var generators = _getGenerators(
- error.errorCode,
- CorrectionProducerContext(
- dartFixContext: context,
- diagnostic: error,
- resolvedResult: resolveResult,
- selectionOffset: context.error.offset,
- selectionLength: context.error.length,
- workspace: workspace,
- ));
+ var correctionContext = CorrectionProducerContext.create(
+ dartFixContext: context,
+ diagnostic: error,
+ resolvedResult: resolveResult,
+ selectionOffset: context.error.offset,
+ selectionLength: context.error.length,
+ workspace: workspace,
+ );
+ if (correctionContext == null) {
+ return const <Fix>[];
+ }
+
+ var generators = _getGenerators(error.errorCode, correctionContext);
var fixes = <Fix>[];
for (var generator in generators) {
@@ -248,7 +251,7 @@
Future<void> _fixError(DartFixContext fixContext, FixState fixState,
CorrectionProducer producer, AnalysisError diagnostic) async {
- var context = CorrectionProducerContext(
+ var context = CorrectionProducerContext.create(
applyingBulkFixes: true,
dartFixContext: fixContext,
diagnostic: diagnostic,
@@ -257,9 +260,7 @@
selectionLength: diagnostic.length,
workspace: fixContext.workspace,
);
-
- var setupSuccess = context.setupCompute();
- if (!setupSuccess) {
+ if (context == null) {
return;
}
@@ -1745,7 +1746,7 @@
Future<void> _addFromProducers() async {
var error = fixContext.error;
- var context = CorrectionProducerContext(
+ var context = CorrectionProducerContext.create(
dartFixContext: fixContext,
diagnostic: error,
resolvedResult: resolvedResult,
@@ -1753,9 +1754,7 @@
selectionLength: fixContext.error.length,
workspace: workspace,
);
-
- var setupSuccess = context.setupCompute();
- if (!setupSuccess) {
+ if (context == null) {
return;
}