Skip to content

Commit e51f9de

Browse files
author
John Messerly
committed
fixes #616, statics on callable functions
also fixes `this` for them [email protected] Review URL: https://codereview.chromium.org/2200913002 .
1 parent 344124e commit e51f9de

20 files changed

+106
-69
lines changed

pkg/dev_compiler/lib/runtime/dart_sdk.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
949949
dart.callableClass = function(callableCtor, classExpr) {
950950
callableCtor.prototype = classExpr.prototype;
951951
callableCtor.prototype.constructor = callableCtor;
952-
callableCtor.__proto__ = classExpr.__proto__;
952+
callableCtor.__proto__ = classExpr;
953953
return callableCtor;
954954
};
955955
dart.defineNamedConstructorCallable = function(clazz, name, ctor) {

pkg/dev_compiler/lib/src/compiler/code_generator.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -808,9 +808,8 @@ class CodeGenerator extends GeneralizingAstVisitor
808808
JS.Fun _emitCallableClassConstructor(ConstructorElement ctor) {
809809
return js.call(
810810
r'''function (...args) {
811-
const self = this;
812811
function call(...args) {
813-
return self.call.apply(self, args);
812+
return call.call.apply(call, args);
814813
}
815814
call.__proto__ = this.__proto__;
816815
call.#.apply(call, args);
@@ -1416,7 +1415,7 @@ class CodeGenerator extends GeneralizingAstVisitor
14161415

14171416
var args = new JS.TemporaryId('args');
14181417
var fnArgs = <JS.Parameter>[];
1419-
JS.Expression positionalArgs;;
1418+
JS.Expression positionalArgs;
14201419

14211420
if (method.type.namedParameterTypes.isNotEmpty) {
14221421
addProperty(
@@ -1442,8 +1441,8 @@ class CodeGenerator extends GeneralizingAstVisitor
14421441
}
14431442
}
14441443

1445-
var fnBody = js.call(
1446-
'this.noSuchMethod(new dart.InvocationImpl(#, #, #))', [
1444+
var fnBody =
1445+
js.call('this.noSuchMethod(new dart.InvocationImpl(#, #, #))', [
14471446
_elementMemberName(method),
14481447
positionalArgs,
14491448
new JS.ObjectInitializer(invocationProps)

pkg/dev_compiler/test/codegen/language/callable_test.dart

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:expect/expect.dart';
6+
57
class X {
68
call() => 42;
79
}
810

911
class Y {
10-
call(int x) => 87;
12+
call(int x) => 87 + x;
13+
14+
static int staticMethod(int x) => x + 1;
15+
}
16+
17+
class Z<T> {
18+
final T value;
19+
Z(this.value);
20+
call() => value;
21+
22+
static int staticMethod(int x) => x + 1;
1123
}
1224

1325
typedef F(int x);
@@ -21,5 +33,15 @@ main() {
2133
F f0 = y; // Should pass checked mode test
2234
F f1 = x; /// 00: dynamic type error, static type warning
2335
G g0 = y; /// 01: dynamic type error, static type warning
24-
}
2536
37+
Expect.equals(f(), 42);
38+
Expect.equals(g(100), 187);
39+
40+
var z = new Z<int>(123);
41+
Expect.equals(z(), 123);
42+
// TODO(jmesserly): this test doesn't work yet.
43+
// Expect.equals((z as dynamic)(), 123);
44+
45+
Expect.equals(Y.staticMethod(6), 7);
46+
Expect.equals(Z.staticMethod(6), 7);
47+
}

pkg/dev_compiler/test/codegen_expected/corelib/apply3_test.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ dart_library.library('corelib/apply3_test', null, /* Imports */[
1414
let MapOfSymbol$dynamic = () => (MapOfSymbol$dynamic = dart.constFn(core.Map$(core.Symbol, dart.dynamic)))();
1515
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1616
apply3_test.F = dart.callableClass(function F(...args) {
17-
const self = this;
1817
function call(...args) {
19-
return self.call.apply(self, args);
18+
return call.call.apply(call, args);
2019
}
2120
call.__proto__ = this.__proto__;
2221
call.new.apply(call, args);
@@ -34,9 +33,8 @@ dart_library.library('corelib/apply3_test', null, /* Imports */[
3433
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [], [dart.dynamic])})
3534
});
3635
apply3_test.G = dart.callableClass(function G(...args) {
37-
const self = this;
3836
function call(...args) {
39-
return self.call.apply(self, args);
37+
return call.call.apply(call, args);
4038
}
4139
call.__proto__ = this.__proto__;
4240
call.new.apply(call, args);
@@ -53,9 +51,8 @@ dart_library.library('corelib/apply3_test', null, /* Imports */[
5351
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [])})
5452
});
5553
apply3_test.H = dart.callableClass(function H(...args) {
56-
const self = this;
5754
function call(...args) {
58-
return self.call.apply(self, args);
55+
return call.call.apply(call, args);
5956
}
6057
call.__proto__ = this.__proto__;
6158
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/corelib/apply_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ dart_library.library('corelib/apply_test', null, /* Imports */[
6565
methods: () => ({foo: dart.definiteFunctionType(core.int, [dart.dynamic])})
6666
});
6767
apply_test.Callable = dart.callableClass(function Callable(...args) {
68-
const self = this;
6968
function call(...args) {
70-
return self.call.apply(self, args);
69+
return call.call.apply(call, args);
7170
}
7271
call.__proto__ = this.__proto__;
7372
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/call_argument_inference_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ dart_library.library('language/call_argument_inference_test', null, /* Imports *
1010
const call_argument_inference_test = Object.create(null);
1111
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1212
call_argument_inference_test.A = dart.callableClass(function A(...args) {
13-
const self = this;
1413
function call(...args) {
15-
return self.call.apply(self, args);
14+
return call.call.apply(call, args);
1615
}
1716
call.__proto__ = this.__proto__;
1817
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/call_function_apply_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ dart_library.library('language/call_function_apply_test', null, /* Imports */[
1010
const call_function_apply_test = Object.create(null);
1111
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1212
call_function_apply_test.A = dart.callableClass(function A(...args) {
13-
const self = this;
1413
function call(...args) {
15-
return self.call.apply(self, args);
14+
return call.call.apply(call, args);
1615
}
1716
call.__proto__ = this.__proto__;
1817
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/call_operator_test.js

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ dart_library.library('language/call_operator_test', null, /* Imports */[
1010
const call_operator_test = Object.create(null);
1111
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1212
call_operator_test.A1 = dart.callableClass(function A1(...args) {
13-
const self = this;
1413
function call(...args) {
15-
return self.call.apply(self, args);
14+
return call.call.apply(call, args);
1615
}
1716
call.__proto__ = this.__proto__;
1817
call.new.apply(call, args);
@@ -26,9 +25,8 @@ dart_library.library('language/call_operator_test', null, /* Imports */[
2625
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [])})
2726
});
2827
call_operator_test.A2 = dart.callableClass(function A2(...args) {
29-
const self = this;
3028
function call(...args) {
31-
return self.call.apply(self, args);
29+
return call.call.apply(call, args);
3230
}
3331
call.__proto__ = this.__proto__;
3432
call.new.apply(call, args);
@@ -42,9 +40,8 @@ dart_library.library('language/call_operator_test', null, /* Imports */[
4240
methods: () => ({call: dart.definiteFunctionType(core.int, [])})
4341
});
4442
call_operator_test.B = dart.callableClass(function B(...args) {
45-
const self = this;
4643
function call(...args) {
47-
return self.call.apply(self, args);
44+
return call.call.apply(call, args);
4845
}
4946
call.__proto__ = this.__proto__;
5047
call.new.apply(call, args);
@@ -58,9 +55,8 @@ dart_library.library('language/call_operator_test', null, /* Imports */[
5855
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [])})
5956
});
6057
call_operator_test.C = dart.callableClass(function C(...args) {
61-
const self = this;
6258
function call(...args) {
63-
return self.call.apply(self, args);
59+
return call.call.apply(call, args);
6460
}
6561
call.__proto__ = this.__proto__;
6662
call.new.apply(call, args);
@@ -74,9 +70,8 @@ dart_library.library('language/call_operator_test', null, /* Imports */[
7470
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [dart.dynamic])})
7571
});
7672
call_operator_test.D = dart.callableClass(function D(...args) {
77-
const self = this;
7873
function call(...args) {
79-
return self.call.apply(self, args);
74+
return call.call.apply(call, args);
8075
}
8176
call.__proto__ = this.__proto__;
8277
call.new.apply(call, args);
@@ -91,9 +86,8 @@ dart_library.library('language/call_operator_test', null, /* Imports */[
9186
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [], [dart.dynamic])})
9287
});
9388
call_operator_test.E = dart.callableClass(function E(...args) {
94-
const self = this;
9589
function call(...args) {
96-
return self.call.apply(self, args);
90+
return call.call.apply(call, args);
9791
}
9892
call.__proto__ = this.__proto__;
9993
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/call_this_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ dart_library.library('language/call_this_test', null, /* Imports */[
1010
const call_this_test = Object.create(null);
1111
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1212
call_this_test.A = dart.callableClass(function A(...args) {
13-
const self = this;
1413
function call(...args) {
15-
return self.call.apply(self, args);
14+
return call.call.apply(call, args);
1615
}
1716
call.__proto__ = this.__proto__;
1817
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/call_with_no_such_method_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ dart_library.library('language/call_with_no_such_method_test', null, /* Imports
1313
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1414
let const$;
1515
call_with_no_such_method_test.F = dart.callableClass(function F(...args) {
16-
const self = this;
1716
function call(...args) {
18-
return self.call.apply(self, args);
17+
return call.call.apply(call, args);
1918
}
2019
call.__proto__ = this.__proto__;
2120
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/callable_test_none_multi.js

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
dart_library.library('language/callable_test_none_multi', null, /* Imports */[
2-
'dart_sdk'
3-
], function load__callable_test_none_multi(exports, dart_sdk) {
2+
'dart_sdk',
3+
'expect'
4+
], function load__callable_test_none_multi(exports, dart_sdk, expect) {
45
'use strict';
56
const core = dart_sdk.core;
67
const dart = dart_sdk.dart;
78
const dartx = dart_sdk.dartx;
9+
const expect$ = expect.expect;
810
const callable_test_none_multi = Object.create(null);
11+
let Z = () => (Z = dart.constFn(callable_test_none_multi.Z$()))();
12+
let ZOfint = () => (ZOfint = dart.constFn(callable_test_none_multi.Z$(core.int)))();
913
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1014
callable_test_none_multi.X = dart.callableClass(function X(...args) {
11-
const self = this;
1215
function call(...args) {
13-
return self.call.apply(self, args);
16+
return call.call.apply(call, args);
1417
}
1518
call.__proto__ = this.__proto__;
1619
call.new.apply(call, args);
@@ -24,21 +27,54 @@ dart_library.library('language/callable_test_none_multi', null, /* Imports */[
2427
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [])})
2528
});
2629
callable_test_none_multi.Y = dart.callableClass(function Y(...args) {
27-
const self = this;
2830
function call(...args) {
29-
return self.call.apply(self, args);
31+
return call.call.apply(call, args);
3032
}
3133
call.__proto__ = this.__proto__;
3234
call.new.apply(call, args);
3335
return call;
3436
}, class Y extends core.Object {
3537
call(x) {
36-
return 87;
38+
return 87 + dart.notNull(x);
39+
}
40+
static staticMethod(x) {
41+
return dart.notNull(x) + 1;
3742
}
3843
});
3944
dart.setSignature(callable_test_none_multi.Y, {
40-
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [core.int])})
45+
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [core.int])}),
46+
statics: () => ({staticMethod: dart.definiteFunctionType(core.int, [core.int])}),
47+
names: ['staticMethod']
48+
});
49+
callable_test_none_multi.Z$ = dart.generic(T => {
50+
const Z = dart.callableClass(function Z(...args) {
51+
function call(...args) {
52+
return call.call.apply(call, args);
53+
}
54+
call.__proto__ = this.__proto__;
55+
call.new.apply(call, args);
56+
return call;
57+
}, class Z extends core.Object {
58+
new(value) {
59+
this.value = value;
60+
}
61+
call() {
62+
return this.value;
63+
}
64+
static staticMethod(x) {
65+
return dart.notNull(x) + 1;
66+
}
67+
});
68+
dart.addTypeTests(Z);
69+
dart.setSignature(Z, {
70+
constructors: () => ({new: dart.definiteFunctionType(callable_test_none_multi.Z$(T), [T])}),
71+
methods: () => ({call: dart.definiteFunctionType(dart.dynamic, [])}),
72+
statics: () => ({staticMethod: dart.definiteFunctionType(core.int, [core.int])}),
73+
names: ['staticMethod']
74+
});
75+
return Z;
4176
});
77+
callable_test_none_multi.Z = Z();
4278
callable_test_none_multi.F = dart.typedef('F', () => dart.functionType(dart.dynamic, [core.int]));
4379
callable_test_none_multi.G = dart.typedef('G', () => dart.functionType(dart.dynamic, [core.String]));
4480
callable_test_none_multi.main = function() {
@@ -47,6 +83,12 @@ dart_library.library('language/callable_test_none_multi', null, /* Imports */[
4783
let y = new callable_test_none_multi.Y();
4884
let g = y;
4985
let f0 = y;
86+
expect$.Expect.equals(dart.dcall(f), 42);
87+
expect$.Expect.equals(dart.dcall(g, 100), 187);
88+
let z = new (ZOfint())(123);
89+
expect$.Expect.equals(z(), 123);
90+
expect$.Expect.equals(callable_test_none_multi.Y.staticMethod(6), 7);
91+
expect$.Expect.equals(callable_test_none_multi.Z.staticMethod(6), 7);
5092
};
5193
dart.fn(callable_test_none_multi.main, VoidTodynamic());
5294
// Exports:

pkg/dev_compiler/test/codegen_expected/language/cascade2_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ dart_library.library('language/cascade2_test', null, /* Imports */[
1212
let dynamicTobool = () => (dynamicTobool = dart.constFn(dart.definiteFunctionType(core.bool, [dart.dynamic])))();
1313
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1414
cascade2_test.A = dart.callableClass(function A(...args) {
15-
const self = this;
1615
function call(...args) {
17-
return self.call.apply(self, args);
16+
return call.call.apply(call, args);
1817
}
1918
call.__proto__ = this.__proto__;
2019
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/function_propagation_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ dart_library.library('language/function_propagation_test', null, /* Imports */[
1010
const function_propagation_test = Object.create(null);
1111
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1212
function_propagation_test.A = dart.callableClass(function A(...args) {
13-
const self = this;
1413
function call(...args) {
15-
return self.call.apply(self, args);
14+
return call.call.apply(call, args);
1615
}
1716
call.__proto__ = this.__proto__;
1817
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/function_subtype3_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ dart_library.library('language/function_subtype3_test', null, /* Imports */[
1717
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
1818
function_subtype3_test.FunctionLike$ = dart.generic(T => {
1919
const FunctionLike = dart.callableClass(function FunctionLike(...args) {
20-
const self = this;
2120
function call(...args) {
22-
return self.call.apply(self, args);
21+
return call.call.apply(call, args);
2322
}
2423
call.__proto__ = this.__proto__;
2524
call.new.apply(call, args);

pkg/dev_compiler/test/codegen_expected/language/function_subtype_call0_test.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ dart_library.library('language/function_subtype_call0_test', null, /* Imports */
1414
function_subtype_call0_test.Baz = dart.typedef('Baz', () => dart.functionType(dart.void, [core.bool], {b: core.String}));
1515
function_subtype_call0_test.Boz = dart.typedef('Boz', () => dart.functionType(dart.void, [core.bool]));
1616
function_subtype_call0_test.C1 = dart.callableClass(function C1(...args) {
17-
const self = this;
1817
function call(...args) {
19-
return self.call.apply(self, args);
18+
return call.call.apply(call, args);
2019
}
2120
call.__proto__ = this.__proto__;
2221
call.new.apply(call, args);
@@ -30,9 +29,8 @@ dart_library.library('language/function_subtype_call0_test', null, /* Imports */
3029
methods: () => ({call: dart.definiteFunctionType(dart.void, [core.bool], [core.String])})
3130
});
3231
function_subtype_call0_test.C2 = dart.callableClass(function C2(...args) {
33-
const self = this;
3432
function call(...args) {
35-
return self.call.apply(self, args);
33+
return call.call.apply(call, args);
3634
}
3735
call.__proto__ = this.__proto__;
3836
call.new.apply(call, args);
@@ -46,9 +44,8 @@ dart_library.library('language/function_subtype_call0_test', null, /* Imports */
4644
methods: () => ({call: dart.definiteFunctionType(dart.void, [core.bool], {b: core.String})})
4745
});
4846
function_subtype_call0_test.C3 = dart.callableClass(function C3(...args) {
49-
const self = this;
5047
function call(...args) {
51-
return self.call.apply(self, args);
48+
return call.call.apply(call, args);
5249
}
5350
call.__proto__ = this.__proto__;
5451
call.new.apply(call, args);

0 commit comments

Comments
 (0)