Skip to content

Commit eb3c51e

Browse files
committed
Check default parameters properly
[email protected] Review URL: https://chromereviews.googleplex.com/155367013
1 parent b235789 commit eb3c51e

File tree

6 files changed

+46
-5
lines changed

6 files changed

+46
-5
lines changed

pkg/dev_compiler/lib/src/checker/checker.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,32 @@ class CodeChecker extends RecursiveAstVisitor {
504504
node.visitChildren(this);
505505
}
506506

507+
visitDefaultFormalParameter(DefaultFormalParameter node) {
508+
// Check that defaults have the proper subtype.
509+
var parameter = node.parameter;
510+
var parameterType = _rules.elementType(parameter.element);
511+
assert(parameterType != null);
512+
var defaultValue = node.defaultValue;
513+
var defaultType;
514+
if (defaultValue == null) {
515+
// TODO(vsm): Should this be null?
516+
defaultType = _rules.provider.bottomType;
517+
} else {
518+
defaultType = _rules.getStaticType(defaultValue);
519+
}
520+
521+
// If defaultType is bottom, this enforces that parameterType is not
522+
// non-nullable.
523+
if (!_rules.isSubTypeOf(defaultType, parameterType)) {
524+
var staticInfo = (defaultValue == null)
525+
? new InvalidVariableDeclaration(
526+
_rules, node.identifier, parameterType)
527+
: new StaticTypeError(_rules, defaultValue, parameterType);
528+
_recordMessage(staticInfo);
529+
}
530+
node.visitChildren(this);
531+
}
532+
507533
visitVariableDeclarationList(VariableDeclarationList node) {
508534
TypeName type = node.type;
509535
if (type == null) {

pkg/dev_compiler/lib/src/info.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ class InvalidVariableDeclaration extends StaticError {
361361
final DartType expectedType;
362362

363363
InvalidVariableDeclaration(
364-
TypeRules rules, VariableDeclaration declaration, this.expectedType)
364+
TypeRules rules, AstNode declaration, this.expectedType)
365365
: super(declaration);
366366

367367
String get message => 'Type check failed: null is not of type $expectedType';

pkg/dev_compiler/test/checker/checker_test.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ main() {
4646
static num z;
4747
}
4848
49+
void foo(int w, [int x = /*severe:StaticTypeError*/null, int /*severe:InvalidVariableDeclaration*/y, int z = 0]) {
50+
}
51+
52+
void bar(int w, {int x = /*severe:StaticTypeError*/null, int /*severe:InvalidVariableDeclaration*/y, int z: 0}) {
53+
}
54+
4955
void main() {
5056
int /*severe:InvalidVariableDeclaration*/x;
5157
double /*severe:InvalidVariableDeclaration*/y;
@@ -96,6 +102,9 @@ main() {
96102
// Transformed to: T z = cast(null, T)
97103
T /*severe:InvalidVariableDeclaration*/z;
98104
}
105+
106+
void baz(T x, [T /*severe:InvalidVariableDeclaration*/y, T z = /*severe:StaticTypeError*/null]) {
107+
}
99108
}
100109
101110
class B<T extends List> {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
// Messages from compiling methods.dart
2+
info: line 10, column 21 of test/codegen/methods.dart: b (num) will need runtime check to cast to type int
3+
int z([num b]) => b;
4+
^
5+
info: line 15, column 12 of test/codegen/methods.dart: a + b (num) will need runtime check to cast to type int
6+
return a + b;
7+
^^^^^
28
warning: line 45, column 3 of test/codegen/methods.dart: f.bar("Bar's call method!") requires dynamic invoke
39
f.bar("Bar's call method!");
410
^^^^^^^^^^^^^^^^^^^^^^^^^^^

pkg/dev_compiler/test/codegen/expect/methods/methods.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ var methods;
1212
}
1313
z(b) {
1414
if (b === undefined) b = null;
15-
return b
15+
return dart.notNull(b)
1616
}
1717
zz(b) {
1818
if (b === undefined) b = 0;
1919
return b
2020
}
2121
w(a, opt$) {
2222
let b = opt$.b === undefined ? null : opt$.b;
23-
return a + b;
23+
return dart.notNull(a + b);
2424
}
2525
ww(a, opt$) {
2626
let b = opt$.b === undefined ? 0 : opt$.b;

pkg/dev_compiler/test/codegen/methods.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ class A {
77
return a;
88
}
99

10-
int z([int b]) => b;
10+
int z([num b]) => b;
1111

1212
int zz([int b = 0]) => b;
1313

14-
int w(int a, {int b}) {
14+
int w(int a, {num b}) {
1515
return a + b;
1616
}
1717

0 commit comments

Comments
 (0)