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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart

Issue 891673003: dart2js: Refactoring, documentation, and a few bugfixes in Namer class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comments & some fixes Created 5 years, 10 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 ClassStubGenerator get _stubGenerator => 9 ClassStubGenerator get _stubGenerator =>
10 new ClassStubGenerator(compiler, namer, backend); 10 new ClassStubGenerator(compiler, namer, backend);
11 11
12 /** 12 /**
13 * Documentation wanted -- johnniwinther 13 * Documentation wanted -- johnniwinther
14 */ 14 */
15 void emitClass(Class cls, ClassBuilder enclosingBuilder) { 15 void emitClass(Class cls, ClassBuilder enclosingBuilder) {
16 ClassElement classElement = cls.element; 16 ClassElement classElement = cls.element;
17 17
18 assert(invariant(classElement, classElement.isDeclaration)); 18 assert(invariant(classElement, classElement.isDeclaration));
19 19
20 emitter.needsClassSupport = true; 20 emitter.needsClassSupport = true;
21 21
22 ClassElement superclass = classElement.superclass; 22 ClassElement superclass = classElement.superclass;
23 String superName = ""; 23 String superName = "";
24 if (superclass != null) { 24 if (superclass != null) {
25 superName = namer.getNameOfClass(superclass); 25 superName = namer.className(superclass);
26 } 26 }
27 27
28 if (cls.isMixinApplication) { 28 if (cls.isMixinApplication) {
29 MixinApplication mixinApplication = cls; 29 MixinApplication mixinApplication = cls;
30 String mixinName = mixinApplication.mixinClass.name; 30 String mixinName = mixinApplication.mixinClass.name;
31 superName = '$superName+$mixinName'; 31 superName = '$superName+$mixinName';
32 emitter.needsMixinSupport = true; 32 emitter.needsMixinSupport = true;
33 } 33 }
34 34
35 ClassBuilder builder = new ClassBuilder(classElement, namer); 35 ClassBuilder builder = new ClassBuilder(classElement, namer);
36 builder.superName = superName; 36 builder.superName = superName;
37 emitConstructorsForCSP(cls); 37 emitConstructorsForCSP(cls);
38 emitFields(cls, builder); 38 emitFields(cls, builder);
39 emitCheckedClassSetters(cls, builder); 39 emitCheckedClassSetters(cls, builder);
40 emitClassGettersSettersForCSP(cls, builder); 40 emitClassGettersSettersForCSP(cls, builder);
41 emitInstanceMembers(cls, builder); 41 emitInstanceMembers(cls, builder);
42 emitCallStubs(cls, builder); 42 emitCallStubs(cls, builder);
43 emitRuntimeTypeInformation(cls, builder); 43 emitRuntimeTypeInformation(cls, builder);
44 emitNativeInfo(cls, builder); 44 emitNativeInfo(cls, builder);
45 45
46 if (classElement == backend.closureClass) { 46 if (classElement == backend.closureClass) {
47 // We add a special getter here to allow for tearing off a closure from 47 // We add a special getter here to allow for tearing off a closure from
48 // itself. 48 // itself.
49 String name = namer.getMappedInstanceName(Compiler.CALL_OPERATOR_NAME);
50 jsAst.Fun function = js('function() { return this; }'); 49 jsAst.Fun function = js('function() { return this; }');
51 builder.addProperty(namer.getterNameFromAccessorName(name), function); 50 String name = namer.getterForPublicMember(Compiler.CALL_OPERATOR_NAME);
51 builder.addProperty(name, function);
52 } 52 }
53 53
54 emitTypeVariableReaders(classElement, builder); 54 emitTypeVariableReaders(classElement, builder);
55 55
56 emitClassBuilderWithReflectionData(cls, builder, enclosingBuilder); 56 emitClassBuilderWithReflectionData(cls, builder, enclosingBuilder);
57 } 57 }
58 /** 58 /**
59 * Emits the precompiled constructor when in CSP mode. 59 * Emits the precompiled constructor when in CSP mode.
60 */ 60 */
61 void emitConstructorsForCSP(Class cls) { 61 void emitConstructorsForCSP(Class cls) {
62 List<String> fieldNames = <String>[]; 62 List<String> fieldNames = <String>[];
63 63
64 if (!compiler.useContentSecurityPolicy) return; 64 if (!compiler.useContentSecurityPolicy) return;
65 65
66 if (!cls.onlyForRti && !cls.isNative) { 66 if (!cls.onlyForRti && !cls.isNative) {
67 fieldNames = cls.fields.map((Field field) => field.name).toList(); 67 fieldNames = cls.fields.map((Field field) => field.name).toList();
68 } 68 }
69 69
70 ClassElement classElement = cls.element; 70 ClassElement classElement = cls.element;
71 71
72 jsAst.Expression constructorAst = 72 jsAst.Expression constructorAst =
73 _stubGenerator.generateClassConstructor(classElement, fieldNames); 73 _stubGenerator.generateClassConstructor(classElement, fieldNames);
74 74
75 String constructorName = namer.getNameOfClass(classElement); 75 String constructorName = namer.className(classElement);
76 OutputUnit outputUnit = 76 OutputUnit outputUnit =
77 compiler.deferredLoadTask.outputUnitForElement(classElement); 77 compiler.deferredLoadTask.outputUnitForElement(classElement);
78 emitter.emitPrecompiledConstructor( 78 emitter.emitPrecompiledConstructor(
79 outputUnit, constructorName, constructorAst, fieldNames); 79 outputUnit, constructorName, constructorAst, fieldNames);
80 } 80 }
81 81
82 /// Returns `true` if fields added. 82 /// Returns `true` if fields added.
83 bool emitFields(FieldContainer container, 83 bool emitFields(FieldContainer container,
84 ClassBuilder builder, 84 ClassBuilder builder,
85 { bool classIsNative: false, 85 { bool classIsNative: false,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 assert(!classIsNative); 136 assert(!classIsNative);
137 } else { 137 } else {
138 // Emit (possibly renaming) field name so we can add accessors at 138 // Emit (possibly renaming) field name so we can add accessors at
139 // runtime. 139 // runtime.
140 if (name != accessorName) { 140 if (name != accessorName) {
141 fieldName = '$accessorName:$name'; 141 fieldName = '$accessorName:$name';
142 } 142 }
143 143
144 if (field.needsInterceptedGetter) { 144 if (field.needsInterceptedGetter) {
145 emitter.interceptorEmitter.interceptorInvocationNames.add( 145 emitter.interceptorEmitter.interceptorInvocationNames.add(
146 namer.getterName(fieldElement)); 146 namer.getterForElement(fieldElement));
147 } 147 }
148 // TODO(16168): The setter creator only looks at the getter-name. 148 // TODO(16168): The setter creator only looks at the getter-name.
149 // Even though the setter could avoid the interceptor convention we 149 // Even though the setter could avoid the interceptor convention we
150 // currently still need to add the additional argument. 150 // currently still need to add the additional argument.
151 if (field.needsInterceptedGetter || field.needsInterceptedSetter) { 151 if (field.needsInterceptedGetter || field.needsInterceptedSetter) {
152 emitter.interceptorEmitter.interceptorInvocationNames.add( 152 emitter.interceptorEmitter.interceptorInvocationNames.add(
153 namer.setterName(fieldElement)); 153 namer.setterForElement(fieldElement));
154 } 154 }
155 155
156 int code = field.getterFlags + (field.setterFlags << 2); 156 int code = field.getterFlags + (field.setterFlags << 2);
157 if (code == 0) { 157 if (code == 0) {
158 compiler.internalError(fieldElement, 158 compiler.internalError(fieldElement,
159 'Field code is 0 ($fieldElement).'); 159 'Field code is 0 ($fieldElement).');
160 } else { 160 } else {
161 fieldCode = FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]; 161 fieldCode = FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE];
162 } 162 }
163 } 163 }
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 DartType type = member.type; 487 DartType type = member.type;
488 return type.treatAsDynamic || (type.element == compiler.objectClass); 488 return type.treatAsDynamic || (type.element == compiler.objectClass);
489 } 489 }
490 490
491 void generateCheckedSetter(Element member, 491 void generateCheckedSetter(Element member,
492 String fieldName, 492 String fieldName,
493 String accessorName, 493 String accessorName,
494 ClassBuilder builder) { 494 ClassBuilder builder) {
495 jsAst.Expression code = backend.generatedCode[member]; 495 jsAst.Expression code = backend.generatedCode[member];
496 assert(code != null); 496 assert(code != null);
497 String setterName = namer.setterNameFromAccessorName(accessorName); 497 String setterName = namer.deriveSetterName(accessorName);
498 compiler.dumpInfoTask.registerElementAst(member, 498 compiler.dumpInfoTask.registerElementAst(member,
499 builder.addProperty(setterName, code)); 499 builder.addProperty(setterName, code));
500 generateReflectionDataForFieldGetterOrSetter( 500 generateReflectionDataForFieldGetterOrSetter(
501 member, setterName, builder, isGetter: false); 501 member, setterName, builder, isGetter: false);
502 } 502 }
503 503
504 void emitGetterForCSP(Element member, String fieldName, String accessorName, 504 void emitGetterForCSP(Element member, String fieldName, String accessorName,
505 ClassBuilder builder) { 505 ClassBuilder builder) {
506 jsAst.Expression function = 506 jsAst.Expression function =
507 _stubGenerator.generateGetter(member, fieldName); 507 _stubGenerator.generateGetter(member, fieldName);
508 508
509 String getterName = namer.getterNameFromAccessorName(accessorName); 509 String getterName = namer.deriveGetterName(accessorName);
510 ClassElement cls = member.enclosingClass; 510 ClassElement cls = member.enclosingClass;
511 String className = namer.getNameOfClass(cls); 511 String className = namer.className(cls);
512 OutputUnit outputUnit = 512 OutputUnit outputUnit =
513 compiler.deferredLoadTask.outputUnitForElement(member); 513 compiler.deferredLoadTask.outputUnitForElement(member);
514 emitter.cspPrecompiledFunctionFor(outputUnit).add( 514 emitter.cspPrecompiledFunctionFor(outputUnit).add(
515 js('#.prototype.# = #', [className, getterName, function])); 515 js('#.prototype.# = #', [className, getterName, function]));
516 if (backend.isAccessibleByReflection(member)) { 516 if (backend.isAccessibleByReflection(member)) {
517 emitter.cspPrecompiledFunctionFor(outputUnit).add( 517 emitter.cspPrecompiledFunctionFor(outputUnit).add(
518 js('#.prototype.#.${namer.reflectableField} = 1', 518 js('#.prototype.#.${namer.reflectableField} = 1',
519 [className, getterName])); 519 [className, getterName]));
520 } 520 }
521 } 521 }
522 522
523 void emitSetterForCSP(Element member, String fieldName, String accessorName, 523 void emitSetterForCSP(Element member, String fieldName, String accessorName,
524 ClassBuilder builder) { 524 ClassBuilder builder) {
525 jsAst.Expression function = 525 jsAst.Expression function =
526 _stubGenerator.generateSetter(member, fieldName); 526 _stubGenerator.generateSetter(member, fieldName);
527 527
528 String setterName = namer.setterNameFromAccessorName(accessorName); 528 String setterName = namer.deriveSetterName(accessorName);
529 ClassElement cls = member.enclosingClass; 529 ClassElement cls = member.enclosingClass;
530 String className = namer.getNameOfClass(cls); 530 String className = namer.className(cls);
531 OutputUnit outputUnit = 531 OutputUnit outputUnit =
532 compiler.deferredLoadTask.outputUnitForElement(member); 532 compiler.deferredLoadTask.outputUnitForElement(member);
533 emitter.cspPrecompiledFunctionFor(outputUnit).add( 533 emitter.cspPrecompiledFunctionFor(outputUnit).add(
534 js('#.prototype.# = #', [className, setterName, function])); 534 js('#.prototype.# = #', [className, setterName, function]));
535 if (backend.isAccessibleByReflection(member)) { 535 if (backend.isAccessibleByReflection(member)) {
536 emitter.cspPrecompiledFunctionFor(outputUnit).add( 536 emitter.cspPrecompiledFunctionFor(outputUnit).add(
537 js('#.prototype.#.${namer.reflectableField} = 1', 537 js('#.prototype.#.${namer.reflectableField} = 1',
538 [className, setterName])); 538 [className, setterName]));
539 } 539 }
540 } 540 }
(...skipping 22 matching lines...) Expand all
563 emitTypeVariableReader(cls, builder, parameter.element); 563 emitTypeVariableReader(cls, builder, parameter.element);
564 } 564 }
565 } 565 }
566 superclass = superclass.superclass; 566 superclass = superclass.superclass;
567 } 567 }
568 } 568 }
569 569
570 void emitTypeVariableReader(ClassElement cls, 570 void emitTypeVariableReader(ClassElement cls,
571 ClassBuilder builder, 571 ClassBuilder builder,
572 TypeVariableElement element) { 572 TypeVariableElement element) {
573 String name = namer.readTypeVariableName(element); 573 String name = namer.nameForReadTypeVariable(element);
574 int index = RuntimeTypes.getTypeVariableIndex(element); 574 int index = RuntimeTypes.getTypeVariableIndex(element);
575 jsAst.Expression computeTypeVariable; 575 jsAst.Expression computeTypeVariable;
576 576
577 Substitution substitution = 577 Substitution substitution =
578 backend.rti.computeSubstitution( 578 backend.rti.computeSubstitution(
579 cls, element.typeDeclaration, alwaysGenerateFunction: true); 579 cls, element.typeDeclaration, alwaysGenerateFunction: true);
580 if (substitution != null) { 580 if (substitution != null) {
581 computeTypeVariable = 581 computeTypeVariable =
582 js(r'#.apply(null, this.$builtinTypeInfo)', 582 js(r'#.apply(null, this.$builtinTypeInfo)',
583 substitution.getCodeForVariable(index, backend.rti)); 583 substitution.getCodeForVariable(index, backend.rti));
584 } else { 584 } else {
585 // TODO(ahe): These can be generated dynamically. 585 // TODO(ahe): These can be generated dynamically.
586 computeTypeVariable = 586 computeTypeVariable =
587 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]', 587 js(r'this.$builtinTypeInfo && this.$builtinTypeInfo[#]',
588 js.number(index)); 588 js.number(index));
589 } 589 }
590 jsAst.Expression convertRtiToRuntimeType = emitter 590 jsAst.Expression convertRtiToRuntimeType = emitter
591 .staticFunctionAccess(backend.findHelper('convertRtiToRuntimeType')); 591 .staticFunctionAccess(backend.findHelper('convertRtiToRuntimeType'));
592 compiler.dumpInfoTask.registerElementAst(element, 592 compiler.dumpInfoTask.registerElementAst(element,
593 builder.addProperty(name, 593 builder.addProperty(name,
594 js('function () { return #(#) }', 594 js('function () { return #(#) }',
595 [convertRtiToRuntimeType, computeTypeVariable]))); 595 [convertRtiToRuntimeType, computeTypeVariable])));
596 } 596 }
597 } 597 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698