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 |