| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class ClassEmitter extends CodeEmitterHelper { | 7 class ClassEmitter extends CodeEmitterHelper { |
| 8 /** | 8 /** |
| 9 * Documentation wanted -- johnniwinther | 9 * Documentation wanted -- johnniwinther |
| 10 * | 10 * |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 217 } |
| 218 int code = getterCode + (setterCode << 2); | 218 int code = getterCode + (setterCode << 2); |
| 219 if (code == 0) { | 219 if (code == 0) { |
| 220 compiler.internalError(field, | 220 compiler.internalError(field, |
| 221 'Field code is 0 ($element/$field).'); | 221 'Field code is 0 ($element/$field).'); |
| 222 } else { | 222 } else { |
| 223 fieldCode = FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]; | 223 fieldCode = FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]; |
| 224 } | 224 } |
| 225 } | 225 } |
| 226 if (backend.isAccessibleByReflection(field)) { | 226 if (backend.isAccessibleByReflection(field)) { |
| 227 reflectionMarker = '-'; | 227 DartType type = field.type; |
| 228 if (backend.isNeededForReflection(field)) { | 228 reflectionMarker = '-${task.metadataEmitter.reifyType(type)}'; |
| 229 DartType type = field.type; | |
| 230 reflectionMarker = '-${task.metadataEmitter.reifyType(type)}'; | |
| 231 } | |
| 232 } | 229 } |
| 233 builder.addField('$fieldName$fieldCode$reflectionMarker'); | 230 builder.addField('$fieldName$fieldCode$reflectionMarker'); |
| 234 fieldsAdded = true; | 231 fieldsAdded = true; |
| 235 } | 232 } |
| 236 }); | 233 }); |
| 237 } | 234 } |
| 238 | 235 |
| 239 if (hasMetadata) { | 236 if (hasMetadata) { |
| 240 builder.fieldMetadata = fieldMetadata; | 237 builder.fieldMetadata = fieldMetadata; |
| 241 } | 238 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 | 303 |
| 307 void emitClassBuilderWithReflectionData(String className, | 304 void emitClassBuilderWithReflectionData(String className, |
| 308 ClassElement classElement, | 305 ClassElement classElement, |
| 309 ClassBuilder classBuilder, | 306 ClassBuilder classBuilder, |
| 310 ClassBuilder enclosingBuilder) { | 307 ClassBuilder enclosingBuilder) { |
| 311 var metadata = task.metadataEmitter.buildMetadataFunction(classElement); | 308 var metadata = task.metadataEmitter.buildMetadataFunction(classElement); |
| 312 if (metadata != null) { | 309 if (metadata != null) { |
| 313 classBuilder.addProperty("@", metadata); | 310 classBuilder.addProperty("@", metadata); |
| 314 } | 311 } |
| 315 | 312 |
| 316 if (backend.isNeededForReflection(classElement)) { | 313 if (backend.isAccessibleByReflection(classElement)) { |
| 317 Link typeVars = classElement.typeVariables; | 314 Link typeVars = classElement.typeVariables; |
| 318 Iterable typeVariableProperties = task.typeVariableHandler | 315 Iterable typeVariableProperties = task.typeVariableHandler |
| 319 .typeVariablesOf(classElement).map(js.number); | 316 .typeVariablesOf(classElement).map(js.number); |
| 320 | 317 |
| 321 ClassElement superclass = classElement.superclass; | 318 ClassElement superclass = classElement.superclass; |
| 322 bool hasSuper = superclass != null; | 319 bool hasSuper = superclass != null; |
| 323 if ((!typeVariableProperties.isEmpty && !hasSuper) || | 320 if ((!typeVariableProperties.isEmpty && !hasSuper) || |
| 324 (hasSuper && superclass.typeVariables != typeVars)) { | 321 (hasSuper && superclass.typeVariables != typeVars)) { |
| 325 classBuilder.addProperty('<>', | 322 classBuilder.addProperty('<>', |
| 326 new jsAst.ArrayInitializer.from(typeVariableProperties)); | 323 new jsAst.ArrayInitializer.from(typeVariableProperties)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 346 | 343 |
| 347 if (!statics.isEmpty) { | 344 if (!statics.isEmpty) { |
| 348 classBuilder.addProperty('static', new jsAst.ObjectInitializer(statics)); | 345 classBuilder.addProperty('static', new jsAst.ObjectInitializer(statics)); |
| 349 } | 346 } |
| 350 | 347 |
| 351 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. | 348 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. |
| 352 enclosingBuilder.addProperty(className, classBuilder.toObjectInitializer()); | 349 enclosingBuilder.addProperty(className, classBuilder.toObjectInitializer()); |
| 353 | 350 |
| 354 String reflectionName = task.getReflectionName(classElement, className); | 351 String reflectionName = task.getReflectionName(classElement, className); |
| 355 if (reflectionName != null) { | 352 if (reflectionName != null) { |
| 356 if (!backend.isNeededForReflection(classElement)) { | 353 if (!backend.isAccessibleByReflection(classElement)) { |
| 357 enclosingBuilder.addProperty("+$reflectionName", js.number(0)); | 354 enclosingBuilder.addProperty("+$reflectionName", js.number(0)); |
| 358 } else { | 355 } else { |
| 359 List<int> types = <int>[]; | 356 List<int> types = <int>[]; |
| 360 if (classElement.supertype != null) { | 357 if (classElement.supertype != null) { |
| 361 types.add(task.metadataEmitter.reifyType(classElement.supertype)); | 358 types.add(task.metadataEmitter.reifyType(classElement.supertype)); |
| 362 } | 359 } |
| 363 for (DartType interface in classElement.interfaces) { | 360 for (DartType interface in classElement.interfaces) { |
| 364 types.add(task.metadataEmitter.reifyType(interface)); | 361 types.add(task.metadataEmitter.reifyType(interface)); |
| 365 } | 362 } |
| 366 enclosingBuilder.addProperty("+$reflectionName", | 363 enclosingBuilder.addProperty("+$reflectionName", |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 void generateGetter(Element member, String fieldName, String accessorName, | 526 void generateGetter(Element member, String fieldName, String accessorName, |
| 530 ClassBuilder builder) { | 527 ClassBuilder builder) { |
| 531 String getterName = namer.getterNameFromAccessorName(accessorName); | 528 String getterName = namer.getterNameFromAccessorName(accessorName); |
| 532 ClassElement cls = member.enclosingClass; | 529 ClassElement cls = member.enclosingClass; |
| 533 String className = namer.getNameOfClass(cls); | 530 String className = namer.getNameOfClass(cls); |
| 534 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 531 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; |
| 535 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 532 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; |
| 536 task.precompiledFunction.add( | 533 task.precompiledFunction.add( |
| 537 js('#.prototype.# = function(#) { return #.# }', | 534 js('#.prototype.# = function(#) { return #.# }', |
| 538 [className, getterName, args, receiver, fieldName])); | 535 [className, getterName, args, receiver, fieldName])); |
| 539 if (backend.isNeededForReflection(member)) { | 536 if (backend.isAccessibleByReflection(member)) { |
| 540 task.precompiledFunction.add( | 537 task.precompiledFunction.add( |
| 541 js('#.prototype.#.${namer.reflectableField} = 1', | 538 js('#.prototype.#.${namer.reflectableField} = 1', |
| 542 [className, getterName])); | 539 [className, getterName])); |
| 543 } | 540 } |
| 544 } | 541 } |
| 545 | 542 |
| 546 void generateSetter(Element member, String fieldName, String accessorName, | 543 void generateSetter(Element member, String fieldName, String accessorName, |
| 547 ClassBuilder builder) { | 544 ClassBuilder builder) { |
| 548 String setterName = namer.setterNameFromAccessorName(accessorName); | 545 String setterName = namer.setterNameFromAccessorName(accessorName); |
| 549 ClassElement cls = member.enclosingClass; | 546 ClassElement cls = member.enclosingClass; |
| 550 String className = namer.getNameOfClass(cls); | 547 String className = namer.getNameOfClass(cls); |
| 551 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 548 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; |
| 552 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 549 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; |
| 553 task.precompiledFunction.add( | 550 task.precompiledFunction.add( |
| 554 // TODO: remove 'return'? | 551 // TODO: remove 'return'? |
| 555 js('#.prototype.# = function(#, v) { return #.# = v; }', | 552 js('#.prototype.# = function(#, v) { return #.# = v; }', |
| 556 [className, setterName, args, receiver, fieldName])); | 553 [className, setterName, args, receiver, fieldName])); |
| 557 if (backend.isNeededForReflection(member)) { | 554 if (backend.isAccessibleByReflection(member)) { |
| 558 task.precompiledFunction.add( | 555 task.precompiledFunction.add( |
| 559 js('#.prototype.#.${namer.reflectableField} = 1', | 556 js('#.prototype.#.${namer.reflectableField} = 1', |
| 560 [className, setterName])); | 557 [className, setterName])); |
| 561 } | 558 } |
| 562 } | 559 } |
| 563 | 560 |
| 564 void generateReflectionDataForFieldGetterOrSetter(Element member, | 561 void generateReflectionDataForFieldGetterOrSetter(Element member, |
| 565 String name, | 562 String name, |
| 566 ClassBuilder builder, | 563 ClassBuilder builder, |
| 567 {bool isGetter}) { | 564 {bool isGetter}) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 computeTypeVariable = | 607 computeTypeVariable = |
| 611 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', index); | 608 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', index); |
| 612 } | 609 } |
| 613 jsAst.Expression convertRtiToRuntimeType = | 610 jsAst.Expression convertRtiToRuntimeType = |
| 614 namer.elementAccess(backend.findHelper('convertRtiToRuntimeType')); | 611 namer.elementAccess(backend.findHelper('convertRtiToRuntimeType')); |
| 615 builder.addProperty(name, | 612 builder.addProperty(name, |
| 616 js('function () { return #(#) }', | 613 js('function () { return #(#) }', |
| 617 [convertRtiToRuntimeType, computeTypeVariable])); | 614 [convertRtiToRuntimeType, computeTypeVariable])); |
| 618 } | 615 } |
| 619 } | 616 } |
| OLD | NEW |