| Index: pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| index b8a4d6df8e22ed6d961cd8643d50b7ef24bde945..4f0adbee48fd1120aa0af77de7e8cb928d2f36b1 100644
|
| --- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| +++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| @@ -118,6 +118,8 @@ class CodeGenerator extends Object
|
| new HashMap<ParameterElement, JS.TemporaryId>();
|
|
|
| JS.Identifier _extensionSymbolsModule;
|
| + final _extensionSymbols = new Map<String, JS.TemporaryId>();
|
| +
|
| JS.Identifier _runtimeModule;
|
| final namedArgumentTemp = new JS.TemporaryId('opts');
|
|
|
| @@ -318,6 +320,7 @@ class CodeGenerator extends Object
|
|
|
| // Initialize our library variables.
|
| var items = <JS.ModuleItem>[];
|
| + var isBuildingSdk = false;
|
| for (var unit in compilationUnits) {
|
| var library =
|
| resolutionMap.elementDeclaredByCompilationUnit(unit).library;
|
| @@ -333,6 +336,7 @@ class CodeGenerator extends Object
|
| // dart:_runtime has a magic module that holds extension method symbols.
|
| // TODO(jmesserly): find a cleaner design for this.
|
| if (isSdkInternalRuntime(library)) {
|
| + isBuildingSdk = true;
|
| items.add(new JS.ExportDeclaration(js
|
| .call('const # = Object.create(null)', [_extensionSymbolsModule])));
|
| }
|
| @@ -372,6 +376,15 @@ class CodeGenerator extends Object
|
|
|
| // Declare imports
|
| _finishImports(items);
|
| + // Initialize extension symbols
|
| + _extensionSymbols.forEach((name, id) {
|
| + var value =
|
| + new JS.PropertyAccess(_extensionSymbolsModule, _propertyName(name));
|
| + if (isBuildingSdk) {
|
| + value = js.call('# = Symbol(#)', [value, js.string("dartx.$name")]);
|
| + }
|
| + items.add(js.statement('const # = #;', [id, value]));
|
| + });
|
|
|
| // Discharge the type table cache variables and
|
| // hoisted definitions.
|
| @@ -933,7 +946,6 @@ class CodeGenerator extends Object
|
| fields: allFields);
|
|
|
| var body = <JS.Statement>[];
|
| - _initExtensionSymbols(classElem, methods, fields, body);
|
| _emitSuperHelperSymbols(body);
|
|
|
| // Emit the class, e.g. `core.Object = class Object { ... }`
|
| @@ -1178,10 +1190,15 @@ class CodeGenerator extends Object
|
| 'addTypeTests(#, #);', [defaultInst, isClassSymbol]);
|
| }
|
|
|
| - void _emitSuperHelperSymbols(List<JS.Statement> body) {
|
| - for (var id in _superHelpers.values.map((m) => m.name as JS.TemporaryId)) {
|
| + void _emitSymbols(Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
|
| + for (var id in vars) {
|
| body.add(js.statement('const # = Symbol(#)', [id, js.string(id.name)]));
|
| }
|
| + }
|
| +
|
| + void _emitSuperHelperSymbols(List<JS.Statement> body) {
|
| + _emitSymbols(
|
| + _superHelpers.values.map((m) => m.name as JS.TemporaryId), body);
|
| _superHelpers.clear();
|
| }
|
|
|
| @@ -2155,38 +2172,6 @@ class CodeGenerator extends Object
|
| }
|
| }
|
|
|
| - /// Ensure `dartx.` symbols we will use are present.
|
| - void _initExtensionSymbols(
|
| - ClassElement classElem,
|
| - List<MethodDeclaration> methods,
|
| - List<FieldDeclaration> fields,
|
| - List<JS.Statement> body) {
|
| - if (_extensionTypes.hasNativeSubtype(classElem.type)) {
|
| - var dartxNames = <JS.Expression>[];
|
| - for (var m in methods) {
|
| - if (!m.isAbstract &&
|
| - !m.isStatic &&
|
| - resolutionMap.elementDeclaredByMethodDeclaration(m).isPublic) {
|
| - dartxNames.add(_declareMemberName(m.element, useExtension: false));
|
| - }
|
| - }
|
| - for (var fieldDecl in fields) {
|
| - if (!fieldDecl.isStatic) {
|
| - for (var field in fieldDecl.fields.variables) {
|
| - var e = field.element as FieldElement;
|
| - if (e.isPublic) {
|
| - dartxNames.add(_declareMemberName(e.getter, useExtension: false));
|
| - }
|
| - }
|
| - }
|
| - }
|
| - if (dartxNames.isNotEmpty) {
|
| - body.add(_callHelperStatement('defineExtensionNames(#)',
|
| - [new JS.ArrayInitializer(dartxNames, multiline: true)]));
|
| - }
|
| - }
|
| - }
|
| -
|
| JS.Expression _emitConstructor(ConstructorDeclaration node,
|
| List<FieldDeclaration> fields, bool isCallable, JS.Expression className) {
|
| var params = _emitFormalParameterList(node.parameters);
|
| @@ -5654,13 +5639,11 @@ class CodeGenerator extends Object
|
| break;
|
| }
|
|
|
| - var result = _propertyName(name);
|
| -
|
| - useExtension ??= _isSymbolizedMember(type, name);
|
| -
|
| - return useExtension
|
| - ? js.call('#.#', [_extensionSymbolsModule, result])
|
| - : result;
|
| + if (useExtension ?? _isSymbolizedMember(type, name)) {
|
| + return _extensionSymbols.putIfAbsent(name,
|
| + () => new JS.TemporaryId('\$${_friendlyOperatorName[name] ?? name}'));
|
| + }
|
| + return _propertyName(name);
|
| }
|
|
|
| var _forwardingCache = new HashMap<Element, Map<String, ExecutableElement>>();
|
| @@ -6072,3 +6055,23 @@ bool _isDeferredLoadLibrary(Expression target, SimpleIdentifier name) {
|
|
|
| bool _annotatedNullCheck(Element e) =>
|
| e != null && findAnnotation(e, isNullCheckAnnotation) != null;
|
| +
|
| +final _friendlyOperatorName = {
|
| + '<': 'lessThan',
|
| + '>': 'greaterThan',
|
| + '<=': 'lessOrEquals',
|
| + '>=': 'greaterOrEquals',
|
| + '==': 'equals',
|
| + '-': 'minus',
|
| + '+': 'plus',
|
| + '/': 'divide',
|
| + '~/': 'floorDivide',
|
| + '*': 'times',
|
| + '%': 'modulo',
|
| + '|': 'bitOr',
|
| + '^': 'bitXor',
|
| + '&': 'bitAnd',
|
| + '<<': 'leftShift',
|
| + '>>': 'rightShift',
|
| + '~': 'bitNot'
|
| +};
|
|
|