| OLD | NEW |
| 1 | |
| 2 // 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 |
| 3 // 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 |
| 4 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 5 | 4 |
| 6 library dart2js.common.resolution; | 5 library dart2js.common.resolution; |
| 7 | 6 |
| 8 import '../common.dart'; | 7 import '../common.dart'; |
| 9 import '../compiler.dart' show | 8 import '../compiler.dart' show Compiler; |
| 10 Compiler; | 9 import '../constants/expressions.dart' show ConstantExpression; |
| 11 import '../constants/expressions.dart' show | 10 import '../core_types.dart' show CoreTypes; |
| 12 ConstantExpression; | 11 import '../dart_types.dart' show DartType, InterfaceType; |
| 13 import '../core_types.dart' show | 12 import '../elements/elements.dart' |
| 14 CoreTypes; | 13 show |
| 15 import '../dart_types.dart' show | 14 AstElement, |
| 16 DartType, | 15 ClassElement, |
| 17 InterfaceType; | 16 Element, |
| 18 import '../elements/elements.dart' show | 17 ErroneousElement, |
| 19 AstElement, | 18 FunctionElement, |
| 20 ClassElement, | 19 FunctionSignature, |
| 21 Element, | 20 LocalFunctionElement, |
| 22 ErroneousElement, | 21 MetadataAnnotation, |
| 23 FunctionElement, | 22 MethodElement, |
| 24 FunctionSignature, | 23 TypedefElement, |
| 25 LocalFunctionElement, | 24 TypeVariableElement; |
| 26 MetadataAnnotation, | 25 import '../enqueue.dart' show ResolutionEnqueuer; |
| 27 MethodElement, | 26 import '../options.dart' show ParserOptions; |
| 28 TypedefElement, | 27 import '../parser/element_listener.dart' show ScannerOptions; |
| 29 TypeVariableElement; | 28 import '../tree/tree.dart' show AsyncForIn, Send, TypeAnnotation; |
| 30 import '../enqueue.dart' show | 29 import '../universe/world_impact.dart' show WorldImpact; |
| 31 ResolutionEnqueuer; | 30 import 'work.dart' show ItemCompilationContext, WorkItem; |
| 32 import '../options.dart' show | |
| 33 ParserOptions; | |
| 34 import '../parser/element_listener.dart' show | |
| 35 ScannerOptions; | |
| 36 import '../tree/tree.dart' show | |
| 37 AsyncForIn, | |
| 38 Send, | |
| 39 TypeAnnotation; | |
| 40 import '../universe/world_impact.dart' show | |
| 41 WorldImpact; | |
| 42 import 'work.dart' show | |
| 43 ItemCompilationContext, | |
| 44 WorkItem; | |
| 45 | 31 |
| 46 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. | 32 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. |
| 47 class ResolutionWorkItem extends WorkItem { | 33 class ResolutionWorkItem extends WorkItem { |
| 48 bool _isAnalyzed = false; | 34 bool _isAnalyzed = false; |
| 49 | 35 |
| 50 ResolutionWorkItem(AstElement element, | 36 ResolutionWorkItem( |
| 51 ItemCompilationContext compilationContext) | 37 AstElement element, ItemCompilationContext compilationContext) |
| 52 : super(element, compilationContext); | 38 : super(element, compilationContext); |
| 53 | 39 |
| 54 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { | 40 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { |
| 55 WorldImpact impact = compiler.analyze(this, world); | 41 WorldImpact impact = compiler.analyze(this, world); |
| 56 _isAnalyzed = true; | 42 _isAnalyzed = true; |
| 57 return impact; | 43 return impact; |
| 58 } | 44 } |
| 59 | 45 |
| 60 bool get isAnalyzed => _isAnalyzed; | 46 bool get isAnalyzed => _isAnalyzed; |
| 61 } | 47 } |
| 62 | 48 |
| 63 class ResolutionImpact extends WorldImpact { | 49 class ResolutionImpact extends WorldImpact { |
| 64 const ResolutionImpact(); | 50 const ResolutionImpact(); |
| 65 | 51 |
| 66 Iterable<Feature> get features => const <Feature>[]; | 52 Iterable<Feature> get features => const <Feature>[]; |
| 67 Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[]; | 53 Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[]; |
| 68 Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[]; | 54 Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[]; |
| 69 Iterable<String> get constSymbolNames => const <String>[]; | 55 Iterable<String> get constSymbolNames => const <String>[]; |
| 70 Iterable<ConstantExpression> get constantLiterals { | 56 Iterable<ConstantExpression> get constantLiterals { |
| 71 return const <ConstantExpression>[]; | 57 return const <ConstantExpression>[]; |
| 72 } | 58 } |
| 73 } | 59 } |
| 74 | 60 |
| 75 /// A language feature seen during resolution. | 61 /// A language feature seen during resolution. |
| 76 // TODO(johnniwinther): Should mirror usage be part of this? | 62 // TODO(johnniwinther): Should mirror usage be part of this? |
| 77 enum Feature { | 63 enum Feature { |
| 78 /// Invocation of a generative construction on an abstract class. | 64 /// Invocation of a generative construction on an abstract class. |
| 79 ABSTRACT_CLASS_INSTANTIATION, | 65 ABSTRACT_CLASS_INSTANTIATION, |
| 66 |
| 80 /// An assert statement with no message. | 67 /// An assert statement with no message. |
| 81 ASSERT, | 68 ASSERT, |
| 69 |
| 82 /// An assert statement with a message. | 70 /// An assert statement with a message. |
| 83 ASSERT_WITH_MESSAGE, | 71 ASSERT_WITH_MESSAGE, |
| 72 |
| 84 /// A method with an `async` body modifier. | 73 /// A method with an `async` body modifier. |
| 85 ASYNC, | 74 ASYNC, |
| 75 |
| 86 /// An asynchronous for in statement like `await for (var e in i) {}`. | 76 /// An asynchronous for in statement like `await for (var e in i) {}`. |
| 87 ASYNC_FOR_IN, | 77 ASYNC_FOR_IN, |
| 78 |
| 88 /// A method with an `async*` body modifier. | 79 /// A method with an `async*` body modifier. |
| 89 ASYNC_STAR, | 80 ASYNC_STAR, |
| 81 |
| 90 /// A catch statement. | 82 /// A catch statement. |
| 91 CATCH_STATEMENT, | 83 CATCH_STATEMENT, |
| 84 |
| 92 /// A compile time error. | 85 /// A compile time error. |
| 93 COMPILE_TIME_ERROR, | 86 COMPILE_TIME_ERROR, |
| 87 |
| 94 /// A fall through in a switch case. | 88 /// A fall through in a switch case. |
| 95 FALL_THROUGH_ERROR, | 89 FALL_THROUGH_ERROR, |
| 90 |
| 96 /// A ++/-- operation. | 91 /// A ++/-- operation. |
| 97 INC_DEC_OPERATION, | 92 INC_DEC_OPERATION, |
| 93 |
| 98 /// A field whose initialization is not a constant. | 94 /// A field whose initialization is not a constant. |
| 99 LAZY_FIELD, | 95 LAZY_FIELD, |
| 96 |
| 100 /// A catch clause with a variable for the stack trace. | 97 /// A catch clause with a variable for the stack trace. |
| 101 STACK_TRACE_IN_CATCH, | 98 STACK_TRACE_IN_CATCH, |
| 99 |
| 102 /// String interpolation. | 100 /// String interpolation. |
| 103 STRING_INTERPOLATION, | 101 STRING_INTERPOLATION, |
| 102 |
| 104 /// String juxtaposition. | 103 /// String juxtaposition. |
| 105 STRING_JUXTAPOSITION, | 104 STRING_JUXTAPOSITION, |
| 105 |
| 106 /// An implicit call to `super.noSuchMethod`, like calling an unresolved | 106 /// An implicit call to `super.noSuchMethod`, like calling an unresolved |
| 107 /// super method. | 107 /// super method. |
| 108 SUPER_NO_SUCH_METHOD, | 108 SUPER_NO_SUCH_METHOD, |
| 109 |
| 109 /// A redirection to the `Symbol` constructor. | 110 /// A redirection to the `Symbol` constructor. |
| 110 SYMBOL_CONSTRUCTOR, | 111 SYMBOL_CONSTRUCTOR, |
| 112 |
| 111 /// An synchronous for in statement, like `for (var e in i) {}`. | 113 /// An synchronous for in statement, like `for (var e in i) {}`. |
| 112 SYNC_FOR_IN, | 114 SYNC_FOR_IN, |
| 115 |
| 113 /// A method with a `sync*` body modifier. | 116 /// A method with a `sync*` body modifier. |
| 114 SYNC_STAR, | 117 SYNC_STAR, |
| 118 |
| 115 /// A throw expression. | 119 /// A throw expression. |
| 116 THROW_EXPRESSION, | 120 THROW_EXPRESSION, |
| 121 |
| 117 /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved | 122 /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved |
| 118 /// static method. | 123 /// static method. |
| 119 THROW_NO_SUCH_METHOD, | 124 THROW_NO_SUCH_METHOD, |
| 125 |
| 120 /// An implicit throw of a runtime error, like | 126 /// An implicit throw of a runtime error, like |
| 121 THROW_RUNTIME_ERROR, | 127 THROW_RUNTIME_ERROR, |
| 128 |
| 122 /// The need for a type variable bound check, like instantiation of a generic | 129 /// The need for a type variable bound check, like instantiation of a generic |
| 123 /// type whose type variable have non-trivial bounds. | 130 /// type whose type variable have non-trivial bounds. |
| 124 TYPE_VARIABLE_BOUNDS_CHECK, | 131 TYPE_VARIABLE_BOUNDS_CHECK, |
| 125 } | 132 } |
| 126 | 133 |
| 127 /// A use of a map literal seen during resolution. | 134 /// A use of a map literal seen during resolution. |
| 128 class MapLiteralUse { | 135 class MapLiteralUse { |
| 129 final InterfaceType type; | 136 final InterfaceType type; |
| 130 final bool isConstant; | 137 final bool isConstant; |
| 131 final bool isEmpty; | 138 final bool isEmpty; |
| 132 | 139 |
| 133 MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); | 140 MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); |
| 134 | 141 |
| 135 int get hashCode { | 142 int get hashCode { |
| 136 return | 143 return type.hashCode * 13 + |
| 137 type.hashCode * 13 + | |
| 138 isConstant.hashCode * 17 + | 144 isConstant.hashCode * 17 + |
| 139 isEmpty.hashCode * 19; | 145 isEmpty.hashCode * 19; |
| 140 } | 146 } |
| 141 | 147 |
| 142 bool operator ==(other) { | 148 bool operator ==(other) { |
| 143 if (identical(this, other)) return true; | 149 if (identical(this, other)) return true; |
| 144 if (other is! MapLiteralUse) return false; | 150 if (other is! MapLiteralUse) return false; |
| 145 return | 151 return type == other.type && |
| 146 type == other.type && | |
| 147 isConstant == other.isConstant && | 152 isConstant == other.isConstant && |
| 148 isEmpty == other.isEmpty; | 153 isEmpty == other.isEmpty; |
| 149 } | 154 } |
| 150 | 155 |
| 151 String toString() { | 156 String toString() { |
| 152 return 'MapLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)'; | 157 return 'MapLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)'; |
| 153 } | 158 } |
| 154 } | 159 } |
| 155 | 160 |
| 156 /// A use of a list literal seen during resolution. | 161 /// A use of a list literal seen during resolution. |
| 157 class ListLiteralUse { | 162 class ListLiteralUse { |
| 158 final InterfaceType type; | 163 final InterfaceType type; |
| 159 final bool isConstant; | 164 final bool isConstant; |
| 160 final bool isEmpty; | 165 final bool isEmpty; |
| 161 | 166 |
| 162 ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); | 167 ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); |
| 163 | 168 |
| 164 int get hashCode { | 169 int get hashCode { |
| 165 return | 170 return type.hashCode * 13 + |
| 166 type.hashCode * 13 + | |
| 167 isConstant.hashCode * 17 + | 171 isConstant.hashCode * 17 + |
| 168 isEmpty.hashCode * 19; | 172 isEmpty.hashCode * 19; |
| 169 } | 173 } |
| 170 | 174 |
| 171 bool operator ==(other) { | 175 bool operator ==(other) { |
| 172 if (identical(this, other)) return true; | 176 if (identical(this, other)) return true; |
| 173 if (other is! ListLiteralUse) return false; | 177 if (other is! ListLiteralUse) return false; |
| 174 return | 178 return type == other.type && |
| 175 type == other.type && | |
| 176 isConstant == other.isConstant && | 179 isConstant == other.isConstant && |
| 177 isEmpty == other.isEmpty; | 180 isEmpty == other.isEmpty; |
| 178 } | 181 } |
| 179 | 182 |
| 180 String toString() { | 183 String toString() { |
| 181 return 'ListLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)'; | 184 return 'ListLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)'; |
| 182 } | 185 } |
| 183 } | 186 } |
| 184 | 187 |
| 185 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`. | 188 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 void emptyCache(); | 229 void emptyCache(); |
| 227 } | 230 } |
| 228 | 231 |
| 229 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`. | 232 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`. |
| 230 abstract class Parsing { | 233 abstract class Parsing { |
| 231 DiagnosticReporter get reporter; | 234 DiagnosticReporter get reporter; |
| 232 void parsePatchClass(ClassElement cls); | 235 void parsePatchClass(ClassElement cls); |
| 233 measure(f()); | 236 measure(f()); |
| 234 ScannerOptions getScannerOptionsFor(Element element); | 237 ScannerOptions getScannerOptionsFor(Element element); |
| 235 ParserOptions get parserOptions; | 238 ParserOptions get parserOptions; |
| 236 } | 239 } |
| OLD | NEW |