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

Side by Side Diff: pkg/compiler/lib/src/compile_time_constants.dart

Issue 1559233002: WIP: Compute constant expressions in resolution. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/constant_system_dart.dart » ('j') | no next file with comments »
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 library dart2js.compile_time_constant_evaluator; 5 library dart2js.compile_time_constant_evaluator;
6 6
7 import 'common.dart'; 7 import 'common.dart';
8 import 'common/resolution.dart' show 8 import 'common/resolution.dart' show
9 Resolution; 9 Resolution;
10 import 'common/tasks.dart' show 10 import 'common/tasks.dart' show
11 CompilerTask; 11 CompilerTask;
12 import 'compiler.dart' show 12 import 'compiler.dart' show
13 Compiler; 13 Compiler;
14 import 'constant_system_dart.dart'; 14 import 'constant_system_dart.dart';
15 import 'constants/constant_system.dart'; 15 import 'constants/constant_system.dart';
16 import 'constants/constructors.dart';
16 import 'constants/evaluation.dart'; 17 import 'constants/evaluation.dart';
17 import 'constants/expressions.dart'; 18 import 'constants/expressions.dart';
18 import 'constants/values.dart'; 19 import 'constants/values.dart';
20 import 'core_types.dart';
19 import 'dart_types.dart'; 21 import 'dart_types.dart';
20 import 'elements/elements.dart'; 22 import 'elements/elements.dart';
21 import 'elements/modelx.dart' show 23 import 'elements/modelx.dart' show
22 FunctionElementX; 24 FunctionElementX;
25 import 'enqueue.dart' show
26 WorldImpact;
23 import 'resolution/tree_elements.dart' show 27 import 'resolution/tree_elements.dart' show
24 TreeElements; 28 TreeElements;
25 import 'resolution/operators.dart'; 29 import 'resolution/operators.dart';
26 import 'tree/tree.dart'; 30 import 'tree/tree.dart';
27 import 'util/util.dart' show 31 import 'util/util.dart' show
28 Link; 32 Link;
29 import 'universe/call_structure.dart' show 33 import 'universe/call_structure.dart' show
30 CallStructure; 34 CallStructure;
31 35
32 /// A [ConstantEnvironment] provides access for constants compiled for variable 36 /// A [ConstantEnvironment] provides access for constants compiled for variable
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 /// Depending on implementation, the constant compiler might also compute 88 /// Depending on implementation, the constant compiler might also compute
85 /// the compile-time constant for the backend interpretation of constants. 89 /// the compile-time constant for the backend interpretation of constants.
86 /// 90 ///
87 /// The returned constant is always of the frontend interpretation. 91 /// The returned constant is always of the frontend interpretation.
88 ConstantExpression compileMetadata(MetadataAnnotation metadata, 92 ConstantExpression compileMetadata(MetadataAnnotation metadata,
89 Node node, 93 Node node,
90 TreeElements elements); 94 TreeElements elements);
91 95
92 /// Evaluates [constant] and caches the result. 96 /// Evaluates [constant] and caches the result.
93 // TODO(johnniwinther): Remove when all constants are evaluated. 97 // TODO(johnniwinther): Remove when all constants are evaluated.
94 void evaluate(ConstantExpression constant); 98 void evaluate(Spannable spannable, ConstantExpression constant);
95 } 99 }
96 100
97 /// A [BackendConstantEnvironment] provides access to constants needed for 101 /// A [BackendConstantEnvironment] provides access to constants needed for
98 /// backend implementation. 102 /// backend implementation.
99 abstract class BackendConstantEnvironment extends ConstantEnvironment { 103 abstract class BackendConstantEnvironment extends ConstantEnvironment {
100 /// Returns the compile-time constant value associated with [node]. 104 /// Returns the compile-time constant value associated with [node].
101 /// 105 ///
102 /// Depending on implementation, the constant might be stored in [elements]. 106 /// Depending on implementation, the constant might be stored in [elements].
103 ConstantValue getConstantValueForNode(Node node, TreeElements elements); 107 ConstantValue getConstantValueForNode(Node node, TreeElements elements);
104 108
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 @override 172 @override
169 ConstantExpression getConstantForVariable(VariableElement element) { 173 ConstantExpression getConstantForVariable(VariableElement element) {
170 return initialVariableValues[element.declaration]; 174 return initialVariableValues[element.declaration];
171 } 175 }
172 176
173 ConstantExpression compileConstant(VariableElement element) { 177 ConstantExpression compileConstant(VariableElement element) {
174 return internalCompileVariable(element, true, true); 178 return internalCompileVariable(element, true, true);
175 } 179 }
176 180
177 @override 181 @override
178 void evaluate(ConstantExpression constant) { 182 void evaluate(Spannable spannable, ConstantExpression constant) {
179 constantValueMap.putIfAbsent(constant, () { 183 constantValueMap.putIfAbsent(constant, () {
180 return constant.evaluate( 184 return constant.evaluate(
181 new _CompilerEnvironment(compiler), 185 new CompilerEnvironment(compiler, spannable),
182 constantSystem); 186 constantSystem);
183 }); 187 });
184 } 188 }
185 189
186 ConstantExpression compileVariable(VariableElement element) { 190 ConstantExpression compileVariable(VariableElement element) {
187 return internalCompileVariable(element, false, true); 191 return internalCompileVariable(element, false, true);
188 } 192 }
189 193
190 /// Compile [element] into a constant expression. If [isConst] is true, 194 /// Compile [element] into a constant expression. If [isConst] is true,
191 /// then [element] is a constant variable. If [checkType] is true, then 195 /// then [element] is a constant variable. If [checkType] is true, then
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 return expression; 287 return expression;
284 } 288 }
285 289
286 void cacheConstantValue(ConstantExpression expression, ConstantValue value) { 290 void cacheConstantValue(ConstantExpression expression, ConstantValue value) {
287 constantValueMap[expression] = value; 291 constantValueMap[expression] = value;
288 } 292 }
289 293
290 ConstantExpression compileNodeWithDefinitions( 294 ConstantExpression compileNodeWithDefinitions(
291 Node node, TreeElements definitions, {bool isConst: true}) { 295 Node node, TreeElements definitions, {bool isConst: true}) {
292 assert(node != null); 296 assert(node != null);
297 ConstantExpression constantExpression = definitions.getConstant(node);
298 if (constantExpression != null) {
299 constantValueMap.putIfAbsent(constantExpression, () {
300 return constantExpression.evaluate(
301 new CompilerEnvironment(compiler, node), constantSystem);
302 });
303 return constantExpression;
304 }
293 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( 305 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
294 this, definitions, compiler, isConst: isConst); 306 this, definitions, compiler, isConst: isConst);
295 AstConstant constant = evaluator.evaluate(node); 307 AstConstant constant = evaluator.evaluate(node);
296 if (constant != null) { 308 if (constant != null) {
297 cacheConstantValue(constant.expression, constant.value); 309 cacheConstantValue(constant.expression, constant.value);
298 return constant.expression; 310 return constant.expression;
299 } 311 }
300 return null; 312 return null;
313 /*
314 if (constantExpression == null) {
315 compiler.internalError(node, "No constant computed for $node.");
316 }
317 constantValueMap.putIfAbsent(
318 constantExpression, () {
319 return constantExpression.evaluate(
320 new CompilerEnvironment(compiler, node), constantSystem);
321 });
322 return constantExpression;*/
301 } 323 }
302 324
303 ConstantValue getConstantValue(ConstantExpression expression) { 325 ConstantValue getConstantValue(ConstantExpression expression) {
304 return constantValueMap[expression]; 326 return constantValueMap[expression];
305 } 327 }
306 328
307 ConstantExpression compileNode(Node node, TreeElements elements, 329 ConstantExpression compileNode(Node node, TreeElements elements,
308 {bool enforceConst: true}) { 330 {bool enforceConst: true}) {
309 return compileNodeWithDefinitions(node, elements, isConst: enforceConst); 331 return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
310 } 332 }
311 333
312 ConstantExpression compileMetadata( 334 ConstantExpression compileMetadata(
313 MetadataAnnotation metadata, Node node, TreeElements elements) { 335 MetadataAnnotation metadata, Node node, TreeElements elements) {
314 return compileNodeWithDefinitions(node, elements); 336 return compileNodeWithDefinitions(node, elements);
315 } 337 }
316 338
317 void forgetElement(Element element) { 339 void forgetElement(Element element) {
318 initialVariableValues.remove(element); 340 initialVariableValues.remove(element);
319 if (element is ScopeContainerElement) { 341 if (element is ScopeContainerElement) {
320 element.forEachLocalMember(initialVariableValues.remove); 342 element.forEachLocalMember(initialVariableValues.remove);
321 } 343 }
322 if (element is FunctionElement && element.hasFunctionSignature) { 344 if (element is FunctionElement && element.hasFunctionSignature) {
323 element.functionSignature.forEachParameter(this.forgetElement); 345 element.functionSignature.forEachParameter(this.forgetElement);
324 } 346 }
325 } 347 }
326 } 348 }
327 349
350 class CompilerEnvironment implements Environment {
351 final Compiler compiler;
352 final Spannable spannable;
353 final Set<VariableElement> evaluatingVariables = new Set<VariableElement>();
354 final Set<ConstructorElement> evaluatingConstructors =
355 new Set<ConstructorElement>();
356
357 CompilerEnvironment(this.compiler, this.spannable);
358
359 @override
360 CoreTypes get coreTypes => compiler.coreTypes;
361
362 @override
363 String readFromEnvironment(String name) => compiler.fromEnvironment(name);
364
365 @override
366 void reportWarning(ConstantExpression expression,
367 MessageKind kind,
368 Map arguments) {
369 compiler.reporter.reportWarningMessage(spannable, kind, arguments);
370 }
371
372 @override
373 void reportError(ConstantExpression expression,
374 MessageKind kind,
375 Map arguments) {
376 compiler.reporter.reportErrorMessage(spannable, kind, arguments);
377 }
378
379 @override
380 ConstantValue evaluateConstructor(
381 ConstructorElement constructor,
382 ConstantValue evaluate()) {
383 if (evaluatingConstructors.contains(constructor)) {
384 return new NonConstantValue();
385 }
386 ConstructorElement parentConstructor = constructor;
387 while (parentConstructor != null) {
388 _analyzeElementEagerly(compiler, parentConstructor);
389 ConstantConstructor constantConstructor =
390 parentConstructor.constantConstructor;
391 assert(invariant(parentConstructor, constantConstructor != null,
392 message: "No constant constructor on ${parentConstructor}."));
393 parentConstructor = constantConstructor.parentConstructor;
394 }
395 evaluatingConstructors.add(constructor);
396 ConstantValue value = evaluate();
397 evaluatingConstructors.remove(constructor);
398 return value;
399 }
400
401 @override
402 ConstantValue evaluateVariable(
403 VariableElement variable,
404 ConstantValue evaluate()) {
405 if (evaluatingVariables.contains(variable)) {
406 return new NonConstantValue();
407 }
408 if (!variable.isLocal) {
409 _analyzeElementEagerly(compiler, variable);
410 }
411 evaluatingVariables.add(variable);
412 ConstantValue value = evaluate();
413 evaluatingVariables.remove(variable);
414 return value;
415 }
416 }
417
328 /// [ConstantCompiler] that uses the Dart semantics for the compile-time 418 /// [ConstantCompiler] that uses the Dart semantics for the compile-time
329 /// constant evaluation. 419 /// constant evaluation.
330 class DartConstantCompiler extends ConstantCompilerBase { 420 class DartConstantCompiler extends ConstantCompilerBase {
331 DartConstantCompiler(Compiler compiler) 421 DartConstantCompiler(Compiler compiler)
332 : super(compiler, const DartConstantSystem()); 422 : super(compiler, const DartConstantSystem());
333 423
334 ConstantExpression getConstantForNode(Node node, TreeElements definitions) { 424 ConstantExpression getConstantForNode(Node node, TreeElements definitions) {
335 return definitions.getConstant(node); 425 return definitions.getConstant(node);
336 } 426 }
337 427
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 return makeConstructedConstant(compiler, handler, context, node, type, 957 return makeConstructedConstant(compiler, handler, context, node, type,
868 constructor, constructedType, implementation, callStructure, 958 constructor, constructedType, implementation, callStructure,
869 concreteArguments, normalizedArguments); 959 concreteArguments, normalizedArguments);
870 } 960 }
871 } 961 }
872 962
873 AstConstant createFromEnvironmentConstant(Node node, InterfaceType type, 963 AstConstant createFromEnvironmentConstant(Node node, InterfaceType type,
874 ConstructorElement constructor, CallStructure callStructure, 964 ConstructorElement constructor, CallStructure callStructure,
875 List<AstConstant> normalizedArguments, 965 List<AstConstant> normalizedArguments,
876 List<AstConstant> concreteArguments) { 966 List<AstConstant> concreteArguments) {
877 var firstArgument = normalizedArguments[0].value; 967
968 ConstantValue firstArgument = normalizedArguments[0].value;
878 ConstantValue defaultValue = normalizedArguments[1].value; 969 ConstantValue defaultValue = normalizedArguments[1].value;
879 970
880 if (firstArgument.isNull) { 971 if (firstArgument.isNull) {
881 reporter.reportErrorMessage( 972 reporter.reportErrorMessage(
882 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); 973 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED);
883 return null; 974 return null;
884 } 975 }
885 976
886 if (!firstArgument.isString) { 977 if (!firstArgument.isString) {
887 DartType type = defaultValue.getType(compiler.coreTypes); 978 DartType type = firstArgument.getType(compiler.coreTypes);
888 reporter.reportErrorMessage( 979 reporter.reportErrorMessage(
889 normalizedArguments[0].node, 980 normalizedArguments[0].node,
890 MessageKind.NOT_ASSIGNABLE, 981 MessageKind.NOT_ASSIGNABLE,
891 {'fromType': type, 982 {'fromType': type,
892 'toType': compiler.stringClass.rawType}); 983 'toType': compiler.stringClass.rawType});
893 return null; 984 return null;
894 } 985 }
895 986
896 if (constructor == compiler.intEnvironment && 987 if (constructor == compiler.intEnvironment &&
897 !(defaultValue.isNull || defaultValue.isInt)) { 988 !(defaultValue.isNull || defaultValue.isInt)) {
(...skipping 21 matching lines...) Expand all
919 !(defaultValue.isNull || defaultValue.isString)) { 1010 !(defaultValue.isNull || defaultValue.isString)) {
920 DartType type = defaultValue.getType(compiler.coreTypes); 1011 DartType type = defaultValue.getType(compiler.coreTypes);
921 reporter.reportErrorMessage( 1012 reporter.reportErrorMessage(
922 normalizedArguments[1].node, 1013 normalizedArguments[1].node,
923 MessageKind.NOT_ASSIGNABLE, 1014 MessageKind.NOT_ASSIGNABLE,
924 {'fromType': type, 1015 {'fromType': type,
925 'toType': compiler.stringClass.rawType}); 1016 'toType': compiler.stringClass.rawType});
926 return null; 1017 return null;
927 } 1018 }
928 1019
929 String name = firstArgument.primitiveValue.slowToString(); 1020 PrimitiveConstantValue nameArgument = firstArgument;
1021 String name = nameArgument.primitiveValue.slowToString();
930 String value = compiler.fromEnvironment(name); 1022 String value = compiler.fromEnvironment(name);
931 1023
932 AstConstant createEvaluatedConstant(ConstantValue value) { 1024 AstConstant createEvaluatedConstant(ConstantValue value) {
933 ConstantExpression expression; 1025 ConstantExpression expression;
934 ConstantExpression name = concreteArguments[0].expression; 1026 ConstantExpression name = concreteArguments[0].expression;
935 ConstantExpression defaultValue; 1027 ConstantExpression defaultValue;
936 if (concreteArguments.length > 1) { 1028 if (concreteArguments.length > 1) {
937 defaultValue = concreteArguments[1].expression; 1029 defaultValue = concreteArguments[1].expression;
938 } 1030 }
939 if (constructor == compiler.intEnvironment) { 1031 if (constructor == compiler.intEnvironment) {
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 ErroneousAstConstant(Element element, Node node) : super(element, node, 1348 ErroneousAstConstant(Element element, Node node) : super(element, node,
1257 // TODO(johnniwinther): Return a [NonConstantValue] instead. 1349 // TODO(johnniwinther): Return a [NonConstantValue] instead.
1258 new ErroneousConstantExpression(), new NullConstantValue()); 1350 new ErroneousConstantExpression(), new NullConstantValue());
1259 } 1351 }
1260 1352
1261 // TODO(johnniwinther): Clean this up. 1353 // TODO(johnniwinther): Clean this up.
1262 TreeElements _analyzeElementEagerly(Compiler compiler, AstElement element) { 1354 TreeElements _analyzeElementEagerly(Compiler compiler, AstElement element) {
1263 compiler.resolution.analyzeElement(element.declaration); 1355 compiler.resolution.analyzeElement(element.declaration);
1264 return element.resolvedAst.elements; 1356 return element.resolvedAst.elements;
1265 } 1357 }
1266
1267 class _CompilerEnvironment implements Environment {
1268 final Compiler compiler;
1269
1270 _CompilerEnvironment(this.compiler);
1271
1272 @override
1273 String readFromEnvironment(String name) {
1274 return compiler.fromEnvironment(name);
1275 }
1276 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/constant_system_dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698