Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(795)

Unified Diff: pkg/dev_compiler/lib/src/compiler/code_generator.dart

Issue 2623053004: Fix noSuchMethod handling of methods that are also extension methods. Fix noSuchMethod handling of … (Closed)
Patch Set: Fix noSuchMethod handling of methods that are also extension methods. Fix noSuchMethod handling of … Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/dev_compiler/lib/sdk/ddc_sdk.sum ('k') | pkg/dev_compiler/test/browser/language_tests.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « pkg/dev_compiler/lib/sdk/ddc_sdk.sum ('k') | pkg/dev_compiler/test/browser/language_tests.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698