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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 (Element member, | 63 (Element member, |
64 String name, | 64 String name, |
65 String accessorName, | 65 String accessorName, |
66 bool needsGetter, | 66 bool needsGetter, |
67 bool needsSetter, | 67 bool needsSetter, |
68 bool needsCheckedSetter) { | 68 bool needsCheckedSetter) { |
69 fields.add(name); | 69 fields.add(name); |
70 }); | 70 }); |
71 } | 71 } |
72 String constructorName = namer.getNameOfClass(classElement); | 72 String constructorName = namer.getNameOfClass(classElement); |
73 | |
73 task.precompiledFunction.add(new jsAst.FunctionDeclaration( | 74 task.precompiledFunction.add(new jsAst.FunctionDeclaration( |
74 new jsAst.VariableDeclaration(constructorName), | 75 new jsAst.VariableDeclaration(constructorName), |
75 js.fun(fields, fields.map( | 76 js('function(#) { #; }', |
floitsch
2014/04/22 16:11:18
not correctly indented.
sra1
2014/04/23 02:33:50
Done.
| |
76 (name) => js('this.$name = $name')).toList()))); | 77 [fields, fields.map((name) => js('this.# = #', [name, name]))]))); |
floitsch
2014/04/22 16:11:18
split arguments and body in separate lines.
sra1
2014/04/23 02:33:50
Done.
| |
78 // TODO(sra): Implement placeholders in VariableDeclaration position: | |
floitsch
2014/04/22 16:11:18
Move TODO before the 'new'.
sra1
2014/04/23 02:33:50
Done.
| |
79 // task.precompiledFunction.add(js.statement('function #(#) { #; }', | |
80 // [ constructorName, fields, | |
81 // fields.map( | |
82 // (name) => js('this.# = #', [name, name]))])); | |
77 if (runtimeName == null) { | 83 if (runtimeName == null) { |
78 runtimeName = constructorName; | 84 runtimeName = constructorName; |
79 } | 85 } |
80 task.precompiledFunction.addAll([ | |
81 js('$constructorName.builtin\$cls = "$runtimeName"'), | |
82 js.if_('!"name" in $constructorName', | |
83 js('$constructorName.name = "$constructorName"')), | |
84 js('\$desc=\$collectedClasses.$constructorName'), | |
85 js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')), | |
86 js('$constructorName.prototype = \$desc'), | |
87 ]); | |
88 | 86 |
89 task.precompiledConstructorNames.add(js(constructorName)); | 87 task.precompiledFunction.add( |
88 js.statement('''{ | |
floitsch
2014/04/22 16:11:18
make raw string?
sra1
2014/04/23 02:33:50
Done.
| |
89 #.builtin\$cls = #; | |
90 if (!"name" in #) | |
91 #.name = #; | |
92 \$desc=\$collectedClasses.#; | |
93 if (\$desc instanceof Array) \$desc = \$desc[1]; | |
94 #.prototype = \$desc; | |
95 }''', | |
96 [ constructorName, js.string(runtimeName), | |
97 constructorName, | |
98 constructorName, js.string(constructorName), | |
99 constructorName, | |
100 constructorName | |
101 ])); | |
102 | |
103 task.precompiledConstructorNames.add(js('#', constructorName)); | |
90 } | 104 } |
91 | 105 |
92 /// Returns `true` if fields added. | 106 /// Returns `true` if fields added. |
93 bool emitFields(Element element, | 107 bool emitFields(Element element, |
94 ClassBuilder builder, | 108 ClassBuilder builder, |
95 String superName, | 109 String superName, |
96 { bool classIsNative: false, | 110 { bool classIsNative: false, |
97 bool emitStatics: false, | 111 bool emitStatics: false, |
98 bool onlyForRti: false }) { | 112 bool onlyForRti: false }) { |
99 assert(!emitStatics || !onlyForRti); | 113 assert(!emitStatics || !onlyForRti); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 ClassBuilder classBuilder, | 309 ClassBuilder classBuilder, |
296 ClassBuilder enclosingBuilder) { | 310 ClassBuilder enclosingBuilder) { |
297 var metadata = task.metadataEmitter.buildMetadataFunction(classElement); | 311 var metadata = task.metadataEmitter.buildMetadataFunction(classElement); |
298 if (metadata != null) { | 312 if (metadata != null) { |
299 classBuilder.addProperty("@", metadata); | 313 classBuilder.addProperty("@", metadata); |
300 } | 314 } |
301 | 315 |
302 if (backend.isNeededForReflection(classElement)) { | 316 if (backend.isNeededForReflection(classElement)) { |
303 Link typeVars = classElement.typeVariables; | 317 Link typeVars = classElement.typeVariables; |
304 Iterable typeVariableProperties = task.typeVariableHandler | 318 Iterable typeVariableProperties = task.typeVariableHandler |
305 .typeVariablesOf(classElement).map(js.toExpression); | 319 .typeVariablesOf(classElement).map(js.number); |
306 | 320 |
307 ClassElement superclass = classElement.superclass; | 321 ClassElement superclass = classElement.superclass; |
308 bool hasSuper = superclass != null; | 322 bool hasSuper = superclass != null; |
309 if ((!typeVariableProperties.isEmpty && !hasSuper) || | 323 if ((!typeVariableProperties.isEmpty && !hasSuper) || |
310 (hasSuper && superclass.typeVariables != typeVars)) { | 324 (hasSuper && superclass.typeVariables != typeVars)) { |
311 classBuilder.addProperty('<>', | 325 classBuilder.addProperty('<>', |
312 new jsAst.ArrayInitializer.from(typeVariableProperties)); | 326 new jsAst.ArrayInitializer.from(typeVariableProperties)); |
313 } | 327 } |
314 } | 328 } |
315 | 329 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 } | 527 } |
514 | 528 |
515 void generateGetter(Element member, String fieldName, String accessorName, | 529 void generateGetter(Element member, String fieldName, String accessorName, |
516 ClassBuilder builder) { | 530 ClassBuilder builder) { |
517 String getterName = namer.getterNameFromAccessorName(accessorName); | 531 String getterName = namer.getterNameFromAccessorName(accessorName); |
518 ClassElement cls = member.getEnclosingClass(); | 532 ClassElement cls = member.getEnclosingClass(); |
519 String className = namer.getNameOfClass(cls); | 533 String className = namer.getNameOfClass(cls); |
520 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 534 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; |
521 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 535 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; |
522 task.precompiledFunction.add( | 536 task.precompiledFunction.add( |
523 js('$className.prototype.$getterName = #', | 537 js('#.prototype.# = function(#) { return #.# }', |
524 js.fun(args, js.return_(js('$receiver.$fieldName'))))); | 538 [className, getterName, args, receiver, fieldName])); |
525 if (backend.isNeededForReflection(member)) { | 539 if (backend.isNeededForReflection(member)) { |
526 task.precompiledFunction.add( | 540 task.precompiledFunction.add( |
527 js('$className.prototype.$getterName.${namer.reflectableField} = 1')); | 541 js('#.prototype.#.${namer.reflectableField} = 1', |
542 [className, getterName])); | |
528 } | 543 } |
529 } | 544 } |
530 | 545 |
531 void generateSetter(Element member, String fieldName, String accessorName, | 546 void generateSetter(Element member, String fieldName, String accessorName, |
532 ClassBuilder builder) { | 547 ClassBuilder builder) { |
533 String setterName = namer.setterNameFromAccessorName(accessorName); | 548 String setterName = namer.setterNameFromAccessorName(accessorName); |
534 ClassElement cls = member.getEnclosingClass(); | 549 ClassElement cls = member.getEnclosingClass(); |
535 String className = namer.getNameOfClass(cls); | 550 String className = namer.getNameOfClass(cls); |
536 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 551 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; |
537 List<String> args = | 552 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; |
538 backend.isInterceptedMethod(member) ? ['receiver', 'v'] : ['v']; | |
539 task.precompiledFunction.add( | 553 task.precompiledFunction.add( |
540 js('$className.prototype.$setterName = #', | 554 // TODO: remove 'return'? |
541 js.fun(args, js.return_(js('$receiver.$fieldName = v'))))); | 555 js('#.prototype.# = function(#, v) { return #.# = v; }', |
556 [className, setterName, args, receiver, fieldName])); | |
542 if (backend.isNeededForReflection(member)) { | 557 if (backend.isNeededForReflection(member)) { |
543 task.precompiledFunction.add( | 558 task.precompiledFunction.add( |
544 js('$className.prototype.$setterName.${namer.reflectableField} = 1')); | 559 js('#.prototype.#.${namer.reflectableField} = 1', |
560 [className, setterName])); | |
545 } | 561 } |
546 } | 562 } |
547 | 563 |
548 void generateReflectionDataForFieldGetterOrSetter(Element member, | 564 void generateReflectionDataForFieldGetterOrSetter(Element member, |
549 String name, | 565 String name, |
550 ClassBuilder builder, | 566 ClassBuilder builder, |
551 {bool isGetter}) { | 567 {bool isGetter}) { |
552 Selector selector = isGetter | 568 Selector selector = isGetter |
553 ? new Selector.getter(member.name, member.getLibrary()) | 569 ? new Selector.getter(member.name, member.getLibrary()) |
554 : new Selector.setter(member.name, member.getLibrary()); | 570 : new Selector.setter(member.name, member.getLibrary()); |
(...skipping 16 matching lines...) Expand all Loading... | |
571 } | 587 } |
572 superclass = superclass.superclass; | 588 superclass = superclass.superclass; |
573 } | 589 } |
574 } | 590 } |
575 | 591 |
576 void emitTypeVariableReader(ClassElement cls, | 592 void emitTypeVariableReader(ClassElement cls, |
577 ClassBuilder builder, | 593 ClassBuilder builder, |
578 TypeVariableElement element) { | 594 TypeVariableElement element) { |
579 String name = namer.readTypeVariableName(element); | 595 String name = namer.readTypeVariableName(element); |
580 jsAst.Expression index = | 596 jsAst.Expression index = |
581 js.toExpression(RuntimeTypes.getTypeVariableIndex(element)); | 597 js.number(RuntimeTypes.getTypeVariableIndex(element)); |
582 jsAst.Expression computeTypeVariable; | 598 jsAst.Expression computeTypeVariable; |
583 | 599 |
584 Substitution substitution = | 600 Substitution substitution = |
585 backend.rti.computeSubstitution( | 601 backend.rti.computeSubstitution( |
586 cls, element.enclosingElement, alwaysGenerateFunction: true); | 602 cls, element.enclosingElement, alwaysGenerateFunction: true); |
587 if (substitution != null) { | 603 if (substitution != null) { |
588 jsAst.Expression typeArguments = | 604 jsAst.Expression typeArguments = |
589 substitution.getCode(backend.rti, true)['apply']( | 605 js(r'#.apply(null, this.$builtinTypeInfo)', |
590 ['null', r'this.$builtinTypeInfo']); | 606 substitution.getCode(backend.rti, true)); |
591 computeTypeVariable = typeArguments[index]; | 607 computeTypeVariable = js('#[#]', [typeArguments, index]); |
592 } else { | 608 } else { |
593 // TODO(ahe): These can be generated dynamically. | 609 // TODO(ahe): These can be generated dynamically. |
594 computeTypeVariable = | 610 computeTypeVariable = |
595 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', index); | 611 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', index); |
596 } | 612 } |
597 jsAst.Expression convertRtiToRuntimeType = | 613 jsAst.Expression convertRtiToRuntimeType = |
598 namer.elementAccess(compiler.findHelper('convertRtiToRuntimeType')); | 614 namer.elementAccess(compiler.findHelper('convertRtiToRuntimeType')); |
599 builder.addProperty( | 615 builder.addProperty(name, |
600 name, js.fun( | 616 js('function () { return #(#) }', |
601 [], [js.return_(convertRtiToRuntimeType(computeTypeVariable))])); | 617 [convertRtiToRuntimeType, computeTypeVariable])); |
602 } | 618 } |
603 } | 619 } |
OLD | NEW |