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

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

Issue 9315028: Support default values for optional parameters. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 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
« no previous file with comments | « no previous file | dart/frog/leg/compiler.dart » ('j') | dart/frog/leg/compiler.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,
7 * initializations of global and static fields. 7 * initializations of global and static fields, and default values of
8 * optional parameters.
8 */ 9 */
9 class CompileTimeConstantHandler extends CompilerTask { 10 class CompileTimeConstantHandler extends CompilerTask {
10 // Contains the initial value of fields. Must contain all static and global 11 // Contains the initial value of fields. Must contain all static and global
11 // initializations of used fields. May contain caches for instance fields. 12 // initializations of used fields. May contain caches for instance fields.
12 final Map<VariableElement, Dynamic> initialFieldValues; 13 final Map<VariableElement, Dynamic> initialVariableValues;
13 14
14 CompileTimeConstantHandler(Compiler compiler) 15 CompileTimeConstantHandler(Compiler compiler)
15 : initialFieldValues = new Map<VariableElement, Dynamic>(), 16 : initialVariableValues = new Map<VariableElement, Dynamic>(),
16 super(compiler); 17 super(compiler);
17 String get name() => 'CompileTimeConstantHandler'; 18 String get name() => 'CompileTimeConstantHandler';
18 19
19 /** 20 /**
20 * Compiles the initial value of the given field and stores it in an internal 21 * Compiles the initial value of the given field and stores it in an internal
21 * map. 22 * map.
22 * 23 *
23 * [WorkItem] must contain a [VariableElement] refering to a global or 24 * [WorkItem] must contain a [VariableElement] refering to a global or
24 * static field. 25 * static field.
25 */ 26 */
26 void compileWorkItem(WorkItem work) { 27 void compileWorkItem(WorkItem work) {
27 assert(work.element.kind == ElementKind.FIELD); 28 assert(work.element.kind == ElementKind.FIELD
29 || work.element.kind == ElementKind.PARAMETER);
28 VariableElement element = work.element; 30 VariableElement element = work.element;
29 // Shortcut if it has already been compiled. 31 // Shortcut if it has already been compiled.
30 if (initialFieldValues.containsKey(element)) return; 32 if (initialVariableValues.containsKey(element)) return;
31 compileFieldWithDefinitions(element, work.resolutionTree); 33 compileVariableWithDefinitions(element, work.resolutionTree);
32 } 34 }
33 35
34 compileField(VariableElement element) { 36 compileVariable(VariableElement element) {
35 if (initialFieldValues.containsKey(element)) { 37 if (initialVariableValues.containsKey(element)) {
36 return initialFieldValues[element]; 38 return initialVariableValues[element];
37 } 39 }
38 // TODO(floitsch): keep track of currently compiling elements so that we 40 // 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; 41 // don't end up in an infinite loop: final x = y; final y = x;
40 TreeElements definitions = compiler.analyzeElement(element); 42 TreeElements definitions = compiler.analyzeElement(element);
41 return compileFieldWithDefinitions(element, definitions); 43 return compileVariableWithDefinitions(element, definitions);
42 } 44 }
43 45
44 compileFieldWithDefinitions(VariableElement element, 46 compileVariableWithDefinitions(VariableElement element,
45 TreeElements definitions) { 47 TreeElements definitions) {
floitsch 2012/02/01 14:35:39 indent.
ngeoffray 2012/02/01 15:54:59 Done.
46 return measure(() { 48 return measure(() {
47 Node node = element.parseNode(compiler); 49 Node node = element.parseNode(compiler);
48 assert(node !== null); 50 assert(node !== null);
49 SendSet assignment = node.asSendSet(); 51 SendSet assignment = node.asSendSet();
50 var value; 52 var value;
51 if (assignment === null) { 53 if (assignment === null) {
52 // No initial value. 54 // No initial value.
53 value = null; 55 value = null;
54 } else { 56 } else {
55 Node right = assignment.arguments.head; 57 Node right = assignment.arguments.head;
56 CompileTimeConstantEvaluator evaluator = 58 CompileTimeConstantEvaluator evaluator =
57 new CompileTimeConstantEvaluator(this, definitions, compiler); 59 new CompileTimeConstantEvaluator(this, definitions, compiler);
58 value = evaluator.evaluate(right); 60 value = evaluator.evaluate(right);
59 } 61 }
60 initialFieldValues[element] = value; 62 initialVariableValues[element] = value;
61 return value; 63 return value;
62 }); 64 });
63 } 65 }
64 66
65 /** 67 /**
66 * Returns a [List] of static non final fields that need to be initialized. 68 * Returns a [List] of static non final fields that need to be initialized.
67 * The list must be evaluated in order since the fields might depend on each 69 * The list must be evaluated in order since the fields might depend on each
68 * other. 70 * other.
69 */ 71 */
70 List<VariableElement> getStaticNonFinalFieldsForEmission() { 72 List<VariableElement> getStaticNonFinalFieldsForEmission() {
71 return initialFieldValues.getKeys().filter((element) { 73 return initialVariableValues.getKeys().filter((element) {
72 return !element.isInstanceMember() && !element.modifiers.isFinal(); 74 return element.kind == ElementKind.FIELD
75 && !element.isInstanceMember()
76 && !element.modifiers.isFinal();
73 }); 77 });
74 } 78 }
75 79
76 /** 80 /**
77 * Returns a [List] of static final fields that need to be initialized. The 81 * Returns a [List] of static final fields that need to be initialized. The
78 * list must be evaluated in order since the fields might depend on each 82 * list must be evaluated in order since the fields might depend on each
79 * other. 83 * other.
80 */ 84 */
81 List<VariableElement> getStaticFinalFieldsForEmission() { 85 List<VariableElement> getStaticFinalFieldsForEmission() {
82 return initialFieldValues.getKeys().filter((element) { 86 return initialVariableValues.getKeys().filter((element) {
83 return !element.isInstanceMember() && element.modifiers.isFinal(); 87 return element.kind == ElementKind.FIELD
88 && !element.isInstanceMember()
89 && element.modifiers.isFinal();
84 }); 90 });
85 } 91 }
86 92
87 void emitJsCodeForField(VariableElement element, StringBuffer buffer) { 93 String getJsCodeForVariable(VariableElement element) {
88 var value = initialFieldValues[element]; 94 var value = initialVariableValues[element];
89 if (value === null) { 95 if (value === null) return "(void 0)";
90 buffer.add("(void 0)"); 96 if (value is num) return "$value";
91 } else if (value is num) { 97 if (value === true) return "true";
92 buffer.add("$value"); 98 if (value === false) return "false";
93 } else if (value === true) { 99
94 buffer.add("true"); 100 // TODO(floitsch): support more values.
95 } else if (value === false) { 101 compiler.unimplemented("CompileTimeConstantHandler.getJsCodeForVariable",
96 buffer.add("false"); 102 node: element.parseNode(compiler));
97 } else {
98 // TODO(floitsch): support more values.
99 compiler.unimplemented("CompileTimeConstantHandler.emitJsCodeForField",
100 node: element.parseNode(compiler));
101 }
102 } 103 }
103 } 104 }
104 105
105 class CompileTimeConstantEvaluator extends AbstractVisitor { 106 class CompileTimeConstantEvaluator extends AbstractVisitor {
106 final CompileTimeConstantHandler constantHandler; 107 final CompileTimeConstantHandler constantHandler;
107 final TreeElements definitions; 108 final TreeElements definitions;
108 final Compiler compiler; 109 final Compiler compiler;
109 110
110 CompileTimeConstantEvaluator(this.constantHandler, 111 CompileTimeConstantEvaluator(this.constantHandler,
111 this.definitions, 112 this.definitions,
(...skipping 12 matching lines...) Expand all
124 } 125 }
125 126
126 visitSend(Send send) { 127 visitSend(Send send) {
127 Element element = definitions[send]; 128 Element element = definitions[send];
128 if (element !== null && element.kind == ElementKind.FIELD) { 129 if (element !== null && element.kind == ElementKind.FIELD) {
129 if (element.isInstanceMember() || 130 if (element.isInstanceMember() ||
130 element.modifiers === null || 131 element.modifiers === null ||
131 !element.modifiers.isFinal()) { 132 !element.modifiers.isFinal()) {
132 error(element); 133 error(element);
133 } 134 }
134 return constantHandler.compileField(element); 135 return constantHandler.compileVariable(element);
135 } 136 }
136 return super.visitSend(send); 137 return super.visitSend(send);
137 } 138 }
138 139
139 error(Element element) { 140 error(Element element) {
140 // TODO(floitsch): get the list of constants that are currently compiled 141 // TODO(floitsch): get the list of constants that are currently compiled
141 // and present some kind of stack-trace. 142 // and present some kind of stack-trace.
142 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; 143 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
143 List arguments = [element.name]; 144 List arguments = [element.name];
144 Node node = element.parseNode(compiler); 145 Node node = element.parseNode(compiler);
145 compiler.reportError(node, new CompileTimeConstantError(kind, arguments)); 146 compiler.reportError(node, new CompileTimeConstantError(kind, arguments));
146 } 147 }
147 } 148 }
OLDNEW
« no previous file with comments | « no previous file | dart/frog/leg/compiler.dart » ('j') | dart/frog/leg/compiler.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698