Add a fix to insert the keyword late

Change-Id: I40612fd2710a1189137d8ba676c1b66b4943d677
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151037
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Brian Wilkerson 2020-06-21 17:33:10 +00:00
parent 52dd48651b
commit 32d403b472
5 changed files with 140 additions and 0 deletions

View file

@ -0,0 +1,55 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// 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.
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_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
class AddLate extends CorrectionProducer {
@override
FixKind get fixKind => DartFixKind.ADD_LATE;
@override
Future<void> compute(DartChangeBuilder builder) async {
if (!libraryElement.isNonNullableByDefault) {
return;
}
if (node is SimpleIdentifier &&
node.parent is VariableDeclaration &&
node.parent.parent is VariableDeclarationList) {
var list = node.parent.parent as VariableDeclarationList;
if (!list.isLate) {
if (list.type == null) {
var keyword = list.keyword;
if (keyword == null) {
await _insertAt(builder, list.variables[0].offset);
// TODO(brianwilkerson) Consider converting this into an assist and
// expand it to support converting `var` to `late` as well as
// working anywhere a non-late local variable or field is selected.
// } else if (keyword.type == Keyword.VAR) {
// builder.addFileEdit(file, (builder) {
// builder.addSimpleReplacement(range.token(keyword), 'late');
// });
} else if (keyword.type != Keyword.CONST) {
await _insertAt(builder, list.variables[0].offset);
}
} else {
await _insertAt(builder, list.type.offset);
}
}
}
}
void _insertAt(DartChangeBuilder builder, int offset) async {
await builder.addFileEdit(file, (builder) {
builder.addSimpleInsertion(offset, 'late ');
});
}
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
static AddLate newInstance() => AddLate();
}

View file

@ -154,6 +154,8 @@ class DartFixKind {
'dart.fix.add.fieldFormalParameters',
70,
'Add final field formal parameters');
static const ADD_LATE =
FixKind('dart.fix.add.late', 50, "Add 'late' modifier");
static const ADD_MISSING_ENUM_CASE_CLAUSES = FixKind(
'dart.fix.add.missingEnumCaseClauses', 50, 'Add missing case clauses');
static const ADD_MISSING_PARAMETER_NAMED = FixKind(

View file

@ -15,6 +15,7 @@ import 'package:analysis_server/src/services/correction/dart/add_const.dart';
import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
import 'package:analysis_server/src/services/correction/dart/add_explicit_cast.dart';
import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
import 'package:analysis_server/src/services/correction/dart/add_late.dart';
import 'package:analysis_server/src/services/correction/dart/add_missing_enum_case_clauses.dart';
import 'package:analysis_server/src/services/correction/dart/add_missing_parameter.dart';
import 'package:analysis_server/src/services/correction/dart/add_missing_parameter_named.dart';
@ -627,6 +628,9 @@ class FixProcessor extends BaseProcessor {
ChangeTo.classOrMixin,
CreateClass.newInstance,
],
CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD: [
AddLate.newInstance,
],
CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE: [
RemoveQuestionMark.newInstance,
],
@ -912,6 +916,7 @@ class FixProcessor extends BaseProcessor {
RemoveDeadIfNull.newInstance,
],
StaticWarningCode.FINAL_NOT_INITIALIZED: [
AddLate.newInstance,
CreateConstructorForFinalFields.newInstance,
],
StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1: [

View file

@ -0,0 +1,76 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// 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.
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'fix_processor.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AddLatePreNnbdTest);
defineReflectiveTests(AddLateTest);
});
}
@reflectiveTest
class AddLatePreNnbdTest extends FixProcessorTest {
@override
FixKind get kind => DartFixKind.ADD_LATE;
Future<void> test_withFinal() async {
await resolveTestUnit('''
class C {
final String s;
}
''');
await assertNoFix();
}
}
@reflectiveTest
class AddLateTest extends FixProcessorTest {
@override
List<String> get experiments => [EnableString.non_nullable];
@override
FixKind get kind => DartFixKind.ADD_LATE;
Future<void> test_withFinal() async {
await resolveTestUnit('''
class C {
final String s;
}
''');
await assertHasFix('''
class C {
final late String s;
}
''');
}
Future<void> test_withLate() async {
await resolveTestUnit('''
class C {
late s;
}
''');
await assertNoFix();
}
Future<void> test_withType() async {
await resolveTestUnit('''
class C {
String s;
}
''');
await assertHasFix('''
class C {
late String s;
}
''');
}
}

View file

@ -12,6 +12,7 @@ import 'add_diagnostic_property_reference_test.dart'
as add_diagnostic_property_reference;
import 'add_explicit_cast_test.dart' as add_explicit_cast;
import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
import 'add_late_test.dart' as add_late;
import 'add_missing_enum_case_clauses_test.dart'
as add_missing_enum_case_clauses;
import 'add_missing_parameter_named_test.dart' as add_missing_parameter_named;
@ -170,6 +171,7 @@ void main() {
add_diagnostic_property_reference.main();
add_explicit_cast.main();
add_field_formal_parameters.main();
add_late.main();
add_missing_enum_case_clauses.main();
add_missing_parameter_named.main();
add_missing_parameter_positional.main();