Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart

Issue 237583014: JS templates (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: cleanup Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698