diff --git a/pkg/dev_compiler/lib/runtime/dart/_interceptors.js b/pkg/dev_compiler/lib/runtime/dart/_interceptors.js index 615c98079d6b..278ba256eb7b 100644 --- a/pkg/dev_compiler/lib/runtime/dart/_interceptors.js +++ b/pkg/dev_compiler/lib/runtime/dart/_interceptors.js @@ -487,6 +487,50 @@ dart.library('dart/_interceptors', null, /* Imports */[ let _shrReceiverPositive = Symbol('_shrReceiverPositive'); let _shrOtherPositive = Symbol('_shrOtherPositive'); let _shrBothPositive = Symbol('_shrBothPositive'); + dart.defineExtensionNames([ + 'compareTo', + 'isNegative', + 'isNaN', + 'isInfinite', + 'isFinite', + 'remainder', + 'abs', + 'sign', + 'toInt', + 'truncate', + 'ceil', + 'floor', + 'round', + 'ceilToDouble', + 'floorToDouble', + 'roundToDouble', + 'truncateToDouble', + 'clamp', + 'toDouble', + 'toStringAsFixed', + 'toStringAsExponential', + 'toStringAsPrecision', + 'toRadixString', + 'toString', + 'hashCode', + 'unary-', + '+', + '-', + '/', + '*', + '%', + '~/', + '<<', + '>>', + '&', + '|', + '^', + '<', + '>', + '<=', + '>=', + 'runtimeType' + ]); class JSNumber extends Interceptor { JSNumber() { super.Interceptor(); @@ -928,6 +972,9 @@ dart.library('dart/_interceptors', null, /* Imports */[ }); JSInt[dart.metadata] = () => [dart.const(new _js_helper.JsPeerInterface({name: 'Number'}))]; dart.registerExtension(dart.global.Number, JSInt); + dart.defineExtensionNames([ + 'runtimeType' + ]); class JSDouble extends JSNumber { JSDouble() { super.JSNumber(); diff --git a/pkg/dev_compiler/lib/runtime/dart/core.js b/pkg/dev_compiler/lib/runtime/dart/core.js index daddf3297142..9893f751f5ff 100644 --- a/pkg/dev_compiler/lib/runtime/dart/core.js +++ b/pkg/dev_compiler/lib/runtime/dart/core.js @@ -68,6 +68,9 @@ dart.library('dart/core', null, /* Imports */[ constructors: () => ({_Proxy: [_Proxy, []]}) }); let proxy = dart.const(new _Proxy()); + dart.defineExtensionNames([ + 'toString' + ]); class bool extends Object { static fromEnvironment(name, opts) { let defaultValue = opts && 'defaultValue' in opts ? opts.defaultValue : false; @@ -1254,6 +1257,9 @@ dart.library('dart/core', null, /* Imports */[ } } let Iterable$ = dart.generic(function(E) { + dart.defineExtensionNames([ + 'join' + ]); class Iterable extends Object { Iterable() { } diff --git a/pkg/dev_compiler/lib/runtime/dart_runtime.js b/pkg/dev_compiler/lib/runtime/dart_runtime.js index 3cb2c617ca74..1b6125ee3682 100644 --- a/pkg/dev_compiler/lib/runtime/dart_runtime.js +++ b/pkg/dev_compiler/lib/runtime/dart_runtime.js @@ -799,7 +799,12 @@ var dart, dartx; // Mark the JS type's instances so we can easily check for extensions. assert(jsProto[_extensionType] === void 0); jsProto[_extensionType] = extProto; - copyPropertiesHelper(jsProto, extProto, getOwnPropertySymbols(extProto)); + + let dartObjProto = core.Object.prototype; + while (extProto !== dartObjProto && extProto !== jsProto) { + copyPropertiesHelper(jsProto, extProto, getOwnPropertySymbols(extProto)); + extProto = extProto.__proto__; + } } dart.registerExtension = registerExtension; diff --git a/pkg/dev_compiler/lib/src/codegen/js_codegen.dart b/pkg/dev_compiler/lib/src/codegen/js_codegen.dart index 99ece9c88e0c..a4f09d0a54d5 100644 --- a/pkg/dev_compiler/lib/src/codegen/js_codegen.dart +++ b/pkg/dev_compiler/lib/src/codegen/js_codegen.dart @@ -569,15 +569,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor { var name = classElem.name; var body = []; - if (jsPeerName != null) { + if (_extensionTypes.contains(classElem)) { var dartxNames = []; for (var m in methods) { if (!m.isAbstract && !m.isStatic && m.element.isPublic) { dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); } } - body.add(js.statement('dart.defineExtensionNames(#)', - [new JS.ArrayInitializer(dartxNames, multiline: true)])); + if (dartxNames.isNotEmpty) { + body.add(js.statement('dart.defineExtensionNames(#)', + [new JS.ArrayInitializer(dartxNames, multiline: true)])); + } } body.add(new JS.ClassDeclaration(cls)); diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_number.dart b/pkg/dev_compiler/tool/input_sdk/private/js_number.dart index 9d0b1b937310..ced02db358b9 100644 --- a/pkg/dev_compiler/tool/input_sdk/private/js_number.dart +++ b/pkg/dev_compiler/tool/input_sdk/private/js_number.dart @@ -343,6 +343,8 @@ class JSNumber extends Interceptor implements num { */ // TODO(jmesserly): for dev_compiler all numbers will get `int` members at // runtime for dynamic dispatch. We can fix by checking it at dispatch time. +// TODO(jmesserly): merge with JSNumber? That would simplify generated code, +// and dart_runtime's extension mechanism. @JsPeerInterface(name: 'Number') class JSInt extends JSNumber implements int, double { const JSInt();