| 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 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 element: member); | 1203 element: member); |
| 1204 } | 1204 } |
| 1205 emitExtraAccessors(member, builder); | 1205 emitExtraAccessors(member, builder); |
| 1206 } | 1206 } |
| 1207 | 1207 |
| 1208 String getReflectionName(Element element) { | 1208 String getReflectionName(Element element) { |
| 1209 if (!compiler.mirrorsEnabled) return null; | 1209 if (!compiler.mirrorsEnabled) return null; |
| 1210 String name = element.name.slowToString(); | 1210 String name = element.name.slowToString(); |
| 1211 if (element.isGetter()) return name; | 1211 if (element.isGetter()) return name; |
| 1212 if (element.isSetter()) return '$name='; | 1212 if (element.isSetter()) return '$name='; |
| 1213 if (element.isFunction()) { | 1213 if (element.isFunction() || element.isConstructor()) { |
| 1214 FunctionElement function = element; | 1214 FunctionElement function = element; |
| 1215 int requiredParameterCount = function.requiredParameterCount(compiler); | 1215 int requiredParameterCount = function.requiredParameterCount(compiler); |
| 1216 int optionalParameterCount = function.optionalParameterCount(compiler); | 1216 int optionalParameterCount = function.optionalParameterCount(compiler); |
| 1217 String suffix = '$name:$requiredParameterCount:$optionalParameterCount'; | 1217 String suffix = '$name:$requiredParameterCount:$optionalParameterCount'; |
| 1218 return (function.isConstructor()) ? 'new $suffix' : suffix; | 1218 return (function.isConstructor()) ? 'new $suffix' : suffix; |
| 1219 } | 1219 } |
| 1220 if (element.isGenerativeConstructorBody()) { | 1220 if (element.isGenerativeConstructorBody()) { |
| 1221 return null; | 1221 return null; |
| 1222 } | 1222 } |
| 1223 throw compiler.internalErrorOnElement( | 1223 throw compiler.internalErrorOnElement( |
| 1224 element, 'Do not know how to reflect on this'); | 1224 element, 'Do not know how to reflect on this $element'); |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 /** | 1227 /** |
| 1228 * Documentation wanted -- johnniwinther | 1228 * Documentation wanted -- johnniwinther |
| 1229 * | 1229 * |
| 1230 * Invariant: [classElement] must be a declaration element. | 1230 * Invariant: [classElement] must be a declaration element. |
| 1231 */ | 1231 */ |
| 1232 void emitInstanceMembers(ClassElement classElement, | 1232 void emitInstanceMembers(ClassElement classElement, |
| 1233 ClassBuilder builder) { | 1233 ClassBuilder builder) { |
| 1234 assert(invariant(classElement, classElement.isDeclaration)); | 1234 assert(invariant(classElement, classElement.isDeclaration)); |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 emitInstanceMembers(classElement, builder); | 1647 emitInstanceMembers(classElement, builder); |
| 1648 } | 1648 } |
| 1649 emitIsTests(classElement, builder); | 1649 emitIsTests(classElement, builder); |
| 1650 | 1650 |
| 1651 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. | 1651 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. |
| 1652 if (!buffer.isEmpty) { | 1652 if (!buffer.isEmpty) { |
| 1653 buffer.write(',$n$n'); | 1653 buffer.write(',$n$n'); |
| 1654 } | 1654 } |
| 1655 buffer.write('$className:$_'); | 1655 buffer.write('$className:$_'); |
| 1656 buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler)); | 1656 buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler)); |
| 1657 if (compiler.mirrorsEnabled) { |
| 1658 buffer.write(',$n$n"+${classElement.name.slowToString()}": 0'); |
| 1659 } |
| 1657 } | 1660 } |
| 1658 | 1661 |
| 1659 bool get getterAndSetterCanBeImplementedByFieldSpec => true; | 1662 bool get getterAndSetterCanBeImplementedByFieldSpec => true; |
| 1660 | 1663 |
| 1661 /// If this is true then we can generate the noSuchMethod handlers at startup | 1664 /// If this is true then we can generate the noSuchMethod handlers at startup |
| 1662 /// time, instead of them being emitted as part of the Object class. | 1665 /// time, instead of them being emitted as part of the Object class. |
| 1663 bool get generateTrivialNsmHandlers => true; | 1666 bool get generateTrivialNsmHandlers => true; |
| 1664 | 1667 |
| 1665 int _selectorRank(Selector selector) { | 1668 int _selectorRank(Selector selector) { |
| 1666 int arity = selector.argumentCount * 3; | 1669 int arity = selector.argumentCount * 3; |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 for (Element element in Elements.sortedByPosition(elements)) { | 1880 for (Element element in Elements.sortedByPosition(elements)) { |
| 1878 CodeBuffer buffer = bufferForElement(element, eagerBuffer); | 1881 CodeBuffer buffer = bufferForElement(element, eagerBuffer); |
| 1879 jsAst.Expression code = backend.generatedCode[element]; | 1882 jsAst.Expression code = backend.generatedCode[element]; |
| 1880 String name = namer.getName(element); | 1883 String name = namer.getName(element); |
| 1881 emitStaticFunction(buffer, name, code); | 1884 emitStaticFunction(buffer, name, code); |
| 1882 var metadata = buildMetadataFunction(element); | 1885 var metadata = buildMetadataFunction(element); |
| 1883 if (metadata != null) { | 1886 if (metadata != null) { |
| 1884 buffer.write(',$n$n"@$name":$_'); | 1887 buffer.write(',$n$n"@$name":$_'); |
| 1885 buffer.write(jsAst.prettyPrint(metadata, compiler)); | 1888 buffer.write(jsAst.prettyPrint(metadata, compiler)); |
| 1886 } | 1889 } |
| 1890 String reflectionName = getReflectionName(element); |
| 1891 if (reflectionName != null) { |
| 1892 buffer.write(',$n$n"+$reflectionName":${_}0'); |
| 1893 } |
| 1887 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; | 1894 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; |
| 1888 if (bailoutCode != null) { | 1895 if (bailoutCode != null) { |
| 1889 pendingElementsWithBailouts.remove(element); | 1896 pendingElementsWithBailouts.remove(element); |
| 1890 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); | 1897 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); |
| 1891 } | 1898 } |
| 1892 } | 1899 } |
| 1893 | 1900 |
| 1894 if (!pendingElementsWithBailouts.isEmpty) { | 1901 if (!pendingElementsWithBailouts.isEmpty) { |
| 1895 addComment('pendingElementsWithBailouts', eagerBuffer); | 1902 addComment('pendingElementsWithBailouts', eagerBuffer); |
| 1896 } | 1903 } |
| (...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3334 MessageKind.GENERIC.error({'text': message}), | 3341 MessageKind.GENERIC.error({'text': message}), |
| 3335 api.Diagnostic.WARNING); | 3342 api.Diagnostic.WARNING); |
| 3336 } | 3343 } |
| 3337 | 3344 |
| 3338 // TODO(ahe): This code should be integrated in finishClasses. | 3345 // TODO(ahe): This code should be integrated in finishClasses. |
| 3339 String getReflectionDataParser() { | 3346 String getReflectionDataParser() { |
| 3340 return ''' | 3347 return ''' |
| 3341 (function (reflectionData) { | 3348 (function (reflectionData) { |
| 3342 if (!init.libraries) init.libraries = []; | 3349 if (!init.libraries) init.libraries = []; |
| 3343 if (!init.mangledNames) init.mangledNames = {}; | 3350 if (!init.mangledNames) init.mangledNames = {}; |
| 3351 if (!init.mangledGlobalNames) init.mangledGlobalNames = {}; |
| 3344 var libraries = init.libraries; | 3352 var libraries = init.libraries; |
| 3345 var mangledNames = init.mangledNames; | 3353 var mangledNames = init.mangledNames; |
| 3354 var mangledGlobalNames = init.mangledGlobalNames; |
| 3346 var hasOwnProperty = Object.prototype.hasOwnProperty; | 3355 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 3347 var length = reflectionData.length; | 3356 var length = reflectionData.length; |
| 3348 for (var i = 0; i < length; i++) { | 3357 for (var i = 0; i < length; i++) { |
| 3349 var data = reflectionData[i]; | 3358 var data = reflectionData[i]; |
| 3350 var name = data[0]; | 3359 var name = data[0]; |
| 3351 var uri = data[1]; | 3360 var uri = data[1]; |
| 3352 var metadata = data[2]; | 3361 var metadata = data[2]; |
| 3353 var descriptor = data[3]; | 3362 var descriptor = data[3]; |
| 3354 var classes = []; | 3363 var classes = []; |
| 3355 var functions = []; | 3364 var functions = []; |
| 3356 for (var property in descriptor) { | 3365 for (var property in descriptor) { |
| 3357 if (!hasOwnProperty.call(descriptor, property)) continue; | 3366 if (!hasOwnProperty.call(descriptor, property)) continue; |
| 3358 var element = descriptor[property]; | 3367 var element = descriptor[property]; |
| 3359 if (property.substring(0, 1) == "@") { | 3368 var firstChar = property.substring(0, 1); |
| 3369 var previousProperty; |
| 3370 if (firstChar == "+") { |
| 3371 mangledGlobalNames[previousProperty] = property.substring(1); |
| 3372 } else if (firstChar == "@") { |
| 3360 property = property.substring(1); | 3373 property = property.substring(1); |
| 3361 ${namer.CURRENT_ISOLATE}[property]["${namer.metadataField}"] = element; | 3374 ${namer.CURRENT_ISOLATE}[property]["${namer.metadataField}"] = element; |
| 3362 } else if (typeof element === "function") { | 3375 } else if (typeof element === "function") { |
| 3363 ${namer.CURRENT_ISOLATE}[property] = element; | 3376 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; |
| 3364 functions.push(property); | 3377 functions.push(property); |
| 3365 } else { | 3378 } else { |
| 3379 previousProperty = property; |
| 3366 var newDesc = {}; | 3380 var newDesc = {}; |
| 3367 var previousProp; | 3381 var previousProp; |
| 3368 for (var prop in element) { | 3382 for (var prop in element) { |
| 3369 if (!hasOwnProperty.call(element, prop)) continue; | 3383 if (!hasOwnProperty.call(element, prop)) continue; |
| 3370 var firstChar = prop.substring(0, 1); | 3384 firstChar = prop.substring(0, 1); |
| 3371 if (firstChar == "+") { | 3385 if (firstChar == "+") { |
| 3372 mangledNames[previousProp] = prop.substring(1); | 3386 mangledNames[previousProp] = prop.substring(1); |
| 3373 } else if (firstChar == "@" && prop != "@") { | 3387 } else if (firstChar == "@" && prop != "@") { |
| 3374 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' | 3388 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' |
| 3375 '''element[prop]; | 3389 '''element[prop]; |
| 3376 } else { | 3390 } else { |
| 3377 newDesc[previousProp = prop] = element[prop]; | 3391 newDesc[previousProp = prop] = element[prop]; |
| 3378 } | 3392 } |
| 3379 } | 3393 } |
| 3380 $classesCollector[property] = newDesc; | 3394 $classesCollector[property] = newDesc; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3393 | 3407 |
| 3394 const String HOOKS_API_USAGE = """ | 3408 const String HOOKS_API_USAGE = """ |
| 3395 // The code supports the following hooks: | 3409 // The code supports the following hooks: |
| 3396 // dartPrint(message) - if this function is defined it is called | 3410 // dartPrint(message) - if this function is defined it is called |
| 3397 // instead of the Dart [print] method. | 3411 // instead of the Dart [print] method. |
| 3398 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3412 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 3399 // method will not be invoked directly. | 3413 // method will not be invoked directly. |
| 3400 // Instead, a closure that will invoke [main] is | 3414 // Instead, a closure that will invoke [main] is |
| 3401 // passed to [dartMainRunner]. | 3415 // passed to [dartMainRunner]. |
| 3402 """; | 3416 """; |
| OLD | NEW |