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/resolution/resolution.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
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.resolution; 5 library dart2js.resolution;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 8
9 import '../common.dart'; 9 import '../common.dart';
10 import '../common/names.dart' show 10 import '../common/names.dart' show
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 import '../util/util.dart' show 48 import '../util/util.dart' show
49 Link, 49 Link,
50 LinkBuilder, 50 LinkBuilder,
51 Setlet; 51 Setlet;
52 52
53 import 'class_hierarchy.dart'; 53 import 'class_hierarchy.dart';
54 import 'class_members.dart' show MembersCreator; 54 import 'class_members.dart' show MembersCreator;
55 import 'constructors.dart'; 55 import 'constructors.dart';
56 import 'members.dart'; 56 import 'members.dart';
57 import 'registry.dart'; 57 import 'registry.dart';
58 import 'resolution_result.dart';
58 import 'signatures.dart'; 59 import 'signatures.dart';
59 import 'tree_elements.dart'; 60 import 'tree_elements.dart';
60 import 'typedefs.dart'; 61 import 'typedefs.dart';
61 62
62 class ResolverTask extends CompilerTask { 63 class ResolverTask extends CompilerTask {
63 final ConstantCompiler constantCompiler; 64 final ConstantCompiler constantCompiler;
64 65
65 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler); 66 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler);
66 67
67 String get name => 'Resolver'; 68 String get name => 'Resolver';
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 221 }
221 } 222 }
222 223
223 ResolverVisitor visitor = visitorFor(element); 224 ResolverVisitor visitor = visitorFor(element);
224 ResolutionRegistry registry = visitor.registry; 225 ResolutionRegistry registry = visitor.registry;
225 registry.defineFunction(tree, element); 226 registry.defineFunction(tree, element);
226 visitor.setupFunction(tree, element); 227 visitor.setupFunction(tree, element);
227 processAsyncMarker(compiler, element, registry); 228 processAsyncMarker(compiler, element, registry);
228 229
229 if (element.isGenerativeConstructor) { 230 if (element.isGenerativeConstructor) {
231 ConstructorElementX constructor = element;
230 // Even if there is no initializer list we still have to do the 232 // Even if there is no initializer list we still have to do the
231 // resolution in case there is an implicit super constructor call. 233 // resolution in case there is an implicit super constructor call.
232 InitializerResolver resolver = 234 InitializerResolver resolver =
233 new InitializerResolver(visitor, element, tree); 235 new InitializerResolver(visitor, constructor, tree);
234 FunctionElement redirection = resolver.resolveInitializers(); 236 FunctionElement redirection = resolver.resolveInitializers();
237 constructor.constantConstructor;
238 /*if (constructor.isConst && !constructor.isFromEnvironmentConstructor) {
239 assert(invariant(constructor,
240 constructor.constantConstructorCache != null,
241 message: "Constant constructor has"))
242 }*/
235 if (redirection != null) { 243 if (redirection != null) {
236 resolveRedirectingConstructor(resolver, tree, element, redirection); 244 resolveRedirectingConstructor(
245 resolver, tree, constructor, redirection);
237 } 246 }
238 } else if (tree.initializers != null) { 247 } else if (tree.initializers != null) {
239 reporter.reportErrorMessage( 248 reporter.reportErrorMessage(
240 tree, MessageKind.FUNCTION_WITH_INITIALIZER); 249 tree, MessageKind.FUNCTION_WITH_INITIALIZER);
241 } 250 }
242 251
243 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) { 252 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) {
244 // We need to analyze the redirecting factory bodies to ensure that 253 // We need to analyze the redirecting factory bodies to ensure that
245 // we can analyze compile-time constants. 254 // we can analyze compile-time constants.
246 visitor.visit(tree.body); 255 visitor.visit(tree.body);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 useEnclosingScope: useEnclosingScope); 341 useEnclosingScope: useEnclosingScope);
333 } 342 }
334 343
335 WorldImpact resolveField(FieldElementX element) { 344 WorldImpact resolveField(FieldElementX element) {
336 VariableDefinitions tree = element.parseNode(parsing); 345 VariableDefinitions tree = element.parseNode(parsing);
337 if(element.modifiers.isStatic && element.isTopLevel) { 346 if(element.modifiers.isStatic && element.isTopLevel) {
338 reporter.reportErrorMessage( 347 reporter.reportErrorMessage(
339 element.modifiers.getStatic(), 348 element.modifiers.getStatic(),
340 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); 349 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
341 } 350 }
351 bool requireConstant = element.isConst;
352 if (!requireConstant && element.isInstanceMember) {
353 for (ConstructorElement constructor in
354 element.enclosingClass.constructors) {
355 if (constructor.isConst) {
356 requireConstant = true;
357 break;
358 }
359 }
360 }
342 ResolverVisitor visitor = visitorFor(element); 361 ResolverVisitor visitor = visitorFor(element);
343 ResolutionRegistry registry = visitor.registry; 362 ResolutionRegistry registry = visitor.registry;
344 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates 363 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
345 // to the backend ast. 364 // to the backend ast.
346 registry.defineElement(tree.definitions.nodes.head, element); 365 registry.defineElement(tree.definitions.nodes.head, element);
347 // TODO(johnniwinther): Share the resolved type between all variables 366 // TODO(johnniwinther): Share the resolved type between all variables
348 // declared in the same declaration. 367 // declared in the same declaration.
349 if (tree.type != null) { 368 if (tree.type != null) {
350 element.variables.type = visitor.resolveTypeAnnotation(tree.type); 369 element.variables.type = visitor.resolveTypeAnnotation(tree.type);
351 } else { 370 } else {
352 element.variables.type = const DynamicType(); 371 element.variables.type = const DynamicType();
353 } 372 }
354 373
355 Expression initializer = element.initializer; 374 Expression initializer = element.initializer;
356 Modifiers modifiers = element.modifiers; 375 Modifiers modifiers = element.modifiers;
376 ResolutionResult result = const NoneResult();
357 if (initializer != null) { 377 if (initializer != null) {
358 // TODO(johnniwinther): Avoid analyzing initializers if 378 // TODO(johnniwinther): Avoid analyzing initializers if
359 // [Compiler.analyzeSignaturesOnly] is set. 379 // [Compiler.analyzeSignaturesOnly] is set.
360 visitor.visit(initializer); 380 //reportHere(reporter, element, 'resolveField:$element (${visitor.constant State}) (${initializer.runtimeType})');
381 if (requireConstant) {
382 result = visitor.visitInConstantContext(initializer);
383 visitor.checkConstantInvariant(initializer, result);
384 } else {
385 result = visitor.visit(initializer);
386 }
387 registry.setConstant(initializer, result.constant);
361 } else if (modifiers.isConst) { 388 } else if (modifiers.isConst) {
362 reporter.reportErrorMessage( 389 reporter.reportErrorMessage(
363 element, MessageKind.CONST_WITHOUT_INITIALIZER); 390 element, MessageKind.CONST_WITHOUT_INITIALIZER);
364 } else if (modifiers.isFinal && !element.isInstanceMember) { 391 } else if (modifiers.isFinal && !element.isInstanceMember) {
365 reporter.reportErrorMessage( 392 reporter.reportErrorMessage(
366 element, MessageKind.FINAL_WITHOUT_INITIALIZER); 393 element, MessageKind.FINAL_WITHOUT_INITIALIZER);
367 } else { 394 } else {
368 registry.registerInstantiatedClass(compiler.nullClass); 395 registry.registerInstantiatedClass(compiler.nullClass);
369 } 396 }
397 element.constant = result.constant;
370 398
371 if (Elements.isStaticOrTopLevelField(element)) { 399 if (Elements.isStaticOrTopLevelField(element)) {
372 visitor.addDeferredAction(element, () { 400 visitor.addDeferredAction(element, () {
373 if (element.modifiers.isConst) { 401 if (element.modifiers.isConst) {
374 element.constant = constantCompiler.compileConstant(element); 402 // Ensure constant expression will be evaluated.
403 constantCompiler.compileConstant(element);
375 } else { 404 } else {
376 constantCompiler.compileVariable(element); 405 constantCompiler.compileVariable(element);
377 } 406 }
378 }); 407 });
379 if (initializer != null) { 408 if (initializer != null) {
380 if (!element.modifiers.isConst) { 409 if (!element.modifiers.isConst) {
381 // TODO(johnniwinther): Determine the const-ness eagerly to avoid 410 // TODO(johnniwinther): Determine the const-ness eagerly to avoid
382 // unnecessary registrations. 411 // unnecessary registrations.
383 registry.registerLazyField(); 412 registry.registerLazyField();
384 } 413 }
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 assert(invariant(node, context != null, 1052 assert(invariant(node, context != null,
1024 message: "No context found for metadata annotation " 1053 message: "No context found for metadata annotation "
1025 "on $annotatedElement.")); 1054 "on $annotatedElement."));
1026 ResolverVisitor visitor = visitorFor(context, useEnclosingScope: true); 1055 ResolverVisitor visitor = visitorFor(context, useEnclosingScope: true);
1027 ResolutionRegistry registry = visitor.registry; 1056 ResolutionRegistry registry = visitor.registry;
1028 node.accept(visitor); 1057 node.accept(visitor);
1029 // TODO(johnniwinther): Avoid passing the [TreeElements] to 1058 // TODO(johnniwinther): Avoid passing the [TreeElements] to
1030 // [compileMetadata]. 1059 // [compileMetadata].
1031 annotation.constant = 1060 annotation.constant =
1032 constantCompiler.compileMetadata(annotation, node, registry.mapping); 1061 constantCompiler.compileMetadata(annotation, node, registry.mapping);
1033 constantCompiler.evaluate(annotation.constant); 1062 constantCompiler.evaluate(node, annotation.constant);
1034 // TODO(johnniwinther): Register the relation between the annotation 1063 // TODO(johnniwinther): Register the relation between the annotation
1035 // and the annotated element instead. This will allow the backend to 1064 // and the annotated element instead. This will allow the backend to
1036 // retrieve the backend constant and only register metadata on the 1065 // retrieve the backend constant and only register metadata on the
1037 // elements for which it is needed. (Issue 17732). 1066 // elements for which it is needed. (Issue 17732).
1038 registry.registerMetadataConstant(annotation); 1067 registry.registerMetadataConstant(annotation);
1039 annotation.resolutionState = STATE_DONE; 1068 annotation.resolutionState = STATE_DONE;
1040 })); 1069 }));
1041 } 1070 }
1042 1071
1043 List<MetadataAnnotation> resolveMetadata(Element element, 1072 List<MetadataAnnotation> resolveMetadata(Element element,
(...skipping 24 matching lines...) Expand all
1068 TreeElements get treeElements { 1097 TreeElements get treeElements {
1069 assert(invariant(this, _treeElements !=null, 1098 assert(invariant(this, _treeElements !=null,
1070 message: "TreeElements have not been computed for $this.")); 1099 message: "TreeElements have not been computed for $this."));
1071 return _treeElements; 1100 return _treeElements;
1072 } 1101 }
1073 1102
1074 void reuseElement() { 1103 void reuseElement() {
1075 _treeElements = null; 1104 _treeElements = null;
1076 } 1105 }
1077 } 1106 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/members.dart ('k') | pkg/compiler/lib/src/serialization/constant_serialization.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698