Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
index 19051befd201894a20c56fda429922539546a2c0..847c70d7ebff3b93e35bb20316e0201d697bea81 100644 |
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
@@ -1256,7 +1256,7 @@ $classesCollector.$mangledName = {'': |
// Note: the callElement will not have any enclosingElement. |
FunctionElement callElement = |
new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); |
- |
+ |
String invocationName = namer.instanceMethodName(callElement); |
List<String> arguments = new List<String>(parameterCount); |
for (int i = 0; i < parameterCount; i++) { |
@@ -1456,6 +1456,11 @@ $classesCollector.$mangledName = {'': |
String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
+ Element createInvocationMirrorElement = |
+ compiler.findHelper(const SourceString("createInvocationMirror")); |
+ String createInvocationMirrorName = |
+ namer.getName(createInvocationMirrorElement); |
+ |
// Keep track of the JavaScript names we've already added so we |
// do not introduce duplicates (bad for code size). |
Set<String> addedJsNames = new Set<String>(); |
@@ -1478,7 +1483,7 @@ $classesCollector.$mangledName = {'': |
return result; |
} |
- CodeBuffer generateMethod(String methodName, Selector selector) { |
+ CodeBuffer generateMethod(String jsName, Selector selector) { |
// Values match JSInvocationMirror in js-helper library. |
const int METHOD = 0; |
const int GETTER = 1; |
@@ -1486,13 +1491,10 @@ $classesCollector.$mangledName = {'': |
int type = METHOD; |
if (selector.isGetter()) { |
type = GETTER; |
- assert(methodName.startsWith("get:")); |
- methodName = methodName.substring(4); |
} else if (selector.isSetter()) { |
type = SETTER; |
- assert(methodName.startsWith("set:")); |
- methodName = "${methodName.substring(4)}="; |
} |
+ String methodName = selector.invocationMirrorMemberName; |
CodeBuffer args = new CodeBuffer(); |
for (int i = 0; i < selector.argumentCount; i++) { |
if (i != 0) args.add(', '); |
@@ -1506,12 +1508,10 @@ $classesCollector.$mangledName = {'': |
argNames.add(names[i].slowToString()); |
argNames.add('"'); |
} |
- String internalName = namer.instanceMethodInvocationName( |
- selector.library, new SourceString(methodName), selector); |
CodeBuffer buffer = new CodeBuffer(); |
buffer.add('function($args) {\n'); |
buffer.add(' return this.$noSuchMethodName(' |
- '\$.createInvocationMirror("$methodName", "$internalName",' |
+ '\$.$createInvocationMirrorName("$methodName", "$jsName",' |
' $type, [$args], [$argNames]));\n'); |
buffer.add(' }'); |
return buffer; |
@@ -1534,13 +1534,17 @@ $classesCollector.$mangledName = {'': |
// Selector.applies() method. |
if (element is AbstractFieldElement) { |
AbstractFieldElement field = element; |
- if (identical(selector.kind, SelectorKind.GETTER)) { |
+ if (selector.isGetter()) { |
return field.getter != null; |
- } else if (identical(selector.kind, SelectorKind.SETTER)) { |
+ } else if (selector.isSetter()) { |
return field.setter != null; |
} else { |
return false; |
} |
+ } else if (element is VariableElement) { |
+ if (selector.isSetter() && element.modifiers.isFinalOrConst()) { |
+ return false; |
+ } |
} |
return selector.applies(element, compiler); |
} |
@@ -1600,28 +1604,9 @@ $classesCollector.$mangledName = {'': |
// does not implement bar. |
Set<ClassElement> holders = noSuchMethodHoldersFor(receiverType); |
if (holders.every(hasMatchingMember)) continue; |
- |
- String jsName = null; |
- String methodName = null; |
- String nameString = selector.name.slowToString(); |
- if (selector.isGetter()) { |
- jsName = namer.getterName(selector.library, selector.name); |
- methodName = 'get:$nameString'; |
- } else if (selector.isSetter()) { |
- jsName = namer.setterName(selector.library, selector.name); |
- methodName = 'set:$nameString'; |
- } else if (selector.isCall()) { |
- jsName = namer.instanceMethodInvocationName( |
- selector.library, selector.name, selector); |
- methodName = nameString; |
- } else { |
- // We simply ignore selectors that do not need |
- // noSuchMethod handlers. |
- continue; |
- } |
- |
+ String jsName = namer.invocationMirrorInternalName(selector); |
if (!addedJsNames.contains(jsName)) { |
- CodeBuffer jsCode = generateMethod(methodName, selector); |
+ CodeBuffer jsCode = generateMethod(jsName, selector); |
defineInstanceMember(jsName, jsCode); |
addedJsNames.add(jsName); |
} |