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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 221873002: Compute frontend/backend specific constants. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Classes renamed and comments added. Created 6 years, 8 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
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 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element get currentElement; 8 Element get currentElement;
9 Setlet<Node> get superUses; 9 Setlet<Node> get superUses;
10 10
11 /// Iterables of the dependencies that this [TreeElement] records of 11 /// Iterables of the dependencies that this [TreeElement] records of
12 /// [currentElement]. 12 /// [currentElement].
13 Iterable<Element> get allElements; 13 Iterable<Element> get allElements;
14 Iterable<Constant> get allConstants; 14 void forEachConstantNode(f(Node n, Constant c));
15 15
16 /// A set of additional dependencies. See [registerDependency] below. 16 /// A set of additional dependencies. See [registerDependency] below.
17 Setlet<Element> get otherDependencies; 17 Setlet<Element> get otherDependencies;
18 18
19 Element operator[](Node node); 19 Element operator[](Node node);
20 Selector getSelector(Send send); 20 Selector getSelector(Send send);
21 Selector getGetterSelectorInComplexSendSet(SendSet node); 21 Selector getGetterSelectorInComplexSendSet(SendSet node);
22 Selector getOperatorSelectorInComplexSendSet(SendSet node); 22 Selector getOperatorSelectorInComplexSendSet(SendSet node);
23 DartType getType(Node node); 23 DartType getType(Node node);
24 void setSelector(Node node, Selector selector); 24 void setSelector(Node node, Selector selector);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 Map<VariableElement, List<Node>> accessMap = 238 Map<VariableElement, List<Node>> accessMap =
239 accessedByClosureIn.putIfAbsent(contextNode, 239 accessedByClosureIn.putIfAbsent(contextNode,
240 () => new Map<VariableElement, List<Node>>()); 240 () => new Map<VariableElement, List<Node>>());
241 accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode); 241 accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode);
242 } 242 }
243 243
244 String toString() => 'TreeElementMapping($currentElement)'; 244 String toString() => 'TreeElementMapping($currentElement)';
245 245
246 Iterable<Element> get allElements => elements; 246 Iterable<Element> get allElements => elements;
247 247
248 Iterable<Constant> get allConstants => constants.values; 248 void forEachConstantNode(f(Node n, Constant c)) => constants.forEach(f);
249 } 249 }
250 250
251 class ResolverTask extends CompilerTask { 251 class ResolverTask extends CompilerTask {
252 ResolverTask(Compiler compiler) : super(compiler); 252 final ConstantCompiler constantCompiler;
253
254 ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler);
253 255
254 String get name => 'Resolver'; 256 String get name => 'Resolver';
255 257
256 TreeElements resolve(Element element) { 258 TreeElements resolve(Element element) {
257 return measure(() { 259 return measure(() {
258 if (Elements.isErroneousElement(element)) return null; 260 if (Elements.isErroneousElement(element)) return null;
259 261
260 for (MetadataAnnotation metadata in element.metadata) { 262 for (MetadataAnnotation metadata in element.metadata) {
261 metadata.ensureResolved(compiler); 263 metadata.ensureResolved(compiler);
262 } 264 }
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); 575 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
574 } else if (modifiers.isFinal() && !element.isInstanceMember()) { 576 } else if (modifiers.isFinal() && !element.isInstanceMember()) {
575 compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER); 577 compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER);
576 } else { 578 } else {
577 compiler.enqueuer.resolution.registerInstantiatedClass( 579 compiler.enqueuer.resolution.registerInstantiatedClass(
578 compiler.nullClass, visitor.mapping); 580 compiler.nullClass, visitor.mapping);
579 } 581 }
580 582
581 if (Elements.isStaticOrTopLevelField(element)) { 583 if (Elements.isStaticOrTopLevelField(element)) {
582 visitor.addDeferredAction(element, () { 584 visitor.addDeferredAction(element, () {
583 compiler.constantHandler.compileVariable( 585 if (element.modifiers.isConst()) {
584 element, isConst: element.modifiers.isConst()); 586 constantCompiler.compileConstant(element);
587 } else {
588 constantCompiler.compileVariable(element);
589 }
585 }); 590 });
586 if (initializer != null) { 591 if (initializer != null) {
587 if (!element.modifiers.isConst()) { 592 if (!element.modifiers.isConst()) {
588 // TODO(johnniwinther): Determine the const-ness eagerly to avoid 593 // TODO(johnniwinther): Determine the const-ness eagerly to avoid
589 // unnecessary registrations. 594 // unnecessary registrations.
590 compiler.backend.registerLazyField(visitor.mapping); 595 compiler.backend.registerLazyField(visitor.mapping);
591 } 596 }
592 } 597 }
593 } 598 }
594 599
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 Node node = annotation.parseNode(compiler); 1174 Node node = annotation.parseNode(compiler);
1170 // TODO(johnniwinther): Find the right analyzable element to hold the 1175 // TODO(johnniwinther): Find the right analyzable element to hold the
1171 // [TreeElements] for the annotation. 1176 // [TreeElements] for the annotation.
1172 Element annotatedElement = annotation.annotatedElement; 1177 Element annotatedElement = annotation.annotatedElement;
1173 Element context = annotatedElement.enclosingElement; 1178 Element context = annotatedElement.enclosingElement;
1174 if (context == null) { 1179 if (context == null) {
1175 context = annotatedElement; 1180 context = annotatedElement;
1176 } 1181 }
1177 ResolverVisitor visitor = visitorFor(context); 1182 ResolverVisitor visitor = visitorFor(context);
1178 node.accept(visitor); 1183 node.accept(visitor);
1179 annotation.value = compiler.constantHandler.compileNodeWithDefinitions( 1184 annotation.value =
1180 node, visitor.mapping, isConst: true); 1185 constantCompiler.compileMetadata(annotation, node, visitor.mapping);
1181 compiler.backend.registerMetadataConstant(annotation.value, 1186 // TODO(johnniwinther): Register the relation between the annotation
1182 visitor.mapping); 1187 // and the annotated element instead. This will allow the backed to
1183 1188 // retrieve the backend constant and only registered metadata on the
1189 // elements for which it is needed. (Issue 17732).
1190 compiler.backend.registerMetadataConstant(
1191 annotation.value, visitor.mapping);
1184 annotation.resolutionState = STATE_DONE; 1192 annotation.resolutionState = STATE_DONE;
1185 })); 1193 }));
1186 } 1194 }
1187 1195
1188 error(Spannable node, MessageKind kind, [arguments = const {}]) { 1196 error(Spannable node, MessageKind kind, [arguments = const {}]) {
1189 // TODO(ahe): Make non-fatal. 1197 // TODO(ahe): Make non-fatal.
1190 compiler.reportFatalError(node, kind, arguments); 1198 compiler.reportFatalError(node, kind, arguments);
1191 } 1199 }
1192 1200
1193 Link<MetadataAnnotation> resolveMetadata(Element element, 1201 Link<MetadataAnnotation> resolveMetadata(Element element,
1194 VariableDefinitions node) { 1202 VariableDefinitions node) {
1195 LinkBuilder<MetadataAnnotation> metadata = 1203 LinkBuilder<MetadataAnnotation> metadata =
1196 new LinkBuilder<MetadataAnnotation>(); 1204 new LinkBuilder<MetadataAnnotation>();
1197 for (Metadata annotation in node.metadata.nodes) { 1205 for (Metadata annotation in node.metadata.nodes) {
1198 ParameterMetadataAnnotation metadataAnnotation = 1206 ParameterMetadataAnnotation metadataAnnotation =
1199 new ParameterMetadataAnnotation(annotation); 1207 new ParameterMetadataAnnotation(annotation);
1200 metadataAnnotation.annotatedElement = element; 1208 metadataAnnotation.annotatedElement = element;
1201 metadata.addLast(metadataAnnotation.ensureResolved(compiler)); 1209 metadata.addLast(metadataAnnotation.ensureResolved(compiler));
1202 } 1210 }
1203 return metadata.toLink(); 1211 return metadata.toLink();
1204 } 1212 }
1205 } 1213 }
1206 1214
1207 class ConstantMapper extends Visitor {
1208 final Map<Constant, Node> constantToNodeMap = new Map<Constant, Node>();
1209 final CompileTimeConstantEvaluator evaluator;
1210
1211 ConstantMapper(ConstantHandler handler,
1212 TreeElements elements,
1213 Compiler compiler)
1214 : evaluator = new CompileTimeConstantEvaluator(
1215 handler, elements, compiler, isConst: false);
1216
1217 visitNode(Node node) {
1218 Constant constant = evaluator.evaluate(node);
1219 if (constant != null) constantToNodeMap[constant] = node;
1220 node.visitChildren(this);
1221 }
1222 }
1223
1224 class InitializerResolver { 1215 class InitializerResolver {
1225 final ResolverVisitor visitor; 1216 final ResolverVisitor visitor;
1226 final Map<Element, Node> initialized; 1217 final Map<Element, Node> initialized;
1227 Link<Node> initializers; 1218 Link<Node> initializers;
1228 bool hasSuper; 1219 bool hasSuper;
1229 1220
1230 InitializerResolver(this.visitor) 1221 InitializerResolver(this.visitor)
1231 : initialized = new Map<Element, Node>(), hasSuper = false; 1222 : initialized = new Map<Element, Node>(), hasSuper = false;
1232 1223
1233 error(Node node, MessageKind kind, [arguments = const {}]) { 1224 error(Node node, MessageKind kind, [arguments = const {}]) {
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
2197 // fields they reference are visible, but must be resolved independently. 2188 // fields they reference are visible, but must be resolved independently.
2198 if (element.kind == ElementKind.FIELD_PARAMETER) { 2189 if (element.kind == ElementKind.FIELD_PARAMETER) {
2199 useElement(parameterNode, element); 2190 useElement(parameterNode, element);
2200 } else { 2191 } else {
2201 defineElement(parameterNode, element); 2192 defineElement(parameterNode, element);
2202 } 2193 }
2203 parameterNodes = parameterNodes.tail; 2194 parameterNodes = parameterNodes.tail;
2204 }); 2195 });
2205 addDeferredAction(enclosingElement, () { 2196 addDeferredAction(enclosingElement, () {
2206 functionParameters.forEachOptionalParameter((Element parameter) { 2197 functionParameters.forEachOptionalParameter((Element parameter) {
2207 compiler.constantHandler.compileConstant(parameter); 2198 compiler.resolver.constantCompiler.compileConstant(parameter);
2208 }); 2199 });
2209 }); 2200 });
2210 if (inCheckContext) { 2201 if (inCheckContext) {
2211 functionParameters.forEachParameter((Element element) { 2202 functionParameters.forEachParameter((Element element) {
2212 compiler.enqueuer.resolution.registerIsCheck( 2203 compiler.enqueuer.resolution.registerIsCheck(
2213 element.computeType(compiler), mapping); 2204 element.computeType(compiler), mapping);
2214 }); 2205 });
2215 } 2206 }
2216 } 2207 }
2217 2208
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 // type variable expression. 2568 // type variable expression.
2578 mapping.setType(node, compiler.typeClass.computeType(compiler)); 2569 mapping.setType(node, compiler.typeClass.computeType(compiler));
2579 world.registerTypeLiteral(target, mapping); 2570 world.registerTypeLiteral(target, mapping);
2580 } else if (target.impliesType() && (!sendIsMemberAccess || node.isCall)) { 2571 } else if (target.impliesType() && (!sendIsMemberAccess || node.isCall)) {
2581 // Set the type of the node to [Type] to mark this send as a 2572 // Set the type of the node to [Type] to mark this send as a
2582 // type literal. 2573 // type literal.
2583 mapping.setType(node, compiler.typeClass.computeType(compiler)); 2574 mapping.setType(node, compiler.typeClass.computeType(compiler));
2584 world.registerTypeLiteral(target, mapping); 2575 world.registerTypeLiteral(target, mapping);
2585 2576
2586 // Don't try to make constants of calls to type literals. 2577 // Don't try to make constants of calls to type literals.
2587 analyzeConstant(node, isConst: !node.isCall); 2578 if (!node.isCall) {
2579 analyzeConstant(node);
2580 } else {
2581 // The node itself is not a constant but we register the selector (the
2582 // identifier that refers to the class/typedef) as a constant.
2583 analyzeConstant(node.selector);
2584 }
2588 } 2585 }
2589 if (isPotentiallyMutableTarget(target)) { 2586 if (isPotentiallyMutableTarget(target)) {
2590 if (enclosingElement != target.enclosingElement) { 2587 if (enclosingElement != target.enclosingElement) {
2591 for (Node scope in promotionScope) { 2588 for (Node scope in promotionScope) {
2592 mapping.setAccessedByClosureIn(scope, target, node); 2589 mapping.setAccessedByClosureIn(scope, target, node);
2593 } 2590 }
2594 } 2591 }
2595 } 2592 }
2596 } 2593 }
2597 2594
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3047 world.registerFactoryWithTypeArguments(mapping); 3044 world.registerFactoryWithTypeArguments(mapping);
3048 } 3045 }
3049 if (constructor.isGenerativeConstructor() && cls.isAbstract) { 3046 if (constructor.isGenerativeConstructor() && cls.isAbstract) {
3050 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); 3047 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
3051 compiler.backend.registerAbstractClassInstantiation(mapping); 3048 compiler.backend.registerAbstractClassInstantiation(mapping);
3052 } 3049 }
3053 3050
3054 if (isSymbolConstructor) { 3051 if (isSymbolConstructor) {
3055 if (node.isConst()) { 3052 if (node.isConst()) {
3056 Node argumentNode = node.send.arguments.head; 3053 Node argumentNode = node.send.arguments.head;
3057 Constant name = compiler.constantHandler.compileNodeWithDefinitions( 3054 Constant name = compiler.resolver.constantCompiler.compileNode(
3058 argumentNode, mapping, isConst: true); 3055 argumentNode, mapping);
3059 if (!name.isString) { 3056 if (!name.isString) {
3060 DartType type = name.computeType(compiler); 3057 DartType type = name.computeType(compiler);
3061 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, 3058 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED,
3062 {'type': type}); 3059 {'type': type});
3063 } else { 3060 } else {
3064 StringConstant stringConstant = name; 3061 StringConstant stringConstant = name;
3065 String nameString = stringConstant.toDartString().slowToString(); 3062 String nameString = stringConstant.toDartString().slowToString();
3066 if (validateSymbol(argumentNode, nameString)) { 3063 if (validateSymbol(argumentNode, nameString)) {
3067 world.registerConstSymbol(nameString, mapping); 3064 world.registerConstSymbol(nameString, mapping);
3068 } 3065 }
(...skipping 27 matching lines...) Expand all
3096 if (cls == compiler.stringClass) continue; 3093 if (cls == compiler.stringClass) continue;
3097 Element equals = cls.lookupMember('=='); 3094 Element equals = cls.lookupMember('==');
3098 if (equals.getEnclosingClass() != compiler.objectClass) { 3095 if (equals.getEnclosingClass() != compiler.objectClass) {
3099 compiler.reportError(spannable, 3096 compiler.reportError(spannable,
3100 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, 3097 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
3101 {'type': keyType}); 3098 {'type': keyType});
3102 } 3099 }
3103 } 3100 }
3104 } 3101 }
3105 3102
3106 void analyzeConstant(Node node, {bool isConst: true}) { 3103 void analyzeConstant(Node node) {
3107 addDeferredAction(enclosingElement, () { 3104 addDeferredAction(enclosingElement, () {
3108 Constant constant = compiler.constantHandler.compileNodeWithDefinitions( 3105 Constant constant =
3109 node, mapping, isConst: isConst); 3106 compiler.resolver.constantCompiler.compileNode(node, mapping);
3110 3107
3111 if (isConst && constant != null && constant.isMap) { 3108 if (constant.isMap) {
3112 checkConstMapKeysDontOverrideEquals(node, constant); 3109 checkConstMapKeysDontOverrideEquals(node, constant);
3113 } 3110 }
3114 3111
3115 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names 3112 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
3116 // a class that will be instantiated outside the program by attaching a 3113 // a class that will be instantiated outside the program by attaching a
3117 // native class dispatch record referencing the interceptor. 3114 // native class dispatch record referencing the interceptor.
3118 if (argumentsToJsInterceptorConstant != null && 3115 if (argumentsToJsInterceptorConstant != null &&
3119 argumentsToJsInterceptorConstant.contains(node)) { 3116 argumentsToJsInterceptorConstant.contains(node)) {
3120 if (constant.isType) { 3117 if (constant.isType) {
3121 TypeConstant typeConstant = constant; 3118 TypeConstant typeConstant = constant;
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
4451 4448
4452 visitNodeList(NodeList node) { 4449 visitNodeList(NodeList node) {
4453 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { 4450 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
4454 Identifier name = visit(link.head); 4451 Identifier name = visit(link.head);
4455 VariableElement element = new VariableElementX( 4452 VariableElement element = new VariableElementX(
4456 name.source, kind, resolver.enclosingElement, 4453 name.source, kind, resolver.enclosingElement,
4457 variables, name.token); 4454 variables, name.token);
4458 resolver.defineElement(link.head, element); 4455 resolver.defineElement(link.head, element);
4459 if (definitions.modifiers.isConst()) { 4456 if (definitions.modifiers.isConst()) {
4460 compiler.enqueuer.resolution.addDeferredAction(element, () { 4457 compiler.enqueuer.resolution.addDeferredAction(element, () {
4461 compiler.constantHandler.compileVariable(element, isConst: true); 4458 compiler.resolver.constantCompiler.compileConstant(element);
4462 }); 4459 });
4463 } 4460 }
4464 } 4461 }
4465 } 4462 }
4466 } 4463 }
4467 4464
4468 class ConstructorResolver extends CommonResolverVisitor<Element> { 4465 class ConstructorResolver extends CommonResolverVisitor<Element> {
4469 final ResolverVisitor resolver; 4466 final ResolverVisitor resolver;
4470 bool inConstContext; 4467 bool inConstContext;
4471 DartType type; 4468 DartType type;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
4658 TreeElements _treeElements; 4655 TreeElements _treeElements;
4659 4656
4660 bool get hasTreeElements => _treeElements != null; 4657 bool get hasTreeElements => _treeElements != null;
4661 4658
4662 TreeElements get treeElements { 4659 TreeElements get treeElements {
4663 assert(invariant(this, _treeElements !=null, 4660 assert(invariant(this, _treeElements !=null,
4664 message: "TreeElements have not been computed for $this.")); 4661 message: "TreeElements have not been computed for $this."));
4665 return _treeElements; 4662 return _treeElements;
4666 } 4663 }
4667 } 4664 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698