| Index: pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| index bd9e1616069a7a453f4fd281231d1beae21800e9..5ebb9ee23b2481519cc429e35d9206f51bf79d8c 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| @@ -613,7 +613,8 @@ class FragmentEmitter {
|
| }
|
|
|
| allMethods.forEach((Method method) {
|
| - emitInstanceMethod(method).forEach((js.Name name, js.Expression code) {
|
| + emitInstanceMethod(method)
|
| + .forEach((js.Expression name, js.Expression code) {
|
| properties.add(new js.Property(name, code));
|
| });
|
| });
|
| @@ -679,17 +680,30 @@ class FragmentEmitter {
|
| ///
|
| /// If it is a Dart-method, all necessary stub-methods are emitted, too. In
|
| /// that case the returned map contains more than just one entry.
|
| - Map<js.Name, js.Expression> emitInstanceMethod(Method method) {
|
| - Map<js.Name, js.Expression> jsMethods = <js.Name, js.Expression>{};
|
| + ///
|
| + /// If the method is a closure call-method, also returns the necessary
|
| + /// properties in case the closure can be applied.
|
| + Map<js.Expression, js.Expression> emitInstanceMethod(Method method) {
|
| + var properties = <js.Expression, js.Expression>{};
|
|
|
| - jsMethods[method.name] = method.code;
|
| + properties[method.name] = method.code;
|
| if (method is InstanceMethod) {
|
| for (ParameterStubMethod stubMethod in method.parameterStubs) {
|
| - jsMethods[stubMethod.name] = stubMethod.code;
|
| + properties[stubMethod.name] = stubMethod.code;
|
| + }
|
| +
|
| + if (method.isClosureCallMethod && method.canBeApplied) {
|
| + properties[js.string(namer.callCatchAllName)] =
|
| + js.quoteName(method.name);
|
| + properties[js.string(namer.requiredParameterField)] =
|
| + js.number(method.requiredParameterCount);
|
| + properties[js.string(namer.defaultValuesField)] =
|
| + js.js('function() { return #; }',
|
| + _encodeOptionalParameterDefaultValues(method));
|
| }
|
| }
|
|
|
| - return jsMethods;
|
| + return properties;
|
| }
|
|
|
| /// Emits the inheritance block of the fragment.
|
| @@ -759,10 +773,16 @@ class FragmentEmitter {
|
| Map<String, ConstantValue> defaultValues =
|
| method.optionalParameterDefaultValues;
|
| List<js.Property> properties = <js.Property>[];
|
| - defaultValues.forEach((String name, ConstantValue value) {
|
| + List<String> names = defaultValues.keys.toList(growable: false);
|
| + // Sort the names the same way we sort them for the named-argument calling
|
| + // convention.
|
| + names.sort();
|
| +
|
| + for (String name in names) {
|
| + ConstantValue value = defaultValues[name];
|
| properties.add(new js.Property(js.string(name),
|
| generateConstantReference(value)));
|
| - });
|
| + }
|
| return new js.ObjectInitializer(properties);
|
| }
|
| }
|
| @@ -816,7 +836,7 @@ class FragmentEmitter {
|
| _encodeOptionalParameterDefaultValues(method);
|
| }
|
|
|
| -// TODO(floitsch): this can be more efficient.
|
| + // TODO(floitsch): this can be more efficient.
|
| return js.js.statement('''
|
| installTearOff(#container, #getterName, #isStatic, #isIntercepted,
|
| #requiredParameterCount, #optionalParameterDefaultValues,
|
|
|