| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 // 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 | 3 // 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. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 library dart2js.common.resolution; | 6 library dart2js.common.resolution; |
| 7 | 7 |
| 8 import '../compiler.dart' show | 8 import '../compiler.dart' show |
| 9 Compiler; | 9 Compiler; |
| 10 import '../core_types.dart' show | 10 import '../core_types.dart' show |
| 11 CoreTypes; | 11 CoreTypes; |
| 12 import '../dart_types.dart' show | 12 import '../dart_types.dart' show |
| 13 DartType, | 13 DartType; |
| 14 InterfaceType; | |
| 15 import '../diagnostics/diagnostic_listener.dart' show | 14 import '../diagnostics/diagnostic_listener.dart' show |
| 16 DiagnosticReporter; | 15 DiagnosticReporter; |
| 17 import '../elements/elements.dart' show | 16 import '../elements/elements.dart' show |
| 18 AstElement, | 17 AstElement, |
| 19 ClassElement, | 18 ClassElement, |
| 20 Element, | 19 Element, |
| 21 ErroneousElement, | 20 ErroneousElement, |
| 22 FunctionElement, | 21 FunctionElement, |
| 23 FunctionSignature, | 22 FunctionSignature, |
| 24 LocalFunctionElement, | |
| 25 MetadataAnnotation, | 23 MetadataAnnotation, |
| 26 MethodElement, | |
| 27 TypedefElement, | 24 TypedefElement, |
| 28 TypeVariableElement; | 25 TypeVariableElement; |
| 29 import '../enqueue.dart' show | 26 import '../enqueue.dart' show |
| 30 ResolutionEnqueuer, | 27 ResolutionEnqueuer, |
| 31 WorldImpact; | 28 WorldImpact; |
| 32 import '../tree/tree.dart' show | 29 import '../tree/tree.dart' show |
| 33 AsyncForIn, | 30 AsyncForIn, |
| 34 Send, | 31 Send, |
| 35 TypeAnnotation; | 32 TypeAnnotation; |
| 36 import '../universe/universe.dart' show | |
| 37 UniverseSelector; | |
| 38 import '../util/util.dart' show | |
| 39 Setlet; | |
| 40 import 'registry.dart' show | 33 import 'registry.dart' show |
| 41 Registry; | 34 Registry; |
| 42 import 'work.dart' show | 35 import 'work.dart' show |
| 43 ItemCompilationContext, | 36 ItemCompilationContext, |
| 44 WorkItem; | 37 WorkItem; |
| 45 | 38 |
| 46 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. | 39 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. |
| 47 class ResolutionWorkItem extends WorkItem { | 40 class ResolutionWorkItem extends WorkItem { |
| 48 bool _isAnalyzed = false; | 41 bool _isAnalyzed = false; |
| 49 | 42 |
| 50 ResolutionWorkItem(AstElement element, | 43 ResolutionWorkItem(AstElement element, |
| 51 ItemCompilationContext compilationContext) | 44 ItemCompilationContext compilationContext) |
| 52 : super(element, compilationContext); | 45 : super(element, compilationContext); |
| 53 | 46 |
| 54 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { | 47 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { |
| 55 WorldImpact impact = compiler.analyze(this, world); | 48 WorldImpact impact = compiler.analyze(this, world); |
| 56 impact = compiler.backend.resolutionCallbacks.transformImpact(impact); | |
| 57 _isAnalyzed = true; | 49 _isAnalyzed = true; |
| 58 return impact; | 50 return impact; |
| 59 } | 51 } |
| 60 | 52 |
| 61 bool get isAnalyzed => _isAnalyzed; | 53 bool get isAnalyzed => _isAnalyzed; |
| 62 } | 54 } |
| 63 | 55 |
| 64 // TODO(johnniwinther): Rename this to something like `BackendResolutionApi` | |
| 65 // and clean up the interface. | |
| 66 /// Backend callbacks function specific to the resolution phase. | 56 /// Backend callbacks function specific to the resolution phase. |
| 67 class ResolutionCallbacks { | 57 class ResolutionCallbacks { |
| 68 /// | |
| 69 WorldImpact transformImpact(ResolutionWorldImpact worldImpact) => worldImpact; | |
| 70 | |
| 71 /// Register that an assert has been seen. | 58 /// Register that an assert has been seen. |
| 72 void onAssert(bool hasMessage, Registry registry) {} | 59 void onAssert(bool hasMessage, Registry registry) {} |
| 73 | 60 |
| 74 /// Register that an 'await for' has been seen. | 61 /// Register that an 'await for' has been seen. |
| 75 void onAsyncForIn(AsyncForIn node, Registry registry) {} | 62 void onAsyncForIn(AsyncForIn node, Registry registry) {} |
| 76 | 63 |
| 77 /// Called during resolution to notify to the backend that the | 64 /// Called during resolution to notify to the backend that the |
| 78 /// program uses string interpolation. | 65 /// program uses string interpolation. |
| 79 void onStringInterpolation(Registry registry) {} | 66 void onStringInterpolation(Registry registry) {} |
| 80 | 67 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 /// Register that the application creates a constant map. | 126 /// Register that the application creates a constant map. |
| 140 void onMapLiteral(Registry registry, DartType type, bool isConstant) {} | 127 void onMapLiteral(Registry registry, DartType type, bool isConstant) {} |
| 141 | 128 |
| 142 /// Called when resolving the `Symbol` constructor. | 129 /// Called when resolving the `Symbol` constructor. |
| 143 void onSymbolConstructor(Registry registry) {} | 130 void onSymbolConstructor(Registry registry) {} |
| 144 | 131 |
| 145 /// Called when resolving a prefix or postfix expression. | 132 /// Called when resolving a prefix or postfix expression. |
| 146 void onIncDecOperation(Registry registry) {} | 133 void onIncDecOperation(Registry registry) {} |
| 147 } | 134 } |
| 148 | 135 |
| 149 class ResolutionWorldImpact extends WorldImpact { | |
| 150 const ResolutionWorldImpact(); | |
| 151 | |
| 152 // TODO(johnniwinther): Remove this. | |
| 153 void registerDependency(Element element) {} | |
| 154 | |
| 155 Iterable<Feature> get features => const <Feature>[]; | |
| 156 Iterable<DartType> get requiredTypes => const <DartType>[]; | |
| 157 Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[]; | |
| 158 Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[]; | |
| 159 Iterable<DartType> get typeLiterals => const <DartType>[]; | |
| 160 Iterable<String> get constSymbolNames => const <String>[]; | |
| 161 } | |
| 162 | |
| 163 /// A language feature seen during resolution. | |
| 164 // TODO(johnniwinther): Should mirror usage be part of this? | |
| 165 enum Feature { | |
| 166 /// Invocation of a generative construction on an abstract class. | |
| 167 ABSTRACT_CLASS_INSTANTIATION, | |
| 168 /// An assert statement with no message. | |
| 169 ASSERT, | |
| 170 /// An assert statement with a message. | |
| 171 ASSERT_WITH_MESSAGE, | |
| 172 /// A method with an `async` body modifier. | |
| 173 ASYNC, | |
| 174 /// An asynchronous for in statement like `await for (var e in i) {}`. | |
| 175 ASYNC_FOR_IN, | |
| 176 /// A method with an `async*` body modifier. | |
| 177 ASYNC_STAR, | |
| 178 /// A catch statement. | |
| 179 CATCH_STATEMENT, | |
| 180 /// A compile time error. | |
| 181 COMPILE_TIME_ERROR, | |
| 182 /// A fall through in a switch case. | |
| 183 FALL_THROUGH_ERROR, | |
| 184 /// A ++/-- operation. | |
| 185 INC_DEC_OPERATION, | |
| 186 /// A field whose initialization is not a constant. | |
| 187 LAZY_FIELD, | |
| 188 /// A call to `new Symbol`. | |
| 189 NEW_SYMBOL, | |
| 190 /// A catch clause with a variable for the stack trace. | |
| 191 STACK_TRACE_IN_CATCH, | |
| 192 /// String interpolation. | |
| 193 STRING_INTERPOLATION, | |
| 194 /// An implicit call to `super.noSuchMethod`, like calling an unresolved | |
| 195 /// super method. | |
| 196 SUPER_NO_SUCH_METHOD, | |
| 197 /// A redirection to the `Symbol` constructor. | |
| 198 SYMBOL_CONSTRUCTOR, | |
| 199 /// An synchronous for in statement, like `for (var e in i) {}`. | |
| 200 SYNC_FOR_IN, | |
| 201 /// A method with a `sync*` body modifier. | |
| 202 SYNC_STAR, | |
| 203 /// A throw expression. | |
| 204 THROW_EXPRESSION, | |
| 205 /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved | |
| 206 /// static method. | |
| 207 THROW_NO_SUCH_METHOD, | |
| 208 /// An implicit throw of a runtime error, like | |
| 209 THROW_RUNTIME_ERROR, | |
| 210 /// The need for a type variable bound check, like instantiation of a generic | |
| 211 /// type whose type variable have non-trivial bounds. | |
| 212 TYPE_VARIABLE_BOUNDS_CHECK, | |
| 213 } | |
| 214 | |
| 215 /// A use of a map literal seen during resolution. | |
| 216 class MapLiteralUse { | |
| 217 final InterfaceType type; | |
| 218 final bool isConstant; | |
| 219 final bool isEmpty; | |
| 220 | |
| 221 MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); | |
| 222 | |
| 223 int get hashCode { | |
| 224 return | |
| 225 type.hashCode * 13 + | |
| 226 isConstant.hashCode * 17 + | |
| 227 isEmpty.hashCode * 19; | |
| 228 } | |
| 229 | |
| 230 bool operator ==(other) { | |
| 231 if (identical(this, other)) return true; | |
| 232 if (other is! MapLiteralUse) return false; | |
| 233 return | |
| 234 type == other.type && | |
| 235 isConstant == other.isConstant && | |
| 236 isEmpty == other.isEmpty; | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 /// A use of a list literal seen during resolution. | |
| 241 class ListLiteralUse { | |
| 242 final InterfaceType type; | |
| 243 final bool isConstant; | |
| 244 final bool isEmpty; | |
| 245 | |
| 246 ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); | |
| 247 | |
| 248 int get hashCode { | |
| 249 return | |
| 250 type.hashCode * 13 + | |
| 251 isConstant.hashCode * 17 + | |
| 252 isEmpty.hashCode * 19; | |
| 253 } | |
| 254 | |
| 255 bool operator ==(other) { | |
| 256 if (identical(this, other)) return true; | |
| 257 if (other is! ListLiteralUse) return false; | |
| 258 return | |
| 259 type == other.type && | |
| 260 isConstant == other.isConstant && | |
| 261 isEmpty == other.isEmpty; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 /// Mutable implementation of [WorldImpact] used to transform | |
| 266 /// [ResolutionWorldImpact] to [WorldImpact]. | |
| 267 // TODO(johnniwinther): Remove [Registry] when dependency is tracked directly | |
| 268 // on [WorldImpact]. | |
| 269 class TransformedWorldImpact implements WorldImpact, Registry { | |
| 270 final ResolutionWorldImpact worldImpact; | |
| 271 | |
| 272 Setlet<Element> _staticUses; | |
| 273 Setlet<InterfaceType> _instantiatedTypes; | |
| 274 Setlet<UniverseSelector> _dynamicGetters; | |
| 275 Setlet<UniverseSelector> _dynamicInvocations; | |
| 276 Setlet<UniverseSelector> _dynamicSetters; | |
| 277 | |
| 278 TransformedWorldImpact(this.worldImpact); | |
| 279 | |
| 280 @override | |
| 281 Iterable<DartType> get asCasts => worldImpact.asCasts; | |
| 282 | |
| 283 @override | |
| 284 Iterable<DartType> get checkedModeChecks => worldImpact.checkedModeChecks; | |
| 285 | |
| 286 @override | |
| 287 Iterable<MethodElement> get closurizedFunctions { | |
| 288 return worldImpact.closurizedFunctions; | |
| 289 } | |
| 290 | |
| 291 @override | |
| 292 Iterable<UniverseSelector> get dynamicGetters { | |
| 293 return _dynamicGetters != null | |
| 294 ? _dynamicGetters : worldImpact.dynamicGetters; | |
| 295 } | |
| 296 | |
| 297 @override | |
| 298 Iterable<UniverseSelector> get dynamicInvocations { | |
| 299 return _dynamicInvocations != null | |
| 300 ? _dynamicInvocations : worldImpact.dynamicInvocations; | |
| 301 } | |
| 302 | |
| 303 @override | |
| 304 Iterable<UniverseSelector> get dynamicSetters { | |
| 305 return _dynamicSetters != null | |
| 306 ? _dynamicSetters : worldImpact.dynamicSetters; | |
| 307 } | |
| 308 | |
| 309 @override | |
| 310 Iterable<DartType> get isChecks => worldImpact.isChecks; | |
| 311 | |
| 312 @override | |
| 313 Iterable<Element> get staticUses { | |
| 314 if (_staticUses == null) { | |
| 315 return worldImpact.staticUses; | |
| 316 } | |
| 317 return _staticUses; | |
| 318 } | |
| 319 | |
| 320 @override | |
| 321 bool get isForResolution => true; | |
| 322 | |
| 323 _unsupported(String message) => throw new UnsupportedError(message); | |
| 324 | |
| 325 @override | |
| 326 Iterable<Element> get otherDependencies => _unsupported('otherDependencies'); | |
| 327 | |
| 328 // TODO(johnniwinther): Remove this. | |
| 329 @override | |
| 330 void registerAssert(bool hasMessage) => _unsupported('registerAssert'); | |
| 331 | |
| 332 @override | |
| 333 void registerDependency(Element element) { | |
| 334 worldImpact.registerDependency(element); | |
| 335 } | |
| 336 | |
| 337 @override | |
| 338 void registerDynamicGetter(UniverseSelector selector) { | |
| 339 if (_dynamicGetters == null) { | |
| 340 _dynamicGetters = new Setlet<UniverseSelector>(); | |
| 341 _dynamicGetters.addAll(worldImpact.dynamicGetters); | |
| 342 } | |
| 343 _dynamicGetters.add(selector); | |
| 344 } | |
| 345 | |
| 346 @override | |
| 347 void registerDynamicInvocation(UniverseSelector selector) { | |
| 348 if (_dynamicInvocations == null) { | |
| 349 _dynamicInvocations = new Setlet<UniverseSelector>(); | |
| 350 _dynamicInvocations.addAll(worldImpact.dynamicInvocations); | |
| 351 } | |
| 352 _dynamicInvocations.add(selector); | |
| 353 } | |
| 354 | |
| 355 @override | |
| 356 void registerDynamicSetter(UniverseSelector selector) { | |
| 357 if (_dynamicSetters == null) { | |
| 358 _dynamicSetters = new Setlet<UniverseSelector>(); | |
| 359 _dynamicSetters.addAll(worldImpact.dynamicSetters); | |
| 360 } | |
| 361 _dynamicSetters.add(selector); | |
| 362 } | |
| 363 | |
| 364 @override | |
| 365 void registerGetOfStaticFunction(FunctionElement element) { | |
| 366 _unsupported('registerGetOfStaticFunction($element)'); | |
| 367 } | |
| 368 | |
| 369 @override | |
| 370 void registerInstantiation(InterfaceType type) { | |
| 371 // TODO(johnniwinther): Remove this when dependency tracking is done on | |
| 372 // the world impact itself. | |
| 373 registerDependency(type.element); | |
| 374 if (_instantiatedTypes == null) { | |
| 375 _instantiatedTypes = new Setlet<InterfaceType>(); | |
| 376 } | |
| 377 _instantiatedTypes.add(type); | |
| 378 } | |
| 379 | |
| 380 @override | |
| 381 Iterable<InterfaceType> get instantiatedTypes { | |
| 382 return _instantiatedTypes != null | |
| 383 ? _instantiatedTypes : const <InterfaceType>[]; | |
| 384 } | |
| 385 | |
| 386 @override | |
| 387 void registerStaticInvocation(Element element) { | |
| 388 if (_staticUses == null) { | |
| 389 _staticUses = new Setlet<Element>(); | |
| 390 _staticUses.addAll(worldImpact.staticUses); | |
| 391 } | |
| 392 _staticUses.add(element); | |
| 393 } | |
| 394 | |
| 395 @override | |
| 396 Iterable<LocalFunctionElement> get closures => worldImpact.closures; | |
| 397 } | |
| 398 | |
| 399 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`. | 136 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`. |
| 400 abstract class Resolution { | 137 abstract class Resolution { |
| 401 Parsing get parsing; | 138 Parsing get parsing; |
| 402 DiagnosticReporter get reporter; | 139 DiagnosticReporter get reporter; |
| 403 CoreTypes get coreTypes; | 140 CoreTypes get coreTypes; |
| 404 | 141 |
| 405 void resolveTypedef(TypedefElement typdef); | 142 void resolveTypedef(TypedefElement typdef); |
| 406 void resolveClass(ClassElement cls); | 143 void resolveClass(ClassElement cls); |
| 407 void registerClass(ClassElement cls); | 144 void registerClass(ClassElement cls); |
| 408 void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation); | 145 void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation); |
| 409 FunctionSignature resolveSignature(FunctionElement function); | 146 FunctionSignature resolveSignature(FunctionElement function); |
| 410 DartType resolveTypeAnnotation(Element element, TypeAnnotation node); | 147 DartType resolveTypeAnnotation(Element element, TypeAnnotation node); |
| 411 | |
| 412 bool hasBeenResolved(Element element); | |
| 413 ResolutionWorldImpact analyzeElement(Element element); | |
| 414 } | 148 } |
| 415 | 149 |
| 416 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`. | 150 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`. |
| 417 abstract class Parsing { | 151 abstract class Parsing { |
| 418 DiagnosticReporter get reporter; | 152 DiagnosticReporter get reporter; |
| 419 void parsePatchClass(ClassElement cls); | 153 void parsePatchClass(ClassElement cls); |
| 420 measure(f()); | 154 measure(f()); |
| 421 } | 155 } |
| OLD | NEW |