Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e41a600

Browse files
author
Dart CI
committed
Version 2.10.0-136.0.dev
Merge commit '0eec9ee53c4306abea1733b3b5cc2bfb57cbe380' into 'dev'
2 parents 8336597 + 0eec9ee commit e41a600

File tree

24 files changed

+992
-119
lines changed

24 files changed

+992
-119
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
void forEachStatement(Object x) {
6+
if (x is int) {
7+
/*int*/ x;
8+
for (x in [0]) {
9+
/*int*/ x;
10+
}
11+
}
12+
}
13+
14+
forEachElementInListLiteral(Object x) {
15+
if (x is int) {
16+
/*int*/ x;
17+
return [
18+
for (x in [0]) /*int*/ x
19+
];
20+
}
21+
}
22+
23+
forEachElementInMapLiteral(Object x) {
24+
if (x is int) {
25+
/*int*/ x;
26+
return {
27+
for (x in [0]) /*int*/ x: /*int*/ x
28+
};
29+
}
30+
}
31+
32+
forEachElementInSetLiteral(Object x) {
33+
if (x is int) {
34+
/*int*/ x;
35+
return {
36+
for (x in [0]) /*int*/ x
37+
};
38+
}
39+
}

pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4938,8 +4938,8 @@ class CreateFile implements ToJsonable {
49384938
reporter.reportError('must not be null');
49394939
return false;
49404940
}
4941-
if (!(obj['kind'] is String)) {
4942-
reporter.reportError('must be of type String');
4941+
if (!(obj['kind'] == 'create')) {
4942+
reporter.reportError('must be the literal \'create\'');
49434943
return false;
49444944
}
49454945
} finally {
@@ -5963,8 +5963,8 @@ class DeleteFile implements ToJsonable {
59635963
reporter.reportError('must not be null');
59645964
return false;
59655965
}
5966-
if (!(obj['kind'] is String)) {
5967-
reporter.reportError('must be of type String');
5966+
if (!(obj['kind'] == 'delete')) {
5967+
reporter.reportError('must be the literal \'delete\'');
59685968
return false;
59695969
}
59705970
} finally {
@@ -13198,7 +13198,10 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable {
1319813198
final capabilities = json['capabilities'] != null
1319913199
? ClientCapabilities.fromJson(json['capabilities'])
1320013200
: null;
13201-
final trace = json['trace'];
13201+
final trace = const {null, 'off', 'messages', 'verbose'}
13202+
.contains(json['trace'])
13203+
? json['trace']
13204+
: throw '''${json['trace']} was not one of (null, 'off', 'messages', 'verbose')''';
1320213205
final workspaceFolders = json['workspaceFolders']
1320313206
?.map((item) => item != null ? WorkspaceFolder.fromJson(item) : null)
1320413207
?.cast<WorkspaceFolder>()
@@ -13363,8 +13366,12 @@ class InitializeParams implements WorkDoneProgressParams, ToJsonable {
1336313366
}
1336413367
reporter.push('trace');
1336513368
try {
13366-
if (obj['trace'] != null && !(obj['trace'] is String)) {
13367-
reporter.reportError('must be of type String');
13369+
if (obj['trace'] != null &&
13370+
!((obj['trace'] == 'off' ||
13371+
obj['trace'] == 'messages' ||
13372+
obj['trace'] == 'verbose'))) {
13373+
reporter.reportError(
13374+
'must be one of the literals \'off\', \'messages\', \'verbose\'');
1336813375
return false;
1336913376
}
1337013377
} finally {
@@ -16647,8 +16654,8 @@ class RenameFile implements ToJsonable {
1664716654
reporter.reportError('must not be null');
1664816655
return false;
1664916656
}
16650-
if (!(obj['kind'] is String)) {
16651-
reporter.reportError('must be of type String');
16657+
if (!(obj['kind'] == 'rename')) {
16658+
reporter.reportError('must be the literal \'rename\'');
1665216659
return false;
1665316660
}
1665416661
} finally {
@@ -23813,8 +23820,8 @@ class WorkDoneProgressBegin implements ToJsonable {
2381323820
reporter.reportError('must not be null');
2381423821
return false;
2381523822
}
23816-
if (!(obj['kind'] is String)) {
23817-
reporter.reportError('must be of type String');
23823+
if (!(obj['kind'] == 'begin')) {
23824+
reporter.reportError('must be the literal \'begin\'');
2381823825
return false;
2381923826
}
2382023827
} finally {
@@ -24090,8 +24097,8 @@ class WorkDoneProgressEnd implements ToJsonable {
2409024097
reporter.reportError('must not be null');
2409124098
return false;
2409224099
}
24093-
if (!(obj['kind'] is String)) {
24094-
reporter.reportError('must be of type String');
24100+
if (!(obj['kind'] == 'end')) {
24101+
reporter.reportError('must be the literal \'end\'');
2409524102
return false;
2409624103
}
2409724104
} finally {
@@ -24464,8 +24471,8 @@ class WorkDoneProgressReport implements ToJsonable {
2446424471
reporter.reportError('must not be null');
2446524472
return false;
2446624473
}
24467-
if (!(obj['kind'] is String)) {
24468-
reporter.reportError('must be of type String');
24474+
if (!(obj['kind'] == 'report')) {
24475+
reporter.reportError('must be the literal \'report\'');
2446924476
return false;
2447024477
}
2447124478
} finally {
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
6+
import 'package:analysis_server/src/services/correction/fix.dart';
7+
import 'package:analyzer/dart/analysis/features.dart';
8+
import 'package:analyzer/dart/ast/ast.dart';
9+
import 'package:analyzer/dart/ast/token.dart';
10+
import 'package:analyzer/dart/element/element.dart';
11+
import 'package:analyzer/dart/element/nullability_suffix.dart';
12+
import 'package:analyzer/src/dart/element/type.dart';
13+
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
14+
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
15+
import 'package:analyzer_plugin/utilities/range_factory.dart';
16+
17+
class MakeVariableNullable extends CorrectionProducer {
18+
/// The name of the variable whose type is to be made nullable.
19+
String _variableName;
20+
21+
@override
22+
List<Object> get fixArguments => [_variableName];
23+
24+
@override
25+
FixKind get fixKind => DartFixKind.MAKE_VARIABLE_NULLABLE;
26+
27+
@override
28+
Future<void> compute(ChangeBuilder builder) async {
29+
var node = coveredNode;
30+
var parent = node?.parent;
31+
if (unit.featureSet.isEnabled(Feature.non_nullable) &&
32+
parent is AssignmentExpression &&
33+
parent.rightHandSide == node) {
34+
var leftHandSide = parent.leftHandSide;
35+
if (leftHandSide is SimpleIdentifier) {
36+
var element = leftHandSide.staticElement;
37+
if (element is LocalVariableElement) {
38+
var oldType = element.type;
39+
var newType = (node as Expression).staticType;
40+
if (node is NullLiteral) {
41+
newType = (oldType as InterfaceTypeImpl)
42+
.withNullability(NullabilitySuffix.question);
43+
} else if (!typeSystem.isAssignableTo(
44+
oldType, typeSystem.promoteToNonNull(newType))) {
45+
return;
46+
}
47+
var declarationList =
48+
_findDeclaration(element, parent.thisOrAncestorOfType<Block>());
49+
if (declarationList == null || declarationList.variables.length > 1) {
50+
return;
51+
}
52+
var variable = declarationList.variables[0];
53+
_variableName = variable.name.name;
54+
await builder.addDartFileEdit(file, (builder) {
55+
var keyword = declarationList.keyword;
56+
if (keyword != null && keyword.type == Keyword.VAR) {
57+
builder.addReplacement(range.token(keyword), (builder) {
58+
builder.writeType(newType);
59+
});
60+
} else if (keyword == null) {
61+
if (declarationList.type == null) {
62+
builder.addInsertion(variable.offset, (builder) {
63+
builder.writeType(newType);
64+
builder.write(' ');
65+
});
66+
} else {
67+
builder.addSimpleInsertion(declarationList.type.end, '?');
68+
}
69+
}
70+
});
71+
}
72+
}
73+
}
74+
}
75+
76+
/// Return the list of variable declarations containing the declaration of the
77+
/// given [variable] that is located in the given [block] or in a surrounding
78+
/// block. Return `null` if the declaration can't be found.
79+
VariableDeclarationList _findDeclaration(
80+
LocalVariableElement variable, Block block) {
81+
if (variable == null) {
82+
return null;
83+
}
84+
var currentBlock = block;
85+
while (currentBlock != null) {
86+
for (var statement in block.statements) {
87+
if (statement is VariableDeclarationStatement) {
88+
var variableList = statement.variables;
89+
if (variableList != null) {
90+
var variables = variableList.variables;
91+
for (var declaration in variables) {
92+
if (declaration.declaredElement == variable) {
93+
return variableList;
94+
}
95+
}
96+
}
97+
}
98+
}
99+
currentBlock = currentBlock.parent.thisOrAncestorOfType<Block>();
100+
}
101+
return null;
102+
}
103+
104+
/// Return an instance of this class. Used as a tear-off in `FixProcessor`.
105+
static MakeVariableNullable newInstance() => MakeVariableNullable();
106+
}

pkg/analysis_server/lib/src/services/correction/fix.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ class DartFixKind {
323323
'Move type arguments to after class name');
324324
static const MAKE_VARIABLE_NOT_FINAL = FixKind(
325325
'dart.fix.makeVariableNotFinal', 50, "Make variable '{0}' not final");
326+
static const MAKE_VARIABLE_NULLABLE =
327+
FixKind('dart.fix.makeVariableNullable', 50, "Make '{0}' nullable");
326328
static const ORGANIZE_IMPORTS =
327329
FixKind('dart.fix.organize.imports', 50, 'Organize Imports');
328330
static const QUALIFY_REFERENCE =

pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import 'package:analysis_server/src/services/correction/dart/make_field_not_fina
8080
import 'package:analysis_server/src/services/correction/dart/make_final.dart';
8181
import 'package:analysis_server/src/services/correction/dart/make_return_type_nullable.dart';
8282
import 'package:analysis_server/src/services/correction/dart/make_variable_not_final.dart';
83+
import 'package:analysis_server/src/services/correction/dart/make_variable_nullable.dart';
8384
import 'package:analysis_server/src/services/correction/dart/move_type_arguments_to_class.dart';
8485
import 'package:analysis_server/src/services/correction/dart/organize_imports.dart';
8586
import 'package:analysis_server/src/services/correction/dart/qualify_reference.dart';
@@ -716,6 +717,7 @@ class FixProcessor extends BaseProcessor {
716717
AddExplicitCast.newInstance,
717718
AddNullCheck.newInstance,
718719
ChangeTypeAnnotation.newInstance,
720+
MakeVariableNullable.newInstance,
719721
],
720722
CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION: [
721723
RemoveParenthesesInGetterInvocation.newInstance,
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analysis_server/src/services/correction/fix.dart';
6+
import 'package:analyzer/src/dart/analysis/experiments.dart';
7+
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
8+
import 'package:test_reflective_loader/test_reflective_loader.dart';
9+
10+
import 'fix_processor.dart';
11+
12+
void main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(MakeVariableNullableTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class MakeVariableNullableTest extends FixProcessorTest {
20+
@override
21+
List<String> get experiments => [EnableString.non_nullable];
22+
23+
@override
24+
FixKind get kind => DartFixKind.MAKE_VARIABLE_NULLABLE;
25+
26+
Future<void> test_lhsNotIdentifier() async {
27+
await resolveTestUnit('''
28+
void f(C c) {
29+
c.s = null;
30+
}
31+
class C {
32+
String s = '';
33+
}
34+
''');
35+
await assertNoFix();
36+
}
37+
38+
Future<void> test_lhsNotLocalVariable() async {
39+
await resolveTestUnit('''
40+
var s = '';
41+
void f() {
42+
s = null;
43+
print(s);
44+
}
45+
''');
46+
await assertNoFix();
47+
}
48+
49+
Future<void> test_multipleVariables() async {
50+
await resolveTestUnit('''
51+
void f() {
52+
var s = '', t = '';
53+
s = null;
54+
print(s);
55+
print(t);
56+
}
57+
''');
58+
await assertNoFix();
59+
}
60+
61+
Future<void> test_noKeywordOrType() async {
62+
await resolveTestUnit('''
63+
void f() {
64+
late s = '';
65+
s = null;
66+
print(s);
67+
}
68+
''');
69+
await assertHasFix('''
70+
void f() {
71+
late String? s = '';
72+
s = null;
73+
print(s);
74+
}
75+
''');
76+
}
77+
78+
Future<void> test_type() async {
79+
await resolveTestUnit('''
80+
void f() {
81+
String s = '';
82+
s = null;
83+
print(s);
84+
}
85+
''');
86+
await assertHasFix('''
87+
void f() {
88+
String? s = '';
89+
s = null;
90+
print(s);
91+
}
92+
''');
93+
}
94+
95+
Future<void> test_var() async {
96+
await resolveTestUnit('''
97+
void f() {
98+
var s = '';
99+
s = null;
100+
print(s);
101+
}
102+
''');
103+
await assertHasFix('''
104+
void f() {
105+
String? s = '';
106+
s = null;
107+
print(s);
108+
}
109+
''');
110+
}
111+
}

pkg/analysis_server/test/src/services/correction/fix/test_all.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import 'make_field_not_final_test.dart' as make_field_not_final;
9494
import 'make_final_test.dart' as make_final;
9595
import 'make_return_type_nullable_test.dart' as make_return_type_nullable;
9696
import 'make_variable_not_final_test.dart' as make_variable_not_final;
97+
import 'make_variable_nullable_test.dart' as make_variable_nullable;
9798
import 'move_type_arguments_to_class_test.dart' as move_type_arguments_to_class;
9899
import 'organize_imports_test.dart' as organize_imports;
99100
import 'qualify_reference_test.dart' as qualify_reference;
@@ -249,6 +250,7 @@ void main() {
249250
make_final.main();
250251
make_return_type_nullable.main();
251252
make_variable_not_final.main();
253+
make_variable_nullable.main();
252254
move_type_arguments_to_class.main();
253255
organize_imports.main();
254256
qualify_reference.main();

0 commit comments

Comments
 (0)