Skip to content

Commit 50eb282

Browse files
committed
Infer parameter types on overrides
Fixes #105 This overlaps with brian's recent CL moving override inference logic. If this looks good, we'll need to move it over as well. [email protected], [email protected] Review URL: https://codereview.chromium.org/1311863005 .
1 parent c38d2e8 commit 50eb282

File tree

4 files changed

+49
-29
lines changed

4 files changed

+49
-29
lines changed

pkg/dev_compiler/lib/runtime/dart/js.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ dart_library.library('dart/js', null, /* Imports */[
201201
}
202202
}
203203
get(index) {
204-
if (dart.is(index, core.num) && dart.equals(index, dart.dsend(index, 'toInt'))) {
205-
this[_checkIndex](dart.as(index, core.int));
204+
if (dart.is(index, core.num) && index == index[dartx.toInt]()) {
205+
this[_checkIndex](index);
206206
}
207207
return dart.as(super.get(index), E);
208208
}
209209
set(index, value) {
210210
dart.as(value, E);
211-
if (dart.is(index, core.num) && dart.equals(index, dart.dsend(index, 'toInt'))) {
212-
this[_checkIndex](dart.as(index, core.int));
211+
if (dart.is(index, core.num) && index == index[dartx.toInt]()) {
212+
this[_checkIndex](index);
213213
}
214214
super.set(index, value);
215215
}
@@ -282,8 +282,8 @@ dart_library.library('dart/js', null, /* Imports */[
282282
methods: () => ({
283283
[_checkIndex]: [dart.dynamic, [core.int]],
284284
[_checkInsertIndex]: [dart.dynamic, [core.int]],
285-
get: [E, [dart.dynamic]],
286-
set: [dart.void, [dart.dynamic, E]],
285+
get: [E, [core.int]],
286+
set: [dart.void, [core.int, E]],
287287
add: [dart.void, [E]],
288288
addAll: [dart.void, [core.Iterable$(E)]],
289289
insert: [dart.void, [core.int, E]],

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

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ class LibraryResolverWithInference extends LibraryResolver {
168168
.forEach((f) => _inferFieldTypeFromOverride(f, pending));
169169
if (pending.isNotEmpty) _inferVariableFromInitializer(pending);
170170

171-
// Infer return-types from overrides
171+
// Infer return-types and param-types from overrides
172172
cls.members
173173
.where((m) => m is MethodDeclaration && !m.isStatic)
174-
.forEach(_inferMethodReturnTypeFromOverride);
174+
.forEach(_inferMethodTypesFromOverride);
175175
} else {
176176
_inferVariableFromInitializer(cls.members
177177
.where(_isInstanceField)
@@ -231,18 +231,38 @@ class LibraryResolverWithInference extends LibraryResolver {
231231
}
232232
}
233233

234-
void _inferMethodReturnTypeFromOverride(MethodDeclaration method) {
234+
void _inferMethodTypesFromOverride(MethodDeclaration method) {
235235
var methodElement = method.element;
236-
if ((methodElement is MethodElement ||
237-
methodElement is PropertyAccessorElement) &&
238-
methodElement.returnType.isDynamic &&
239-
method.returnType == null) {
240-
var enclosingElement = methodElement.enclosingElement as ClassElement;
241-
var type = searchTypeFor(enclosingElement.type, methodElement);
242-
if (type != null && !type.returnType.isDynamic) {
236+
if (methodElement is! MethodElement &&
237+
methodElement is! PropertyAccessorElement) return;
238+
239+
var enclosingElement = methodElement.enclosingElement as ClassElement;
240+
FunctionType type = null;
241+
242+
// Infer the return type if omitted
243+
if (methodElement.returnType.isDynamic && method.returnType == null) {
244+
type = searchTypeFor(enclosingElement.type, methodElement);
245+
if (type == null) return;
246+
if (!type.returnType.isDynamic) {
243247
methodElement.returnType = type.returnType;
244248
}
245249
}
250+
251+
// Infer parameter types if omitted
252+
if (method.parameters == null) return;
253+
var parameters = method.parameters.parameters;
254+
var length = parameters.length;
255+
for (int i = 0; i < length; ++i) {
256+
var parameter = parameters[i];
257+
if (parameter is DefaultFormalParameter) parameter = parameter.parameter;
258+
if (parameter is SimpleFormalParameter && parameter.type == null) {
259+
type = type ?? searchTypeFor(enclosingElement.type, methodElement);
260+
if (type == null) return;
261+
if (type.parameters.length > i && !type.parameters[i].type.isDynamic) {
262+
parameter.element.type = type.parameters[i].type;
263+
}
264+
}
265+
}
246266
}
247267

248268
void _inferVariableFromInitializer(Iterable<VariableDeclaration> variables) {

pkg/dev_compiler/test/checker/checker_test.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ void main() {
14881488
class Child extends Base {
14891489
void set f1(A value) {}
14901490
/*severe:InvalidMethodOverride*/void set f2(C value) {}
1491-
/*severe:InvalidMethodOverride*/void set f3(value) {}
1491+
void set f3(value) {}
14921492
/*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
14931493
set f5(B value) {}
14941494
}
@@ -1518,7 +1518,7 @@ void main() {
15181518
15191519
void set f1(A value) {}
15201520
/*severe:InvalidMethodOverride*/void set f2(C value) {}
1521-
/*severe:InvalidMethodOverride*/void set f3(value) {}
1521+
void set f3(value) {}
15221522
/*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
15231523
set f5(B value) {}
15241524
}
@@ -1547,7 +1547,7 @@ void main() {
15471547
/*severe:InvalidMethodOverride*/C m2(C value) {}
15481548
/*severe:InvalidMethodOverride*/A m3(C value) {}
15491549
C m4(A value) {}
1550-
/*severe:InvalidMethodOverride*/m5(value) {}
1550+
m5(value) {}
15511551
/*severe:InvalidMethodOverride*/dynamic m6(dynamic value) {}
15521552
}
15531553
'''
@@ -2025,14 +2025,14 @@ void main() {
20252025
implements I1 {}
20262026
20272027
class T2 extends Base implements I1 {
2028-
/*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a) {}
2028+
/*severe:InvalidMethodOverride*/m(a) {}
20292029
}
20302030
20312031
class T3 extends Object with /*severe:InvalidMethodOverride*/Base
20322032
implements I1 {}
20332033
20342034
class T4 extends Object with Base implements I1 {
2035-
/*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a) {}
2035+
/*severe:InvalidMethodOverride*/m(a) {}
20362036
}
20372037
'''
20382038
});

pkg/dev_compiler/tool/sdk_expected_errors.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@ severe: [AnalyzerMessage] Classes cannot implement 'num' (dart:_interceptors/js_
33
severe: [AnalyzerMessage] The return type 'JSNumber' is not a 'double', as defined by the method 'toDouble' (dart:_interceptors/js_number.dart, line 110, col 17)
44
severe: [StaticTypeError] Type check failed: this (JSNumber) is not of type double (dart:_interceptors/js_number.dart, line 110, col 17)
55
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.sign (() → num) is not a subtype of int.sign (() → int). (dart:_interceptors/js_number.dart, line 349, col 13)
6-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.>> ((num) → num) is not a subtype of int.>> ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
6+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.& ((num) → num) is not a subtype of int.& ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
77
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.abs (() → num) is not a subtype of int.abs (() → int). (dart:_interceptors/js_number.dart, line 349, col 13)
88
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.unary- (() → num) is not a subtype of int.unary- (() → int). (dart:_interceptors/js_number.dart, line 349, col 13)
99
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.<< ((num) → num) is not a subtype of int.<< ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
10-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.& ((num) → num) is not a subtype of int.& ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
10+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.>> ((num) → num) is not a subtype of int.>> ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
1111
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.| ((num) → num) is not a subtype of int.| ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
1212
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.^ ((num) → num) is not a subtype of int.^ ((int) → int). (dart:_interceptors/js_number.dart, line 349, col 13)
1313
severe: [AnalyzerMessage] Classes cannot implement 'int' (dart:_interceptors/js_number.dart, line 349, col 41)
1414
severe: [AnalyzerMessage] Classes cannot implement 'double' (dart:_interceptors/js_number.dart, line 349, col 46)
15-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.sign (() → num) is not a subtype of double.sign (() → double). (dart:_interceptors/js_number.dart, line 420, col 16)
16-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.% ((num) → num) is not a subtype of double.% ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
17-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.* ((num) → num) is not a subtype of double.* ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
18-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.- ((num) → num) is not a subtype of double.- ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
19-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.+ ((num) → num) is not a subtype of double.+ ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
2015
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.unary- (() → num) is not a subtype of double.unary- (() → double). (dart:_interceptors/js_number.dart, line 420, col 16)
21-
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.abs (() → num) is not a subtype of double.abs (() → double). (dart:_interceptors/js_number.dart, line 420, col 16)
16+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.sign (() → num) is not a subtype of double.sign (() → double). (dart:_interceptors/js_number.dart, line 420, col 16)
2217
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.remainder ((num) → num) is not a subtype of double.remainder ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
18+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.abs (() → num) is not a subtype of double.abs (() → double). (dart:_interceptors/js_number.dart, line 420, col 16)
19+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.+ ((num) → num) is not a subtype of double.+ ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
20+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.- ((num) → num) is not a subtype of double.- ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
21+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.* ((num) → num) is not a subtype of double.* ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
22+
severe: [InvalidMethodOverride] Base class introduces an invalid override. The type of JSNumber.% ((num) → num) is not a subtype of double.% ((num) → double). (dart:_interceptors/js_number.dart, line 420, col 16)
2323
severe: [AnalyzerMessage] Classes cannot implement 'double' (dart:_interceptors/js_number.dart, line 420, col 44)
2424
severe: [AnalyzerMessage] Classes cannot implement 'String' (dart:_interceptors/js_string.dart, line 14, col 47)
2525
severe: [StaticTypeError] Type check failed: s += s (String) is not of type JSString (dart:_interceptors/js_string.dart, line 346, col 7)

0 commit comments

Comments
 (0)