OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
9 * from the given element. | 9 * from the given element. |
10 */ | 10 */ |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 well as in the generated code. */ | 69 well as in the generated code. */ |
70 String isolateProperties; | 70 String isolateProperties; |
71 String classesCollector; | 71 String classesCollector; |
72 final Set<ClassElement> neededClasses = new Set<ClassElement>(); | 72 final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
73 final List<ClassElement> regularClasses = <ClassElement>[]; | 73 final List<ClassElement> regularClasses = <ClassElement>[]; |
74 final List<ClassElement> deferredClasses = <ClassElement>[]; | 74 final List<ClassElement> deferredClasses = <ClassElement>[]; |
75 final List<ClassElement> nativeClasses = <ClassElement>[]; | 75 final List<ClassElement> nativeClasses = <ClassElement>[]; |
76 final List<Selector> trivialNsmHandlers = <Selector>[]; | 76 final List<Selector> trivialNsmHandlers = <Selector>[]; |
77 final Map<String, String> mangledFieldNames = <String, String>{}; | 77 final Map<String, String> mangledFieldNames = <String, String>{}; |
78 final Set<String> interceptorInvocationNames = new Set<String>(); | 78 final Set<String> interceptorInvocationNames = new Set<String>(); |
| 79 final Set<String> recordedUnmangledNames = new Set<String>(); |
79 | 80 |
80 // TODO(ngeoffray): remove this field. | 81 // TODO(ngeoffray): remove this field. |
81 Set<ClassElement> instantiatedClasses; | 82 Set<ClassElement> instantiatedClasses; |
82 | 83 |
83 final List<jsAst.Expression> boundClosures = <jsAst.Expression>[]; | 84 final List<jsAst.Expression> boundClosures = <jsAst.Expression>[]; |
84 | 85 |
85 JavaScriptBackend get backend => compiler.backend; | 86 JavaScriptBackend get backend => compiler.backend; |
86 | 87 |
87 String get _ => compiler.enableMinification ? "" : " "; | 88 String get _ => compiler.enableMinification ? "" : " "; |
88 String get n => compiler.enableMinification ? "" : "\n"; | 89 String get n => compiler.enableMinification ? "" : "\n"; |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 member, isInterceptedMethod, invocationName, | 1011 member, isInterceptedMethod, invocationName, |
1011 parametersBuffer, argumentsBuffer, | 1012 parametersBuffer, argumentsBuffer, |
1012 indexOfLastOptionalArgumentInParameters); | 1013 indexOfLastOptionalArgumentInParameters); |
1013 } else { | 1014 } else { |
1014 body = [js.return_(js('this')[namer.getName(member)](argumentsBuffer))]; | 1015 body = [js.return_(js('this')[namer.getName(member)](argumentsBuffer))]; |
1015 } | 1016 } |
1016 | 1017 |
1017 jsAst.Fun function = js.fun(parametersBuffer, body); | 1018 jsAst.Fun function = js.fun(parametersBuffer, body); |
1018 | 1019 |
1019 defineStub(invocationName, function); | 1020 defineStub(invocationName, function); |
| 1021 |
| 1022 String reflectionName = getReflectionName(selector); |
| 1023 if (reflectionName != null) { |
| 1024 defineStub('+$reflectionName', js('0')); |
| 1025 } |
1020 } | 1026 } |
1021 | 1027 |
1022 void addParameterStubs(FunctionElement member, | 1028 void addParameterStubs(FunctionElement member, |
1023 DefineStubFunction defineStub) { | 1029 DefineStubFunction defineStub) { |
1024 // We fill the lists depending on the selector. For example, | 1030 // We fill the lists depending on the selector. For example, |
1025 // take method foo: | 1031 // take method foo: |
1026 // foo(a, b, {c, d}); | 1032 // foo(a, b, {c, d}); |
1027 // | 1033 // |
1028 // We may have multiple ways of calling foo: | 1034 // We may have multiple ways of calling foo: |
1029 // (1) foo(1, 2); | 1035 // (1) foo(1, 2); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 if (!parameters.optionalParameters.isEmpty) { | 1204 if (!parameters.optionalParameters.isEmpty) { |
1199 addParameterStubs(member, builder.addProperty); | 1205 addParameterStubs(member, builder.addProperty); |
1200 } | 1206 } |
1201 } else if (!member.isField()) { | 1207 } else if (!member.isField()) { |
1202 compiler.internalError('unexpected kind: "${member.kind}"', | 1208 compiler.internalError('unexpected kind: "${member.kind}"', |
1203 element: member); | 1209 element: member); |
1204 } | 1210 } |
1205 emitExtraAccessors(member, builder); | 1211 emitExtraAccessors(member, builder); |
1206 } | 1212 } |
1207 | 1213 |
1208 String getReflectionName(Element element) { | 1214 String getReflectionName(elementOrSelector) { |
1209 if (!compiler.mirrorsEnabled) return null; | 1215 if (!compiler.mirrorsEnabled) return null; |
1210 String name = element.name.slowToString(); | 1216 String result = getReflectionNameInternal(elementOrSelector); |
1211 if (element.isGetter()) return name; | 1217 if (recordedUnmangledNames.contains(result)) return null; |
1212 if (element.isSetter()) return '$name='; | 1218 recordedUnmangledNames.add(result); |
1213 if (element.isFunction() || element.isConstructor()) { | 1219 return result; |
1214 FunctionElement function = element; | 1220 } |
1215 int requiredParameterCount = function.requiredParameterCount(compiler); | 1221 |
1216 int optionalParameterCount = function.optionalParameterCount(compiler); | 1222 String getReflectionNameInternal(elementOrSelector) { |
| 1223 String name = elementOrSelector.name.slowToString(); |
| 1224 if (elementOrSelector.isGetter()) return name; |
| 1225 if (elementOrSelector.isSetter()) return '$name='; |
| 1226 if (elementOrSelector is Selector |
| 1227 || elementOrSelector.isFunction() |
| 1228 || elementOrSelector.isConstructor()) { |
| 1229 int requiredParameterCount; |
| 1230 int optionalParameterCount; |
| 1231 bool isConstructor; |
| 1232 if (elementOrSelector is Selector) { |
| 1233 requiredParameterCount = elementOrSelector.argumentCount; |
| 1234 optionalParameterCount = 0; |
| 1235 isConstructor = false; |
| 1236 } else { |
| 1237 FunctionElement function = elementOrSelector; |
| 1238 requiredParameterCount = function.requiredParameterCount(compiler); |
| 1239 optionalParameterCount = function.optionalParameterCount(compiler); |
| 1240 isConstructor = function.isConstructor(); |
| 1241 } |
1217 String suffix = '$name:$requiredParameterCount:$optionalParameterCount'; | 1242 String suffix = '$name:$requiredParameterCount:$optionalParameterCount'; |
1218 return (function.isConstructor()) ? 'new $suffix' : suffix; | 1243 return (isConstructor) ? 'new $suffix' : suffix; |
1219 } | 1244 } |
| 1245 Element element = elementOrSelector; |
1220 if (element.isGenerativeConstructorBody()) { | 1246 if (element.isGenerativeConstructorBody()) { |
1221 return null; | 1247 return null; |
1222 } | 1248 } |
1223 throw compiler.internalErrorOnElement( | 1249 throw compiler.internalErrorOnElement( |
1224 element, 'Do not know how to reflect on this $element'); | 1250 element, 'Do not know how to reflect on this $element'); |
1225 } | 1251 } |
1226 | 1252 |
1227 /** | 1253 /** |
1228 * Documentation wanted -- johnniwinther | 1254 * Documentation wanted -- johnniwinther |
1229 * | 1255 * |
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2409 // If we're calling bar on an object of type D, we don't need | 2435 // If we're calling bar on an object of type D, we don't need |
2410 // the handler either because all objects of type D implement | 2436 // the handler either because all objects of type D implement |
2411 // bar through inheritance. | 2437 // bar through inheritance. |
2412 // | 2438 // |
2413 // If we're calling bar on an object of type A we do need the | 2439 // If we're calling bar on an object of type A we do need the |
2414 // handler because we may have to call B.noSuchMethod since B | 2440 // handler because we may have to call B.noSuchMethod since B |
2415 // does not implement bar. | 2441 // does not implement bar. |
2416 if (mask.willHit(selector, compiler)) continue; | 2442 if (mask.willHit(selector, compiler)) continue; |
2417 String jsName = namer.invocationMirrorInternalName(selector); | 2443 String jsName = namer.invocationMirrorInternalName(selector); |
2418 addedJsNames[jsName] = selector; | 2444 addedJsNames[jsName] = selector; |
| 2445 String reflectionName = getReflectionName(selector); |
| 2446 if (reflectionName != null) { |
| 2447 mangledFieldNames[jsName] = reflectionName; |
| 2448 } |
2419 } | 2449 } |
2420 } | 2450 } |
2421 | 2451 |
2422 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); | 2452 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
2423 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); | 2453 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); |
2424 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); | 2454 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); |
2425 | 2455 |
2426 // Set flag used by generateMethod helper below. If we have very few | 2456 // Set flag used by generateMethod helper below. If we have very few |
2427 // handlers we use defineStub for them all, rather than try to generate them | 2457 // handlers we use defineStub for them all, rather than try to generate them |
2428 // at runtime. | 2458 // at runtime. |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3417 | 3447 |
3418 const String HOOKS_API_USAGE = """ | 3448 const String HOOKS_API_USAGE = """ |
3419 // The code supports the following hooks: | 3449 // The code supports the following hooks: |
3420 // dartPrint(message) - if this function is defined it is called | 3450 // dartPrint(message) - if this function is defined it is called |
3421 // instead of the Dart [print] method. | 3451 // instead of the Dart [print] method. |
3422 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3452 // dartMainRunner(main) - if this function is defined, the Dart [main] |
3423 // method will not be invoked directly. | 3453 // method will not be invoked directly. |
3424 // Instead, a closure that will invoke [main] is | 3454 // Instead, a closure that will invoke [main] is |
3425 // passed to [dartMainRunner]. | 3455 // passed to [dartMainRunner]. |
3426 """; | 3456 """; |
OLD | NEW |