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

Side by Side Diff: pkg/compiler/lib/src/constants/expressions.dart

Issue 1282463002: Reorganize constants/* libraries. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js.constants.expressions; 5 library dart2js.constants.expressions;
6 6
7 import '../constants/constant_system.dart'; 7 import '../constants/constant_system.dart';
8 import '../core_types.dart'; 8 import '../core_types.dart';
9 import '../dart2jslib.dart' show assertDebugMode, Compiler; 9 import '../dart2jslib.dart' show assertDebugMode;
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../elements/elements.dart' show 11 import '../elements/elements.dart' show
12 ConstructorElement, 12 ConstructorElement,
13 Element, 13 Element,
14 FieldElement, 14 FieldElement,
15 FunctionElement, 15 FunctionElement,
16 PrefixElement, 16 PrefixElement,
17 VariableElement; 17 VariableElement;
18 import '../resolution/operators.dart'; 18 import '../resolution/operators.dart';
19 import '../tree/tree.dart' show DartString; 19 import '../tree/tree.dart' show DartString;
20 import '../universe/universe.dart' show CallStructure; 20 import '../universe/universe.dart' show CallStructure;
21 import '../util/util.dart'; 21 import 'evaluation.dart';
22 import 'values.dart'; 22 import 'values.dart';
23 23
24 enum ConstantExpressionKind { 24 enum ConstantExpressionKind {
25 BINARY, 25 BINARY,
26 BOOL, 26 BOOL,
27 BOOL_FROM_ENVIRONMENT, 27 BOOL_FROM_ENVIRONMENT,
28 CONCATENATE, 28 CONCATENATE,
29 CONDITIONAL, 29 CONDITIONAL,
30 CONSTRUCTED, 30 CONSTRUCTED,
31 DEFERRED, 31 DEFERRED,
(...skipping 12 matching lines...) Expand all
44 SYMBOL, 44 SYMBOL,
45 SYNTHETIC, 45 SYNTHETIC,
46 TYPE, 46 TYPE,
47 UNARY, 47 UNARY,
48 VARIABLE, 48 VARIABLE,
49 49
50 POSITIONAL_REFERENCE, 50 POSITIONAL_REFERENCE,
51 NAMED_REFERENCE, 51 NAMED_REFERENCE,
52 } 52 }
53 53
54 /// Environment used for evaluating constant expressions.
55 abstract class Environment {
56 // TODO(johnniwinther): Replace this with [CoreTypes] and maybe [Backend].
57 Compiler get compiler;
58
59 /// Read environments string passed in using the '-Dname=value' option.
60 String readFromEnvironment(String name);
61 }
62
63 /// The normalized arguments passed to a const constructor computed from the
64 /// actual [arguments] and the [defaultValues] of the called construrctor.
65 class NormalizedArguments {
66 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues;
67 final CallStructure callStructure;
68 final List<ConstantExpression> arguments;
69
70 NormalizedArguments(this.defaultValues, this.callStructure, this.arguments);
71
72 /// Returns the normalized named argument [name].
73 ConstantExpression getNamedArgument(String name) {
74 int index = callStructure.namedArguments.indexOf(name);
75 if (index == -1) {
76 // The named argument is not provided.
77 return defaultValues[name];
78 }
79 return arguments[index + callStructure.positionalArgumentCount];
80 }
81
82 /// Returns the normalized [index]th positional argument.
83 ConstantExpression getPositionalArgument(int index) {
84 if (index >= callStructure.positionalArgumentCount) {
85 // The positional argument is not provided.
86 return defaultValues[index];
87 }
88 return arguments[index];
89 }
90 }
91
92 enum ConstantConstructorKind {
93 GENERATIVE,
94 REDIRECTING_GENERATIVE,
95 REDIRECTING_FACTORY,
96 }
97
98 /// Definition of a constant constructor.
99 abstract class ConstantConstructor {
100 ConstantConstructorKind get kind;
101
102 /// Computes the type of the instance created in a const constructor
103 /// invocation with type [newType].
104 InterfaceType computeInstanceType(InterfaceType newType);
105
106 /// Computes the constant expressions of the fields of the created instance
107 /// in a const constructor invocation with [arguments].
108 Map<FieldElement, ConstantExpression> computeInstanceFields(
109 List<ConstantExpression> arguments,
110 CallStructure callStructure);
111
112 accept(ConstantConstructorVisitor visitor, arg);
113 }
114
115 abstract class ConstantConstructorVisitor<R, A> {
116 const ConstantConstructorVisitor();
117
118 R visit(ConstantConstructor constantConstructor, A context) {
119 return constantConstructor.accept(this, context);
120 }
121
122 R visitGenerative(GenerativeConstantConstructor constructor, A arg);
123 R visitRedirectingGenerative(
124 RedirectingGenerativeConstantConstructor constructor, A arg);
125 R visitRedirectingFactory(
126 RedirectingFactoryConstantConstructor constructor, A arg);
127 }
128
129 /// A generative constant constructor.
130 class GenerativeConstantConstructor implements ConstantConstructor{
131 final InterfaceType type;
132 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues;
133 final Map<FieldElement, ConstantExpression> fieldMap;
134 final ConstructedConstantExpression superConstructorInvocation;
135
136 GenerativeConstantConstructor(
137 this.type,
138 this.defaultValues,
139 this.fieldMap,
140 this.superConstructorInvocation);
141
142 ConstantConstructorKind get kind => ConstantConstructorKind.GENERATIVE;
143
144 InterfaceType computeInstanceType(InterfaceType newType) {
145 return type.substByContext(newType);
146 }
147
148 Map<FieldElement, ConstantExpression> computeInstanceFields(
149 List<ConstantExpression> arguments,
150 CallStructure callStructure) {
151 NormalizedArguments args = new NormalizedArguments(
152 defaultValues, callStructure, arguments);
153 Map<FieldElement, ConstantExpression> appliedFieldMap =
154 applyFields(args, superConstructorInvocation);
155 fieldMap.forEach((FieldElement field, ConstantExpression constant) {
156 appliedFieldMap[field] = constant.apply(args);
157 });
158 return appliedFieldMap;
159 }
160
161 accept(ConstantConstructorVisitor visitor, arg) {
162 return visitor.visitGenerative(this, arg);
163 }
164
165 int get hashCode {
166 int hash = Hashing.objectHash(type);
167 hash = Hashing.mapHash(defaultValues, hash);
168 hash = Hashing.mapHash(fieldMap, hash);
169 return Hashing.objectHash(superConstructorInvocation, hash);
170 }
171
172 bool operator ==(other) {
173 if (identical(this, other)) return true;
174 if (other is! GenerativeConstantConstructor) return false;
175 return
176 type == other.type &&
177 superConstructorInvocation == other.superConstructorInvocation &&
178 mapEquals(defaultValues, other.defaultValues) &&
179 mapEquals(fieldMap, other.fieldMap);
180 }
181
182 String toString() {
183 StringBuffer sb = new StringBuffer();
184 sb.write("{'type': $type");
185 defaultValues.forEach((key, ConstantExpression expression) {
186 sb.write(",\n 'default:${key}': ${expression.getText()}");
187 });
188 fieldMap.forEach((FieldElement field, ConstantExpression expression) {
189 sb.write(",\n 'field:${field}': ${expression.getText()}");
190 });
191 if (superConstructorInvocation != null) {
192 sb.write(",\n 'constructor: ${superConstructorInvocation.getText()}");
193 }
194 sb.write("}");
195 return sb.toString();
196 }
197
198 static bool mapEquals(Map map1, Map map2) {
199 if (map1.length != map1.length) return false;
200 for (var key in map1.keys) {
201 if (map1[key] != map2[key]) {
202 return false;
203 }
204 }
205 return true;
206 }
207
208 /// Creates the field-to-constant map from applying [args] to
209 /// [constructorInvocation]. If [constructorInvocation] is `null`, an empty
210 /// map is created.
211 static Map<FieldElement, ConstantExpression> applyFields(
212 NormalizedArguments args,
213 ConstructedConstantExpression constructorInvocation) {
214 Map<FieldElement, ConstantExpression> appliedFieldMap =
215 <FieldElement, ConstantExpression>{};
216 if (constructorInvocation != null) {
217 Map<FieldElement, ConstantExpression> fieldMap =
218 constructorInvocation.computeInstanceFields();
219 fieldMap.forEach((FieldElement field, ConstantExpression constant) {
220 appliedFieldMap[field] = constant.apply(args);
221 });
222 }
223 return appliedFieldMap;
224 }
225 }
226
227 /// A redirecting generative constant constructor.
228 class RedirectingGenerativeConstantConstructor implements ConstantConstructor {
229 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues;
230 final ConstructedConstantExpression thisConstructorInvocation;
231
232 RedirectingGenerativeConstantConstructor(
233 this.defaultValues,
234 this.thisConstructorInvocation);
235
236 ConstantConstructorKind get kind {
237 return ConstantConstructorKind.REDIRECTING_GENERATIVE;
238 }
239
240 InterfaceType computeInstanceType(InterfaceType newType) {
241 return thisConstructorInvocation.computeInstanceType()
242 .substByContext(newType);
243 }
244
245 Map<FieldElement, ConstantExpression> computeInstanceFields(
246 List<ConstantExpression> arguments,
247 CallStructure callStructure) {
248 NormalizedArguments args =
249 new NormalizedArguments(defaultValues, callStructure, arguments);
250 Map<FieldElement, ConstantExpression> appliedFieldMap =
251 GenerativeConstantConstructor.applyFields(
252 args, thisConstructorInvocation);
253 return appliedFieldMap;
254 }
255
256 accept(ConstantConstructorVisitor visitor, arg) {
257 return visitor.visitRedirectingGenerative(this, arg);
258 }
259
260 int get hashCode {
261 int hash = Hashing.objectHash(thisConstructorInvocation);
262 return Hashing.mapHash(defaultValues, hash);
263 }
264
265 bool operator ==(other) {
266 if (identical(this, other)) return true;
267 if (other is! RedirectingGenerativeConstantConstructor) return false;
268 return
269 thisConstructorInvocation == other.thisConstructorInvocation &&
270 GenerativeConstantConstructor.mapEquals(
271 defaultValues, other.defaultValues);
272 }
273
274 String toString() {
275 StringBuffer sb = new StringBuffer();
276 sb.write("{'type': ${thisConstructorInvocation.type}");
277 defaultValues.forEach((key, ConstantExpression expression) {
278 sb.write(",\n 'default:${key}': ${expression.getText()}");
279 });
280 sb.write(",\n 'constructor': ${thisConstructorInvocation.getText()}");
281 sb.write("}");
282 return sb.toString();
283 }
284 }
285
286 /// A redirecting factory constant constructor.
287 class RedirectingFactoryConstantConstructor implements ConstantConstructor {
288 final ConstructedConstantExpression targetConstructorInvocation;
289
290 RedirectingFactoryConstantConstructor(this.targetConstructorInvocation);
291
292 ConstantConstructorKind get kind {
293 return ConstantConstructorKind.REDIRECTING_FACTORY;
294 }
295
296 InterfaceType computeInstanceType(InterfaceType newType) {
297 return targetConstructorInvocation.computeInstanceType()
298 .substByContext(newType);
299 }
300
301 Map<FieldElement, ConstantExpression> computeInstanceFields(
302 List<ConstantExpression> arguments,
303 CallStructure callStructure) {
304 ConstantConstructor constantConstructor =
305 targetConstructorInvocation.target.constantConstructor;
306 return constantConstructor.computeInstanceFields(arguments, callStructure);
307 }
308
309 accept(ConstantConstructorVisitor visitor, arg) {
310 return visitor.visitRedirectingFactory(this, arg);
311 }
312
313 int get hashCode {
314 return Hashing.objectHash(targetConstructorInvocation);
315 }
316
317 bool operator ==(other) {
318 if (identical(this, other)) return true;
319 if (other is! RedirectingFactoryConstantConstructor) return false;
320 return targetConstructorInvocation == other.targetConstructorInvocation;
321 }
322
323 String toString() {
324 StringBuffer sb = new StringBuffer();
325 sb.write("{");
326 sb.write("'constructor': ${targetConstructorInvocation.getText()}");
327 sb.write("}");
328 return sb.toString();
329 }
330 }
331
332 /// An expression that is a compile-time constant. 54 /// An expression that is a compile-time constant.
333 /// 55 ///
334 /// Whereas [ConstantValue] represent a compile-time value, a 56 /// Whereas [ConstantValue] represent a compile-time value, a
335 /// [ConstantExpression] represents an expression for creating a constant. 57 /// [ConstantExpression] represents an expression for creating a constant.
336 /// 58 ///
337 /// There is no one-to-one mapping between [ConstantExpression] and 59 /// There is no one-to-one mapping between [ConstantExpression] and
338 /// [ConstantValue], because different expressions can denote the same constant. 60 /// [ConstantValue], because different expressions can denote the same constant.
339 /// For instance, multiple `const` constructors may be used to create the same 61 /// For instance, multiple `const` constructors may be used to create the same
340 /// object, and different `const` variables may hold the same value. 62 /// object, and different `const` variables may hold the same value.
341 abstract class ConstantExpression { 63 abstract class ConstantExpression {
(...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 visit(exp.name); 1597 visit(exp.name);
1876 if (exp.defaultValue != null) { 1598 if (exp.defaultValue != null) {
1877 sb.write(', defaultValue: '); 1599 sb.write(', defaultValue: ');
1878 visit(exp.defaultValue); 1600 visit(exp.defaultValue);
1879 } 1601 }
1880 sb.write(')'); 1602 sb.write(')');
1881 } 1603 }
1882 1604
1883 String toString() => sb.toString(); 1605 String toString() => sb.toString();
1884 } 1606 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/constants/evaluation.dart ('k') | pkg/compiler/lib/src/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698