OLD | NEW |
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 AnalyzableElement get analyzedElement; | 8 AnalyzableElement get analyzedElement; |
9 Iterable<Node> get superUses; | 9 Iterable<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 /// [analyzedElement]. | 12 /// [analyzedElement]. |
13 Iterable<Element> get allElements; | 13 Iterable<Element> get allElements; |
14 void forEachConstantNode(f(Node n, ConstExp c)); | 14 void forEachConstantNode(f(Node n, ConstantExpression c)); |
15 | 15 |
16 /// A set of additional dependencies. See [registerDependency] below. | 16 /// A set of additional dependencies. See [registerDependency] below. |
17 Iterable<Element> get otherDependencies; | 17 Iterable<Element> get otherDependencies; |
18 | 18 |
19 Element operator[](Node node); | 19 Element operator[](Node node); |
20 | 20 |
21 // TODO(johnniwinther): Investigate whether [Node] could be a [Send]. | 21 // TODO(johnniwinther): Investigate whether [Node] could be a [Send]. |
22 Selector getSelector(Node node); | 22 Selector getSelector(Node node); |
23 Selector getGetterSelectorInComplexSendSet(SendSet node); | 23 Selector getGetterSelectorInComplexSendSet(SendSet node); |
24 Selector getOperatorSelectorInComplexSendSet(SendSet node); | 24 Selector getOperatorSelectorInComplexSendSet(SendSet node); |
25 DartType getType(Node node); | 25 DartType getType(Node node); |
26 void setSelector(Node node, Selector selector); | 26 void setSelector(Node node, Selector selector); |
27 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector); | 27 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector); |
28 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector); | 28 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector); |
29 | 29 |
30 /// Returns the for-in loop variable for [node]. | 30 /// Returns the for-in loop variable for [node]. |
31 Element getForInVariable(ForIn node); | 31 Element getForInVariable(ForIn node); |
32 Selector getIteratorSelector(ForIn node); | 32 Selector getIteratorSelector(ForIn node); |
33 Selector getMoveNextSelector(ForIn node); | 33 Selector getMoveNextSelector(ForIn node); |
34 Selector getCurrentSelector(ForIn node); | 34 Selector getCurrentSelector(ForIn node); |
35 void setIteratorSelector(ForIn node, Selector selector); | 35 void setIteratorSelector(ForIn node, Selector selector); |
36 void setMoveNextSelector(ForIn node, Selector selector); | 36 void setMoveNextSelector(ForIn node, Selector selector); |
37 void setCurrentSelector(ForIn node, Selector selector); | 37 void setCurrentSelector(ForIn node, Selector selector); |
38 void setConstant(Node node, ConstExp constant); | 38 void setConstant(Node node, ConstantExpression constant); |
39 ConstExp getConstant(Node node); | 39 ConstantExpression getConstant(Node node); |
40 bool isAssert(Send send); | 40 bool isAssert(Send send); |
41 | 41 |
42 /// Returns the [FunctionElement] defined by [node]. | 42 /// Returns the [FunctionElement] defined by [node]. |
43 FunctionElement getFunctionDefinition(FunctionExpression node); | 43 FunctionElement getFunctionDefinition(FunctionExpression node); |
44 | 44 |
45 /// Returns target constructor for the redirecting factory body [node]. | 45 /// Returns target constructor for the redirecting factory body [node]. |
46 ConstructorElement getRedirectingTargetConstructor( | 46 ConstructorElement getRedirectingTargetConstructor( |
47 RedirectingFactoryBody node); | 47 RedirectingFactoryBody node); |
48 | 48 |
49 /** | 49 /** |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 /// Returns the label that [node] targets. | 86 /// Returns the label that [node] targets. |
87 LabelDefinition getTargetLabel(GotoStatement node); | 87 LabelDefinition getTargetLabel(GotoStatement node); |
88 } | 88 } |
89 | 89 |
90 class TreeElementMapping implements TreeElements { | 90 class TreeElementMapping implements TreeElements { |
91 final AnalyzableElement analyzedElement; | 91 final AnalyzableElement analyzedElement; |
92 Map<Spannable, Selector> _selectors; | 92 Map<Spannable, Selector> _selectors; |
93 Map<Node, DartType> _types; | 93 Map<Node, DartType> _types; |
94 Setlet<Node> _superUses; | 94 Setlet<Node> _superUses; |
95 Setlet<Element> _otherDependencies; | 95 Setlet<Element> _otherDependencies; |
96 Map<Node, ConstExp> _constants; | 96 Map<Node, ConstantExpression> _constants; |
97 Map<VariableElement, List<Node>> _potentiallyMutated; | 97 Map<VariableElement, List<Node>> _potentiallyMutated; |
98 Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn; | 98 Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn; |
99 Map<VariableElement, List<Node>> _potentiallyMutatedInClosure; | 99 Map<VariableElement, List<Node>> _potentiallyMutatedInClosure; |
100 Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn; | 100 Map<Node, Map<VariableElement, List<Node>>> _accessedByClosureIn; |
101 Setlet<Element> _elements; | 101 Setlet<Element> _elements; |
102 Setlet<Send> _asserts; | 102 Setlet<Send> _asserts; |
103 | 103 |
104 /// Map from nodes to the targets they define. | 104 /// Map from nodes to the targets they define. |
105 Map<Node, JumpTarget> _definedTargets; | 105 Map<Node, JumpTarget> _definedTargets; |
106 | 106 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 229 } |
230 | 230 |
231 Selector getCurrentSelector(ForIn node) { | 231 Selector getCurrentSelector(ForIn node) { |
232 return _getSelector(node.inToken); | 232 return _getSelector(node.inToken); |
233 } | 233 } |
234 | 234 |
235 Element getForInVariable(ForIn node) { | 235 Element getForInVariable(ForIn node) { |
236 return this[node]; | 236 return this[node]; |
237 } | 237 } |
238 | 238 |
239 void setConstant(Node node, ConstExp constant) { | 239 void setConstant(Node node, ConstantExpression constant) { |
240 if (_constants == null) { | 240 if (_constants == null) { |
241 _constants = new Maplet<Node, ConstExp>(); | 241 _constants = new Maplet<Node, ConstantExpression>(); |
242 } | 242 } |
243 _constants[node] = constant; | 243 _constants[node] = constant; |
244 } | 244 } |
245 | 245 |
246 ConstExp getConstant(Node node) { | 246 ConstantExpression getConstant(Node node) { |
247 return _constants != null ? _constants[node] : null; | 247 return _constants != null ? _constants[node] : null; |
248 } | 248 } |
249 | 249 |
250 bool isTypeLiteral(Send node) { | 250 bool isTypeLiteral(Send node) { |
251 return getType(node) != null; | 251 return getType(node) != null; |
252 } | 252 } |
253 | 253 |
254 DartType getTypeLiteralType(Send node) { | 254 DartType getTypeLiteralType(Send node) { |
255 return getType(node); | 255 return getType(node); |
256 } | 256 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 () => new Maplet<VariableElement, List<Node>>()); | 337 () => new Maplet<VariableElement, List<Node>>()); |
338 accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode); | 338 accessMap.putIfAbsent(element, () => <Node>[]).add(accessNode); |
339 } | 339 } |
340 | 340 |
341 String toString() => 'TreeElementMapping($analyzedElement)'; | 341 String toString() => 'TreeElementMapping($analyzedElement)'; |
342 | 342 |
343 Iterable<Element> get allElements { | 343 Iterable<Element> get allElements { |
344 return _elements != null ? _elements : const <Element>[]; | 344 return _elements != null ? _elements : const <Element>[]; |
345 } | 345 } |
346 | 346 |
347 void forEachConstantNode(f(Node n, ConstExp c)) { | 347 void forEachConstantNode(f(Node n, ConstantExpression c)) { |
348 if (_constants != null) { | 348 if (_constants != null) { |
349 _constants.forEach(f); | 349 _constants.forEach(f); |
350 } | 350 } |
351 } | 351 } |
352 | 352 |
353 void setAssert(Send node) { | 353 void setAssert(Send node) { |
354 if (_asserts == null) { | 354 if (_asserts == null) { |
355 _asserts = new Setlet<Send>(); | 355 _asserts = new Setlet<Send>(); |
356 } | 356 } |
357 _asserts.add(node); | 357 _asserts.add(node); |
(...skipping 2944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3302 registry.registerFactoryWithTypeArguments(); | 3302 registry.registerFactoryWithTypeArguments(); |
3303 } | 3303 } |
3304 if (constructor.isGenerativeConstructor && cls.isAbstract) { | 3304 if (constructor.isGenerativeConstructor && cls.isAbstract) { |
3305 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); | 3305 warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION); |
3306 registry.registerAbstractClassInstantiation(); | 3306 registry.registerAbstractClassInstantiation(); |
3307 } | 3307 } |
3308 | 3308 |
3309 if (isSymbolConstructor) { | 3309 if (isSymbolConstructor) { |
3310 if (node.isConst) { | 3310 if (node.isConst) { |
3311 Node argumentNode = node.send.arguments.head; | 3311 Node argumentNode = node.send.arguments.head; |
3312 ConstExp constant = compiler.resolver.constantCompiler.compileNode( | 3312 ConstantExpression constant = |
3313 argumentNode, registry.mapping); | 3313 compiler.resolver.constantCompiler.compileNode( |
3314 Constant name = constant.value; | 3314 argumentNode, registry.mapping); |
| 3315 ConstantValue name = constant.value; |
3315 if (!name.isString) { | 3316 if (!name.isString) { |
3316 DartType type = name.computeType(compiler); | 3317 DartType type = name.computeType(compiler); |
3317 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 3318 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, |
3318 {'type': type}); | 3319 {'type': type}); |
3319 } else { | 3320 } else { |
3320 StringConstant stringConstant = name; | 3321 StringConstantValue stringConstant = name; |
3321 String nameString = stringConstant.toDartString().slowToString(); | 3322 String nameString = stringConstant.toDartString().slowToString(); |
3322 if (validateSymbol(argumentNode, nameString)) { | 3323 if (validateSymbol(argumentNode, nameString)) { |
3323 registry.registerConstSymbol(nameString); | 3324 registry.registerConstSymbol(nameString); |
3324 } | 3325 } |
3325 } | 3326 } |
3326 } else { | 3327 } else { |
3327 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 3328 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
3328 enclosingElement)) { | 3329 enclosingElement)) { |
3329 compiler.reportHint( | 3330 compiler.reportHint( |
3330 node.newToken, MessageKind.NON_CONST_BLOAT, | 3331 node.newToken, MessageKind.NON_CONST_BLOAT, |
3331 {'name': compiler.symbolClass.name}); | 3332 {'name': compiler.symbolClass.name}); |
3332 } | 3333 } |
3333 registry.registerNewSymbol(); | 3334 registry.registerNewSymbol(); |
3334 } | 3335 } |
3335 } else if (isMirrorsUsedConstant) { | 3336 } else if (isMirrorsUsedConstant) { |
3336 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 3337 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
3337 } | 3338 } |
3338 if (node.isConst) { | 3339 if (node.isConst) { |
3339 analyzeConstant(node); | 3340 analyzeConstant(node); |
3340 } | 3341 } |
3341 | 3342 |
3342 return null; | 3343 return null; |
3343 } | 3344 } |
3344 | 3345 |
3345 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 3346 void checkConstMapKeysDontOverrideEquals(Spannable spannable, |
3346 MapConstant map) { | 3347 MapConstantValue map) { |
3347 for (Constant key in map.keys) { | 3348 for (ConstantValue key in map.keys) { |
3348 if (!key.isObject) continue; | 3349 if (!key.isObject) continue; |
3349 ObjectConstant objectConstant = key; | 3350 ObjectConstantValue objectConstant = key; |
3350 DartType keyType = objectConstant.type; | 3351 DartType keyType = objectConstant.type; |
3351 ClassElement cls = keyType.element; | 3352 ClassElement cls = keyType.element; |
3352 if (cls == compiler.stringClass) continue; | 3353 if (cls == compiler.stringClass) continue; |
3353 Element equals = cls.lookupMember('=='); | 3354 Element equals = cls.lookupMember('=='); |
3354 if (equals.enclosingClass != compiler.objectClass) { | 3355 if (equals.enclosingClass != compiler.objectClass) { |
3355 compiler.reportError(spannable, | 3356 compiler.reportError(spannable, |
3356 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, | 3357 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, |
3357 {'type': keyType}); | 3358 {'type': keyType}); |
3358 } | 3359 } |
3359 } | 3360 } |
3360 } | 3361 } |
3361 | 3362 |
3362 void analyzeConstant(Node node) { | 3363 void analyzeConstant(Node node) { |
3363 addDeferredAction(enclosingElement, () { | 3364 addDeferredAction(enclosingElement, () { |
3364 ConstExp constant = compiler.resolver.constantCompiler.compileNode( | 3365 ConstantExpression constant = |
3365 node, registry.mapping); | 3366 compiler.resolver.constantCompiler.compileNode( |
| 3367 node, registry.mapping); |
3366 | 3368 |
3367 Constant value = constant.value; | 3369 ConstantValue value = constant.value; |
3368 if (value.isMap) { | 3370 if (value.isMap) { |
3369 checkConstMapKeysDontOverrideEquals(node, value); | 3371 checkConstMapKeysDontOverrideEquals(node, value); |
3370 } | 3372 } |
3371 | 3373 |
3372 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names | 3374 // The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names |
3373 // a class that will be instantiated outside the program by attaching a | 3375 // a class that will be instantiated outside the program by attaching a |
3374 // native class dispatch record referencing the interceptor. | 3376 // native class dispatch record referencing the interceptor. |
3375 if (argumentsToJsInterceptorConstant != null && | 3377 if (argumentsToJsInterceptorConstant != null && |
3376 argumentsToJsInterceptorConstant.contains(node)) { | 3378 argumentsToJsInterceptorConstant.contains(node)) { |
3377 if (value.isType) { | 3379 if (value.isType) { |
3378 TypeConstant typeConstant = value; | 3380 TypeConstantValue typeConstant = value; |
3379 if (typeConstant.representedType is InterfaceType) { | 3381 if (typeConstant.representedType is InterfaceType) { |
3380 registry.registerInstantiatedType(typeConstant.representedType); | 3382 registry.registerInstantiatedType(typeConstant.representedType); |
3381 } else { | 3383 } else { |
3382 compiler.reportError(node, | 3384 compiler.reportError(node, |
3383 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 3385 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
3384 } | 3386 } |
3385 } else { | 3387 } else { |
3386 compiler.reportError(node, | 3388 compiler.reportError(node, |
3387 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 3389 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
3388 } | 3390 } |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3704 } | 3706 } |
3705 | 3707 |
3706 visitLiteralMapEntry(LiteralMapEntry node) { | 3708 visitLiteralMapEntry(LiteralMapEntry node) { |
3707 node.visitChildren(this); | 3709 node.visitChildren(this); |
3708 } | 3710 } |
3709 | 3711 |
3710 visitNamedArgument(NamedArgument node) { | 3712 visitNamedArgument(NamedArgument node) { |
3711 visit(node.expression); | 3713 visit(node.expression); |
3712 } | 3714 } |
3713 | 3715 |
3714 DartType typeOfConstant(Constant constant) { | 3716 DartType typeOfConstant(ConstantValue constant) { |
3715 if (constant.isInt) return compiler.intClass.rawType; | 3717 if (constant.isInt) return compiler.intClass.rawType; |
3716 if (constant.isBool) return compiler.boolClass.rawType; | 3718 if (constant.isBool) return compiler.boolClass.rawType; |
3717 if (constant.isDouble) return compiler.doubleClass.rawType; | 3719 if (constant.isDouble) return compiler.doubleClass.rawType; |
3718 if (constant.isString) return compiler.stringClass.rawType; | 3720 if (constant.isString) return compiler.stringClass.rawType; |
3719 if (constant.isNull) return compiler.nullClass.rawType; | 3721 if (constant.isNull) return compiler.nullClass.rawType; |
3720 if (constant.isFunction) return compiler.functionClass.rawType; | 3722 if (constant.isFunction) return compiler.functionClass.rawType; |
3721 assert(constant.isObject); | 3723 assert(constant.isObject); |
3722 ObjectConstant objectConstant = constant; | 3724 ObjectConstantValue objectConstant = constant; |
3723 return objectConstant.type; | 3725 return objectConstant.type; |
3724 } | 3726 } |
3725 | 3727 |
3726 bool overridesEquals(DartType type) { | 3728 bool overridesEquals(DartType type) { |
3727 ClassElement cls = type.element; | 3729 ClassElement cls = type.element; |
3728 Element equals = cls.lookupMember('=='); | 3730 Element equals = cls.lookupMember('=='); |
3729 return equals.enclosingClass != compiler.objectClass; | 3731 return equals.enclosingClass != compiler.objectClass; |
3730 } | 3732 } |
3731 | 3733 |
3732 void checkCaseExpressions(SwitchStatement node) { | 3734 void checkCaseExpressions(SwitchStatement node) { |
3733 JumpTarget breakElement = getOrDefineTarget(node); | 3735 JumpTarget breakElement = getOrDefineTarget(node); |
3734 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; | 3736 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; |
3735 | 3737 |
3736 Link<Node> cases = node.cases.nodes; | 3738 Link<Node> cases = node.cases.nodes; |
3737 CaseMatch firstCase = null; | 3739 CaseMatch firstCase = null; |
3738 DartType firstCaseType = null; | 3740 DartType firstCaseType = null; |
3739 bool hasReportedProblem = false; | 3741 bool hasReportedProblem = false; |
3740 | 3742 |
3741 for (Link<Node> cases = node.cases.nodes; | 3743 for (Link<Node> cases = node.cases.nodes; |
3742 !cases.isEmpty; | 3744 !cases.isEmpty; |
3743 cases = cases.tail) { | 3745 cases = cases.tail) { |
3744 SwitchCase switchCase = cases.head; | 3746 SwitchCase switchCase = cases.head; |
3745 | 3747 |
3746 for (Node labelOrCase in switchCase.labelsAndCases) { | 3748 for (Node labelOrCase in switchCase.labelsAndCases) { |
3747 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 3749 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
3748 if (caseMatch == null) continue; | 3750 if (caseMatch == null) continue; |
3749 | 3751 |
3750 // Analyze the constant. | 3752 // Analyze the constant. |
3751 ConstExp constant = registry.getConstant(caseMatch.expression); | 3753 ConstantExpression constant = |
| 3754 registry.getConstant(caseMatch.expression); |
3752 assert(invariant(node, constant != null, | 3755 assert(invariant(node, constant != null, |
3753 message: 'No constant computed for $node')); | 3756 message: 'No constant computed for $node')); |
3754 | 3757 |
3755 DartType caseType = typeOfConstant(constant.value); | 3758 DartType caseType = typeOfConstant(constant.value); |
3756 | 3759 |
3757 if (firstCaseType == null) { | 3760 if (firstCaseType == null) { |
3758 firstCase = caseMatch; | 3761 firstCase = caseMatch; |
3759 firstCaseType = caseType; | 3762 firstCaseType = caseType; |
3760 | 3763 |
3761 // We only report the bad type on the first class element. All others | 3764 // We only report the bad type on the first class element. All others |
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4962 } | 4965 } |
4963 | 4966 |
4964 /// The result for the resolution of the `assert` method. | 4967 /// The result for the resolution of the `assert` method. |
4965 class AssertResult implements ResolutionResult { | 4968 class AssertResult implements ResolutionResult { |
4966 const AssertResult(); | 4969 const AssertResult(); |
4967 | 4970 |
4968 Element get element => null; | 4971 Element get element => null; |
4969 | 4972 |
4970 String toString() => 'AssertResult()'; | 4973 String toString() => 'AssertResult()'; |
4971 } | 4974 } |
OLD | NEW |