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

Side by Side Diff: frog/leg/compile_time_constants.dart

Issue 9211005: Support static/global field initializations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments and add start of error-handling. Created 8 years, 11 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
« no previous file with comments | « no previous file | frog/leg/resolver.dart » ('j') | frog/leg/warnings.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * The [CompileTimeConstantHandler] keeps track of compile-time constants, and 6 * The [CompileTimeConstantHandler] keeps track of compile-time constants, and
7 * initializations of global and static fields. 7 * initializations of global and static fields.
8 */ 8 */
9 class CompileTimeConstantHandler extends CompilerTask { 9 class CompileTimeConstantHandler extends CompilerTask {
10 // Contains the initial value of fields. Must contain all static and global 10 // Contains the initial value of fields. Must contain all static and global
(...skipping 17 matching lines...) Expand all
28 VariableElement element = work.element; 28 VariableElement element = work.element;
29 // Shortcut if it has already been compiled. 29 // Shortcut if it has already been compiled.
30 if (initialFieldValues.containsKey(element)) return; 30 if (initialFieldValues.containsKey(element)) return;
31 compileFieldWithDefinitions(element, work.resolutionTree); 31 compileFieldWithDefinitions(element, work.resolutionTree);
32 } 32 }
33 33
34 compileField(VariableElement element) { 34 compileField(VariableElement element) {
35 if (initialFieldValues.containsKey(element)) { 35 if (initialFieldValues.containsKey(element)) {
36 return initialFieldValues[element]; 36 return initialFieldValues[element];
37 } 37 }
38 // TODO(floitsch): keep track of currently compiling elements so that we
39 // don't end up in an infinite loop: final x = y; final y = x;
38 TreeElements definitions = compiler.analyzeElement(element); 40 TreeElements definitions = compiler.analyzeElement(element);
39 return compileFieldWithDefinitions(element, definitions); 41 return compileFieldWithDefinitions(element, definitions);
40 } 42 }
41 43
42 compileFieldWithDefinitions(VariableElement element, 44 compileFieldWithDefinitions(VariableElement element,
43 TreeElements definitions) { 45 TreeElements definitions) {
44 return measure(() { 46 return measure(() {
45 Node node = element.parseNode(compiler, compiler); 47 Node node = element.parseNode(compiler, compiler);
46 assert(node !== null); 48 assert(node !== null);
47 SendSet assignment = node.asSendSet(); 49 SendSet assignment = node.asSendSet();
48 var value; 50 var value;
49 if (assignment === null) { 51 if (assignment === null) {
50 // No initial value. 52 // No initial value.
51 value = null; 53 value = null;
52 } else { 54 } else {
53 compiler.unimplemented("CTC for static initialized fields.", 55 Node right = node.arguments.head;
54 node: node); 56 CompileTimeConstantEvaluator evaluator =
57 new CompileTimeConstantEvaluator(this, definitions, compiler);
58 value = evaluator.evaluate(right);
55 } 59 }
56 initialFieldValues[element] = value; 60 initialFieldValues[element] = value;
57 return value; 61 return value;
58 }); 62 });
59 } 63 }
60 64
61 /** 65 /**
62 * Returns a [List] of static non final fields that need to be initialized. 66 * Returns a [List] of static non final fields that need to be initialized.
63 * The list must be evaluated in order since the fields might depend on each 67 * The list must be evaluated in order since the fields might depend on each
64 * other. 68 * other.
(...skipping 10 matching lines...) Expand all
75 * other. 79 * other.
76 */ 80 */
77 List<VariableElement> getStaticFinalFieldsForEmission() { 81 List<VariableElement> getStaticFinalFieldsForEmission() {
78 return initialFieldValues.getKeys().filter((element) { 82 return initialFieldValues.getKeys().filter((element) {
79 return !element.isInstanceMember() && element.modifiers.isFinal(); 83 return !element.isInstanceMember() && element.modifiers.isFinal();
80 }); 84 });
81 } 85 }
82 86
83 void emitJsCodeForField(VariableElement element, StringBuffer buffer) { 87 void emitJsCodeForField(VariableElement element, StringBuffer buffer) {
84 var value = initialFieldValues[element]; 88 var value = initialFieldValues[element];
85 // TODO(floitsch): support more values. 89 if (value === null) {
86 assert(value === null); 90 buffer.add("(void 0)");
87 buffer.add("(void 0)"); 91 } else if (value === true) {
92 buffer.add("true");
93 } else if (value === false) {
94 buffer.add("false");
95 } else if (value is num) {
96 buffer.add("$value");
97 } else {
98 // TODO(floitsch): support more values.
99 compiler.unimplemented("CompileTimeConstantHandler.emitJsCodeForField",
100 node: element.parseNode(compiler, compiler));
101 }
88 } 102 }
89 } 103 }
104
105 class CompileTimeConstantEvaluator extends AbstractVisitor {
106 final CompileTimeConstantHandler constantHandler;
107 final TreeElements definitions;
108 final Compiler compiler;
109
110 CompileTimeConstantEvaluator(this.constantHandler,
111 this.definitions,
112 this.compiler);
113
114 evaluate(Node node) {
115 return node.accept(this);
116 }
117
118 visitNode(Node node) {
119 compiler.unimplemented("CompileTimeConstantEvaluator", node: node);
120 }
121
122 visitLiteral(Literal literal) {
123 return literal.value;
124 }
125
126 visitSend(Send send) {
ngeoffray 2012/01/16 15:22:35 Maybe add a helper in Elements: Elements.isNonInst
floitsch 2012/01/18 12:56:19 Since I want to check for non-final accesses keepi
127 Element element = definitions[send];
128 if (element !== null &&
129 element.kind == ElementKind.FIELD) {
130 if (element.isInstanceMember() ||
131 element.modifiers === null ||
132 !element.modifiers.isFinal()) {
133 error(element);
ngeoffray 2012/01/16 15:22:35 I believe this can be tested in the resolver.
floitsch 2012/01/18 12:56:19 this one yes, but the resolver would need a state.
134 }
135 return constantHandler.compileField(element);
136 }
137 return super.visitSend(send);
138 }
139
140 error(Element element) {
141 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
142 List arguments = [element.name];
143 Node node = element.parseNode(compiler, compiler);
144 compiler.reportError(node, new CompileTimeConstantError(kind, arguments));
145 }
146 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/resolver.dart » ('j') | frog/leg/warnings.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698