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

Commit 14f1940

Browse files
author
Dart CI
committed
Version 2.10.0-116.0.dev
Merge commit '8d68480746dbb7878bdc6e3926d0324760af6c5f' into 'dev'
2 parents 1abce6d + 8d68480 commit 14f1940

File tree

11 files changed

+206
-84
lines changed

11 files changed

+206
-84
lines changed

pkg/analysis_server/lib/src/services/completion/dart/utilities.dart

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,24 @@ protocol.Element createLocalElement(
168168
returnType: nameForType(id, returnType));
169169
}
170170

171-
DefaultArgument getDefaultStringParameterValue(ParameterElement param) {
172-
if (param != null) {
173-
var type = param.type;
174-
if (type is InterfaceType && type.isDartCoreList) {
175-
return DefaultArgument('[]', cursorPosition: 1);
171+
/// Return a default argument value for the given [parameter].
172+
DefaultArgument getDefaultStringParameterValue(ParameterElement parameter) {
173+
if (parameter != null) {
174+
var type = parameter.type;
175+
if (type is InterfaceType) {
176+
if (type.isDartCoreBool) {
177+
return DefaultArgument('false');
178+
} else if (type.isDartCoreDouble) {
179+
return DefaultArgument('0.0');
180+
} else if (type.isDartCoreInt) {
181+
return DefaultArgument('0');
182+
} else if (type.isDartCoreList) {
183+
return DefaultArgument('[]', cursorPosition: 1);
184+
} else if (type.isDartCoreMap) {
185+
return DefaultArgument('{}', cursorPosition: 1);
186+
} else if (type.isDartCoreString) {
187+
return DefaultArgument("''", cursorPosition: 1);
188+
}
176189
} else if (type is FunctionType) {
177190
var params = type.parameters
178191
.map((p) => '${getTypeString(p.type)}${p.name}')
@@ -181,9 +194,6 @@ DefaultArgument getDefaultStringParameterValue(ParameterElement param) {
181194
var text = '($params) { }';
182195
return DefaultArgument(text, cursorPosition: text.length - 2);
183196
}
184-
185-
// TODO(pq): support map literals
186-
187197
}
188198

189199
return null;

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:analysis_server/src/services/correction/dart/abstract_producer.d
88
import 'package:analysis_server/src/services/correction/fix.dart';
99
import 'package:analyzer/dart/ast/ast.dart';
1010
import 'package:analyzer/dart/element/element.dart';
11+
import 'package:analyzer/dart/element/nullability_suffix.dart';
1112
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1213
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1314

@@ -43,7 +44,7 @@ class AddMissingRequiredArgument extends CorrectionProducer {
4344
}
4445

4546
if (targetElement is ExecutableElement) {
46-
// Format: "Missing required argument 'foo"
47+
// Format: "Missing required argument 'foo'."
4748
var messageParts = diagnostic.problemMessage.message.split("'");
4849
if (messageParts.length < 2) {
4950
return;
@@ -78,6 +79,15 @@ class AddMissingRequiredArgument extends CorrectionProducer {
7879
}
7980
}
8081
}
82+
var defaultValue = getDefaultStringParameterValue(missingParameter);
83+
if (defaultValue == null &&
84+
libraryElement.isNonNullableByDefault &&
85+
missingParameter.type.nullabilitySuffix == NullabilitySuffix.none) {
86+
// In a library opted in to Null Safety we don't want to propose an
87+
// argument value of `null` for a parameter whose type doesn't allow
88+
// `null`.
89+
return;
90+
}
8191

8292
await builder.addDartFileEdit(file, (builder) {
8393
builder.addInsertion(offset, (builder) {
@@ -87,7 +97,6 @@ class AddMissingRequiredArgument extends CorrectionProducer {
8797

8898
builder.write('$_missingParameterName: ');
8999

90-
var defaultValue = getDefaultStringParameterValue(missingParameter);
91100
// Use defaultValue.cursorPosition if it's not null.
92101
if (defaultValue?.cursorPosition != null) {
93102
builder.write(

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,9 @@ class FixProcessor extends BaseProcessor {
720720
CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER: [
721721
AddRequiredKeyword.newInstance,
722722
],
723+
CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT: [
724+
AddMissingRequiredArgument.newInstance,
725+
],
723726
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE: [
724727
ExtendClassForMixin.newInstance,
725728
],

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

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analysis_server/src/services/correction/fix.dart';
6+
import 'package:analyzer/src/dart/analysis/experiments.dart';
67
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
78
import 'package:test_reflective_loader/test_reflective_loader.dart';
89

@@ -11,6 +12,7 @@ import 'fix_processor.dart';
1112
void main() {
1213
defineReflectiveSuite(() {
1314
defineReflectiveTests(AddMissingRequiredArgumentTest);
15+
defineReflectiveTests(AddMissingRequiredArgumentWithNullSafetyTest);
1416
});
1517
}
1618

@@ -72,7 +74,7 @@ class MyWidget extends Widget {
7274
}
7375
7476
build() {
75-
return new MyWidget(a: 1, b: null,);
77+
return new MyWidget(a: 1, b: 0,);
7678
}
7779
''');
7880
}
@@ -99,7 +101,7 @@ class A {
99101
}
100102
101103
void f() {
102-
A a = new A.named(a: null);
104+
A a = new A.named(a: 0);
103105
print(a);
104106
}
105107
''');
@@ -126,7 +128,7 @@ main() {
126128
import 'package:test/a.dart';
127129
128130
main() {
129-
A a = new A(a: null);
131+
A a = new A(a: 0);
130132
print(a);
131133
}
132134
''');
@@ -290,7 +292,7 @@ import 'package:meta/meta.dart';
290292
291293
test({@required int a, @required int bcd}) {}
292294
main() {
293-
test(a: 3, bcd: null);
295+
test(a: 3, bcd: 0);
294296
}
295297
''');
296298
}
@@ -310,7 +312,7 @@ import 'package:meta/meta.dart';
310312
311313
test({@required int a, @required int bcd}) {}
312314
main() {
313-
test(a: null);
315+
test(a: 0);
314316
}
315317
''', errorFilter: (error) => error.message.contains("'a'"));
316318
}
@@ -330,7 +332,7 @@ import 'package:meta/meta.dart';
330332
331333
test({@required int a, @required int bcd}) {}
332334
main() {
333-
test(bcd: null);
335+
test(bcd: 0);
334336
}
335337
''', errorFilter: (error) => error.message.contains("'bcd'"));
336338
}
@@ -362,7 +364,7 @@ class MyWidget extends Widget {
362364
363365
build() {
364366
return new MyWidget(
365-
foo: null,
367+
foo: '',
366368
child: null,
367369
);
368370
}
@@ -396,7 +398,7 @@ class MyWidget extends Widget {
396398
397399
build() {
398400
return new MyWidget(
399-
foo: null,
401+
foo: '',
400402
children: null,
401403
);
402404
}
@@ -418,10 +420,10 @@ import 'package:meta/meta.dart';
418420
419421
test({@required int abc}) {}
420422
main() {
421-
test(abc: null);
423+
test(abc: 0);
422424
}
423425
''');
424-
assertLinkedGroup(change.linkedEditGroups[0], ['null);']);
426+
assertLinkedGroup(change.linkedEditGroups[0], ['0);']);
425427
}
426428

427429
Future<void> test_single_normal() async {
@@ -439,7 +441,7 @@ import 'package:meta/meta.dart';
439441
440442
test(String x, {@required int abc}) {}
441443
main() {
442-
test("foo", abc: null);
444+
test("foo", abc: 0);
443445
}
444446
''');
445447
}
@@ -459,7 +461,71 @@ import 'package:meta/meta.dart';
459461
460462
test({@Required("Really who doesn't need an abc?") int abc}) {}
461463
main() {
462-
test(abc: null);
464+
test(abc: 0);
465+
}
466+
''');
467+
}
468+
}
469+
470+
@reflectiveTest
471+
class AddMissingRequiredArgumentWithNullSafetyTest extends FixProcessorTest {
472+
@override
473+
List<String> get experiments => [EnableString.non_nullable];
474+
475+
@override
476+
FixKind get kind => DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT;
477+
478+
Future<void> test_nonNullable_supported() async {
479+
await resolveTestUnit('''
480+
void f({required int x}) {}
481+
void g() {
482+
f();
483+
}
484+
''');
485+
await assertHasFix('''
486+
void f({required int x}) {}
487+
void g() {
488+
f(x: 0);
489+
}
490+
''');
491+
}
492+
493+
Future<void> test_nonNullable_unsupported() async {
494+
await resolveTestUnit('''
495+
void f({required DateTime d}) {}
496+
void g() {
497+
f();
498+
}
499+
''');
500+
await assertNoFix();
501+
}
502+
503+
Future<void> test_nullable_supported() async {
504+
await resolveTestUnit('''
505+
void f({required int? x}) {}
506+
void g() {
507+
f();
508+
}
509+
''');
510+
await assertHasFix('''
511+
void f({required int? x}) {}
512+
void g() {
513+
f(x: 0);
514+
}
515+
''');
516+
}
517+
518+
Future<void> test_nullable_unsupported() async {
519+
await resolveTestUnit('''
520+
void f({required DateTime? x}) {}
521+
void g() {
522+
f();
523+
}
524+
''');
525+
await assertHasFix('''
526+
void f({required DateTime? x}) {}
527+
void g() {
528+
f(x: null);
463529
}
464530
''');
465531
}

pkg/compiler/lib/src/inferrer/builder_kernel.dart

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -983,10 +983,11 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
983983
if (variable != null) {
984984
Local local = _localsMap.getLocalVariable(variable);
985985
if (!_capturedVariables.contains(local)) {
986+
// Receiver strengthening to non-null.
986987
DartType type = _localsMap.getLocalType(_elementMap, local);
987988
_state.updateLocal(
988989
_inferrer, _capturedAndBoxed, local, receiverType, node, type,
989-
isNullable: selector.appliesToNullWithoutThrow());
990+
excludeNull: !selector.appliesToNullWithoutThrow());
990991
}
991992
}
992993

@@ -1445,11 +1446,16 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
14451446
ir.Expression operand = node.operand;
14461447
if (operand is ir.VariableGet) {
14471448
Local local = _localsMap.getLocalVariable(operand.variable);
1448-
DartType type = _elementMap.getDartType(node.type);
1449+
DartType localType = _elementMap.getDartType(node.type);
14491450
LocalState stateAfterCheckWhenTrue = new LocalState.childPath(_state);
14501451
LocalState stateAfterCheckWhenFalse = new LocalState.childPath(_state);
1451-
stateAfterCheckWhenTrue.narrowLocal(
1452-
_inferrer, _capturedAndBoxed, local, type, node);
1452+
1453+
// Narrow variable to tested type on true branch.
1454+
TypeInformation currentTypeInformation = stateAfterCheckWhenTrue
1455+
.readLocal(_inferrer, _capturedAndBoxed, local);
1456+
stateAfterCheckWhenTrue.updateLocal(_inferrer, _capturedAndBoxed, local,
1457+
currentTypeInformation, node, localType,
1458+
isCast: false);
14531459
_setStateAfter(_state, stateAfterCheckWhenTrue, stateAfterCheckWhenFalse);
14541460
}
14551461
}
@@ -1462,10 +1468,18 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
14621468
DartType localType = _localsMap.getLocalType(_elementMap, local);
14631469
LocalState stateAfterCheckWhenTrue = new LocalState.childPath(_state);
14641470
LocalState stateAfterCheckWhenFalse = new LocalState.childPath(_state);
1471+
1472+
// Narrow tested variable to 'Null' on true branch.
14651473
stateAfterCheckWhenTrue.updateLocal(_inferrer, _capturedAndBoxed, local,
14661474
_types.nullType, node, localType);
1467-
stateAfterCheckWhenFalse.narrowLocal(_inferrer, _capturedAndBoxed, local,
1468-
_closedWorld.commonElements.objectType, node);
1475+
1476+
// Narrow tested variable to 'not null' on false branch.
1477+
TypeInformation currentTypeInformation = stateAfterCheckWhenFalse
1478+
.readLocal(_inferrer, _capturedAndBoxed, local);
1479+
stateAfterCheckWhenFalse.updateLocal(_inferrer, _capturedAndBoxed, local,
1480+
currentTypeInformation, node, _closedWorld.commonElements.objectType,
1481+
excludeNull: true);
1482+
14691483
_setStateAfter(_state, stateAfterCheckWhenTrue, stateAfterCheckWhenFalse);
14701484
}
14711485
}
@@ -1620,7 +1634,7 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
16201634
DartType type = _localsMap.getLocalType(_elementMap, local);
16211635
_state.updateLocal(
16221636
_inferrer, _capturedAndBoxed, local, localFunctionType, node, type,
1623-
isNullable: false);
1637+
excludeNull: true);
16241638
}
16251639

16261640
// We don't put the closure in the work queue of the
@@ -1737,7 +1751,7 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
17371751
Local local = _localsMap.getLocalVariable(exception);
17381752
_state.updateLocal(_inferrer, _capturedAndBoxed, local, mask, node,
17391753
_dartTypes.dynamicType(),
1740-
isNullable: false /* `throw null` produces a NullThrownError */);
1754+
excludeNull: true /* `throw null` produces a NullThrownError */);
17411755
}
17421756
ir.VariableDeclaration stackTrace = node.stackTrace;
17431757
if (stackTrace != null) {
@@ -2088,9 +2102,11 @@ class LocalState {
20882102
TypeInformation type,
20892103
ir.Node node,
20902104
DartType staticType,
2091-
{isNullable: true}) {
2105+
{isCast: true,
2106+
excludeNull: false}) {
20922107
assert(type != null);
2093-
type = inferrer.types.narrowType(type, staticType, isNullable: isNullable);
2108+
type = inferrer.types
2109+
.narrowType(type, staticType, isCast: isCast, excludeNull: excludeNull);
20942110

20952111
FieldEntity field = capturedAndBoxed[local];
20962112
if (field != null) {
@@ -2100,17 +2116,6 @@ class LocalState {
21002116
}
21012117
}
21022118

2103-
void narrowLocal(
2104-
InferrerEngine inferrer,
2105-
Map<Local, FieldEntity> capturedAndBoxed,
2106-
Local local,
2107-
DartType type,
2108-
ir.Node node) {
2109-
TypeInformation currentType = readLocal(inferrer, capturedAndBoxed, local);
2110-
updateLocal(inferrer, capturedAndBoxed, local, currentType, node, type,
2111-
isNullable: false);
2112-
}
2113-
21142119
LocalState mergeFlow(InferrerEngine inferrer, LocalState other) {
21152120
seenReturnOrThrow = false;
21162121
seenBreakOrContinue = false;

0 commit comments

Comments
 (0)