| 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 6ea4fe5ffa071adb6f53e2d1c832314c184e7ed5..87e40891865b5c2338bf1d20169932f3586e09cc 100644
|
| --- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| +++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| @@ -1167,8 +1167,19 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| var classExpr = new JS.ClassExpression(new JS.Identifier(type.name),
|
| _emitClassHeritage(element), [constructor, toStringF]);
|
| var id = _emitTopLevelName(element);
|
| +
|
| + // Emit metadata for synthetic enum index member.
|
| + // TODO(jacobr): make field readonly when that is supported.
|
| + var tInstanceFields = <JS.Property>[
|
| + new JS.Property(
|
| + _emitMemberName('index'), _emitAnnotatedType(intClass.type, null))
|
| + ];
|
| + var sigFields = <JS.Property>[_buildSignatureField('fields', tInstanceFields)];
|
| + var sig = new JS.ObjectInitializer(sigFields);
|
| +
|
| var result = [
|
| - js.statement('# = #', [id, classExpr])
|
| + js.statement('# = #', [id, classExpr]),
|
| + _callHelperStatement('setSignature(#, #);', [id, sig])
|
| ];
|
|
|
| // defineEnumValues internally depends on dart.constList which uses
|
| @@ -1507,7 +1518,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
|
|
| var fnBody = js.call('this.noSuchMethod(new #.InvocationImpl(#, #, #))', [
|
| _runtimeModule,
|
| - _declareMemberName(method),
|
| + _declareMemberName(method, useDisplayName: true),
|
| positionalArgs,
|
| new JS.ObjectInitializer(invocationProps)
|
| ]);
|
| @@ -1772,6 +1783,14 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
| }
|
|
|
| + JS.Property _buildSignatureField(String name, List<JS.Property> elements) {
|
| + var o =
|
| + new JS.ObjectInitializer(elements, multiline: elements.length > 1);
|
| + // TODO(vsm): Remove
|
| + var e = js.call('() => #', o);
|
| + return new JS.Property(_propertyName(name), e);
|
| + }
|
| +
|
| /// Emit the signature on the class recording the runtime type information
|
| void _emitClassSignature(
|
| List<MethodDeclaration> methods,
|
| @@ -1883,45 +1902,37 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| tCtors.add(property);
|
| }
|
|
|
| - JS.Property build(String name, List<JS.Property> elements) {
|
| - var o =
|
| - new JS.ObjectInitializer(elements, multiline: elements.length > 1);
|
| - // TODO(vsm): Remove
|
| - var e = js.call('() => #', o);
|
| - return new JS.Property(_propertyName(name), e);
|
| - }
|
| -
|
| var sigFields = <JS.Property>[];
|
| if (!tCtors.isEmpty) {
|
| - sigFields.add(build('constructors', tCtors));
|
| + sigFields.add(_buildSignatureField('constructors', tCtors));
|
| }
|
| if (!tInstanceFields.isEmpty) {
|
| - sigFields.add(build('fields', tInstanceFields));
|
| + sigFields.add(_buildSignatureField('fields', tInstanceFields));
|
| }
|
| if (!tInstanceGetters.isEmpty) {
|
| - sigFields.add(build('getters', tInstanceGetters));
|
| + sigFields.add(_buildSignatureField('getters', tInstanceGetters));
|
| }
|
| if (!tInstanceSetters.isEmpty) {
|
| - sigFields.add(build('setters', tInstanceSetters));
|
| + sigFields.add(_buildSignatureField('setters', tInstanceSetters));
|
| }
|
| if (!tInstanceMethods.isEmpty) {
|
| - sigFields.add(build('methods', tInstanceMethods));
|
| + sigFields.add(_buildSignatureField('methods', tInstanceMethods));
|
| }
|
| if (!tStaticFields.isEmpty) {
|
| - sigFields.add(build('sfields', tStaticFields));
|
| + sigFields.add(_buildSignatureField('sfields', tStaticFields));
|
| }
|
| if (!tStaticGetters.isEmpty) {
|
| - sigFields.add(build('sgetters', tStaticGetters));
|
| + sigFields.add(_buildSignatureField('sgetters', tStaticGetters));
|
| }
|
| if (!tStaticSetters.isEmpty) {
|
| - sigFields.add(build('ssetters', tStaticSetters));
|
| + sigFields.add(_buildSignatureField('ssetters', tStaticSetters));
|
| }
|
| if (!tStaticMethods.isEmpty) {
|
| assert(!sNames.isEmpty);
|
| // TODO(vsm): Why do we need this names field?
|
| var aNames = new JS.Property(
|
| _propertyName('names'), new JS.ArrayInitializer(sNames));
|
| - sigFields.add(build('statics', tStaticMethods));
|
| + sigFields.add(_buildSignatureField('statics', tStaticMethods));
|
| sigFields.add(aNames);
|
| }
|
| if (!sigFields.isEmpty || extensions.isNotEmpty) {
|
| @@ -1969,14 +1980,14 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
|
|
| List<ExecutableElement> _extensionsToImplement(ClassElement element) {
|
| - var members = <ExecutableElement>[];
|
| - if (_extensionTypes.isNativeClass(element)) return members;
|
| + if (_extensionTypes.isNativeClass(element)) return [];
|
|
|
| // Collect all extension types we implement.
|
| var type = element.type;
|
| var types = _extensionTypes.collectNativeInterfaces(element);
|
| - if (types.isEmpty) return members;
|
| + if (types.isEmpty) return [];
|
|
|
| + var members = new Set<ExecutableElement>();
|
| // Collect all possible extension method names.
|
| var extensionMembers = new HashSet<String>();
|
| for (var t in types) {
|
| @@ -1991,7 +2002,9 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| members.add(m);
|
| }
|
| }
|
| - return members;
|
| + members.addAll(_collectMockMethods(type)
|
| + .where((m) => extensionMembers.contains(m.name)));
|
| + return members.toList();
|
| }
|
|
|
| /// Generates the implicit default constructor for class C of the form
|
| @@ -5501,17 +5514,14 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| ///
|
| /// Unlike call sites, we always have an element available, so we can use it
|
| /// directly rather than computing the relevant options for [_emitMemberName].
|
| - JS.Expression _declareMemberName(ExecutableElement e, {bool useExtension}) {
|
| - String name;
|
| - if (e is PropertyAccessorElement) {
|
| - name = e.variable.name;
|
| - } else {
|
| - name = e.name;
|
| - }
|
| + JS.Expression _declareMemberName(ExecutableElement e,
|
| + {bool useExtension, useDisplayName = false}) {
|
| + var name = (e is PropertyAccessorElement) ? e.variable.name : e.name;
|
| return _emitMemberName(name,
|
| isStatic: e.isStatic,
|
| useExtension:
|
| - useExtension ?? _extensionTypes.isNativeClass(e.enclosingElement));
|
| + useExtension ?? _extensionTypes.isNativeClass(e.enclosingElement),
|
| + useDisplayName: useDisplayName);
|
| }
|
|
|
| /// This handles member renaming for private names and operators.
|
| @@ -5558,6 +5568,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| {DartType type,
|
| bool isStatic: false,
|
| bool useExtension,
|
| + bool useDisplayName: false,
|
| Element element}) {
|
| // Static members skip the rename steps and may require JS interop renames.
|
| if (isStatic) {
|
| @@ -5570,20 +5581,22 @@ class CodeGenerator extends GeneralizingAstVisitor
|
|
|
| // When generating synthetic names, we use _ as the prefix, since Dart names
|
| // won't have this (eliminated above), nor will static names reach here.
|
| - switch (name) {
|
| - case '[]':
|
| - name = '_get';
|
| - break;
|
| - case '[]=':
|
| - name = '_set';
|
| - break;
|
| - case 'unary-':
|
| - name = '_negate';
|
| - break;
|
| - case 'constructor':
|
| - case 'prototype':
|
| - name = '_$name';
|
| - break;
|
| + if (!useDisplayName) {
|
| + switch (name) {
|
| + case '[]':
|
| + name = '_get';
|
| + break;
|
| + case '[]=':
|
| + name = '_set';
|
| + break;
|
| + case 'unary-':
|
| + name = '_negate';
|
| + break;
|
| + case 'constructor':
|
| + case 'prototype':
|
| + name = '_$name';
|
| + break;
|
| + }
|
| }
|
|
|
| var result = _propertyName(name);
|
|
|