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 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 // uninstantiated classes, that have been overwritten by subclasses. | 1165 // uninstantiated classes, that have been overwritten by subclasses. |
1166 | 1166 |
1167 if (member.isFunction() | 1167 if (member.isFunction() |
1168 || member.isGenerativeConstructorBody() | 1168 || member.isGenerativeConstructorBody() |
1169 || member.isAccessor()) { | 1169 || member.isAccessor()) { |
1170 if (member.isAbstract(compiler)) return; | 1170 if (member.isAbstract(compiler)) return; |
1171 jsAst.Expression code = backend.generatedCode[member]; | 1171 jsAst.Expression code = backend.generatedCode[member]; |
1172 if (code == null) return; | 1172 if (code == null) return; |
1173 String name = namer.getName(member); | 1173 String name = namer.getName(member); |
1174 builder.addProperty(name, code); | 1174 builder.addProperty(name, code); |
| 1175 var metadata = buildMetadataFunction(member); |
| 1176 if (metadata != null) { |
| 1177 builder.addProperty('@$name', metadata); |
| 1178 } |
| 1179 String reflectionName = reflectionName(member); |
| 1180 if (reflectionName != null) { |
| 1181 builder.addProperty('+$reflectionName', js('0')); |
| 1182 } |
1175 code = backend.generatedBailoutCode[member]; | 1183 code = backend.generatedBailoutCode[member]; |
1176 if (code != null) { | 1184 if (code != null) { |
1177 builder.addProperty(namer.getBailoutName(member), code); | 1185 builder.addProperty(namer.getBailoutName(member), code); |
1178 } | 1186 } |
1179 FunctionElement function = member; | 1187 FunctionElement function = member; |
1180 FunctionSignature parameters = function.computeSignature(compiler); | 1188 FunctionSignature parameters = function.computeSignature(compiler); |
1181 if (!parameters.optionalParameters.isEmpty) { | 1189 if (!parameters.optionalParameters.isEmpty) { |
1182 addParameterStubs(member, builder.addProperty); | 1190 addParameterStubs(member, builder.addProperty); |
1183 } | 1191 } |
1184 var metadata = buildMetadataFunction(member); | |
1185 if (metadata != null) { | |
1186 builder.addProperty('@$name', metadata); | |
1187 } | |
1188 } else if (!member.isField()) { | 1192 } else if (!member.isField()) { |
1189 compiler.internalError('unexpected kind: "${member.kind}"', | 1193 compiler.internalError('unexpected kind: "${member.kind}"', |
1190 element: member); | 1194 element: member); |
1191 } | 1195 } |
1192 emitExtraAccessors(member, builder); | 1196 emitExtraAccessors(member, builder); |
1193 } | 1197 } |
1194 | 1198 |
| 1199 String reflectionName(Element element) { |
| 1200 if (!compiler.mirrorsEnabled) return null; |
| 1201 String name = element.name.slowToString(); |
| 1202 if (element.isGetter()) return name; |
| 1203 if (element.isSetter()) return '$name='; |
| 1204 if (element.isFunction()) { |
| 1205 FunctionElement function = element; |
| 1206 int requiredParameterCount = function.requiredParameterCount(compiler); |
| 1207 int optionalParameterCount = function.optionalParameterCount(compiler); |
| 1208 String suffix = '$name:$requiredParameterCount:$optionalParameterCount'; |
| 1209 return (function.isConstructor()) ? 'new $suffix' : suffix; |
| 1210 } |
| 1211 if (element.isGenerativeConstructorBody()) { |
| 1212 return null; |
| 1213 } |
| 1214 throw compiler.internalErrorOnElement( |
| 1215 element, 'Do not know how to reflect on this'); |
| 1216 } |
| 1217 |
1195 /** | 1218 /** |
1196 * Documentation wanted -- johnniwinther | 1219 * Documentation wanted -- johnniwinther |
1197 * | 1220 * |
1198 * Invariant: [classElement] must be a declaration element. | 1221 * Invariant: [classElement] must be a declaration element. |
1199 */ | 1222 */ |
1200 void emitInstanceMembers(ClassElement classElement, | 1223 void emitInstanceMembers(ClassElement classElement, |
1201 ClassBuilder builder) { | 1224 ClassBuilder builder) { |
1202 assert(invariant(classElement, classElement.isDeclaration)); | 1225 assert(invariant(classElement, classElement.isDeclaration)); |
1203 | 1226 |
1204 void visitMember(ClassElement enclosing, Element member) { | 1227 void visitMember(ClassElement enclosing, Element member) { |
(...skipping 2061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3266 compiler.reportMessage(compiler.spanFromSpannable(element), | 3289 compiler.reportMessage(compiler.spanFromSpannable(element), |
3267 MessageKind.GENERIC.error({'text': message}), | 3290 MessageKind.GENERIC.error({'text': message}), |
3268 api.Diagnostic.WARNING); | 3291 api.Diagnostic.WARNING); |
3269 } | 3292 } |
3270 | 3293 |
3271 // TODO(ahe): This code should be integrated in finishClasses. | 3294 // TODO(ahe): This code should be integrated in finishClasses. |
3272 String getReflectionDataParser() { | 3295 String getReflectionDataParser() { |
3273 return ''' | 3296 return ''' |
3274 (function (reflectionData) { | 3297 (function (reflectionData) { |
3275 if (!init.libraries) init.libraries = []; | 3298 if (!init.libraries) init.libraries = []; |
| 3299 if (!init.mangledNames) init.mangledNames = {}; |
3276 var libraries = init.libraries; | 3300 var libraries = init.libraries; |
| 3301 var mangledNames = init.mangledNames; |
3277 var hasOwnProperty = Object.prototype.hasOwnProperty; | 3302 var hasOwnProperty = Object.prototype.hasOwnProperty; |
3278 var length = reflectionData.length; | 3303 var length = reflectionData.length; |
3279 for (var i = 0; i < length; i++) { | 3304 for (var i = 0; i < length; i++) { |
3280 var data = reflectionData[i]; | 3305 var data = reflectionData[i]; |
3281 var name = data[0]; | 3306 var name = data[0]; |
3282 var uri = data[1]; | 3307 var uri = data[1]; |
3283 var metadata = data[2]; | 3308 var metadata = data[2]; |
3284 var descriptor = data[3]; | 3309 var descriptor = data[3]; |
3285 var classes = []; | 3310 var classes = []; |
3286 var functions = []; | 3311 var functions = []; |
3287 for (var property in descriptor) { | 3312 for (var property in descriptor) { |
3288 if (!hasOwnProperty.call(descriptor, property)) continue; | 3313 if (!hasOwnProperty.call(descriptor, property)) continue; |
3289 var element = descriptor[property]; | 3314 var element = descriptor[property]; |
3290 if (property.substring(0, 1) == "@") { | 3315 if (property.substring(0, 1) == "@") { |
3291 property = property.substring(1); | 3316 property = property.substring(1); |
3292 ${namer.CURRENT_ISOLATE}[property]["${namer.metadataField}"] = element; | 3317 ${namer.CURRENT_ISOLATE}[property]["${namer.metadataField}"] = element; |
3293 } else if (typeof element === "function") { | 3318 } else if (typeof element === "function") { |
3294 ${namer.CURRENT_ISOLATE}[property] = element; | 3319 ${namer.CURRENT_ISOLATE}[property] = element; |
3295 functions.push(property); | 3320 functions.push(property); |
3296 } else { | 3321 } else { |
3297 var newDesc = {} | 3322 var newDesc = {}; |
| 3323 var previousProp; |
3298 for (var prop in element) { | 3324 for (var prop in element) { |
3299 if (!hasOwnProperty.call(element, prop)) continue; | 3325 if (!hasOwnProperty.call(element, prop)) continue; |
3300 if (prop.substring(0, 1) == "@" && prop != "@") { | 3326 var firstChar = prop.substring(0, 1); |
| 3327 if (firstChar == "+") { |
| 3328 mangledNames[previousProp] = prop.substring(1); |
| 3329 } else if (firstChar == "@" && prop != "@") { |
3301 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' | 3330 newDesc[prop.substring(1)]["${namer.metadataField}"] =''' |
3302 '''element[prop]; | 3331 '''element[prop]; |
3303 } else { | 3332 } else { |
3304 newDesc[prop] = element[prop]; | 3333 newDesc[previousProp = prop] = element[prop]; |
3305 } | 3334 } |
3306 } | 3335 } |
3307 $classesCollector[property] = newDesc; | 3336 $classesCollector[property] = newDesc; |
3308 classes.push(property); | 3337 classes.push(property); |
3309 } | 3338 } |
3310 } | 3339 } |
3311 libraries.push([name, uri, classes, functions, metadata]); | 3340 libraries.push([name, uri, classes, functions, metadata]); |
3312 } | 3341 } |
3313 })'''; | 3342 })'''; |
3314 } | 3343 } |
3315 } | 3344 } |
3316 | 3345 |
3317 const String GENERATED_BY = """ | 3346 const String GENERATED_BY = """ |
3318 // Generated by dart2js, the Dart to JavaScript compiler. | 3347 // Generated by dart2js, the Dart to JavaScript compiler. |
3319 """; | 3348 """; |
3320 | 3349 |
3321 const String HOOKS_API_USAGE = """ | 3350 const String HOOKS_API_USAGE = """ |
3322 // The code supports the following hooks: | 3351 // The code supports the following hooks: |
3323 // dartPrint(message) - if this function is defined it is called | 3352 // dartPrint(message) - if this function is defined it is called |
3324 // instead of the Dart [print] method. | 3353 // instead of the Dart [print] method. |
3325 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3354 // dartMainRunner(main) - if this function is defined, the Dart [main] |
3326 // method will not be invoked directly. | 3355 // method will not be invoked directly. |
3327 // Instead, a closure that will invoke [main] is | 3356 // Instead, a closure that will invoke [main] is |
3328 // passed to [dartMainRunner]. | 3357 // passed to [dartMainRunner]. |
3329 """; | 3358 """; |
OLD | NEW |