| 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 dart_backend; | 5 part of dart_backend; |
| 6 | 6 |
| 7 // TODO(ahe): This class is simply wrong. This backend should use | 7 // TODO(ahe): This class is simply wrong. This backend should use |
| 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, | 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, |
| 9 // TreeElements>] is what is needed. | 9 // TreeElements>] is what is needed. |
| 10 class ElementAst { | 10 class ElementAst { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 } | 40 } |
| 41 | 41 |
| 42 BackendConstantEnvironment get constants => constantCompilerTask; | 42 BackendConstantEnvironment get constants => constantCompilerTask; |
| 43 | 43 |
| 44 DartConstantTask constantCompilerTask; | 44 DartConstantTask constantCompilerTask; |
| 45 | 45 |
| 46 DartResolutionCallbacks resolutionCallbacks; | 46 DartResolutionCallbacks resolutionCallbacks; |
| 47 | 47 |
| 48 final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>(); | 48 final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>(); |
| 49 | 49 |
| 50 /// The set of visible platform classes that are implemented by instantiated |
| 51 /// user classes. |
| 52 final Set<ClassElement> _userImplementedPlatformClasses = |
| 53 new Set<ClassElement>(); |
| 54 |
| 50 /** | 55 /** |
| 51 * Tells whether it is safe to remove type declarations from variables, | 56 * Tells whether it is safe to remove type declarations from variables, |
| 52 * functions parameters. It becomes not safe if: | 57 * functions parameters. It becomes not safe if: |
| 53 * 1) TypeError is used somewhere in the code, | 58 * 1) TypeError is used somewhere in the code, |
| 54 * 2) The code has typedefs in right hand side of IS checks, | 59 * 2) The code has typedefs in right hand side of IS checks, |
| 55 * 3) The code has classes which extend typedefs, have type arguments typedefs | 60 * 3) The code has classes which extend typedefs, have type arguments typedefs |
| 56 * or type variable bounds typedefs. | 61 * or type variable bounds typedefs. |
| 57 * These restrictions can be less strict. | 62 * These restrictions can be less strict. |
| 58 */ | 63 */ |
| 59 bool isSafeToRemoveTypeDeclarations( | 64 bool isSafeToRemoveTypeDeclarations( |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 nonPlatformSize += compilationUnit.script.file.length; | 259 nonPlatformSize += compilationUnit.script.file.length; |
| 255 } | 260 } |
| 256 } | 261 } |
| 257 int percentage = totalOutputSize * 100 ~/ nonPlatformSize; | 262 int percentage = totalOutputSize * 100 ~/ nonPlatformSize; |
| 258 log('Total used non-platform files size: ${nonPlatformSize} bytes, ' | 263 log('Total used non-platform files size: ${nonPlatformSize} bytes, ' |
| 259 'Output total size: $totalOutputSize bytes (${percentage}%)'); | 264 'Output total size: $totalOutputSize bytes (${percentage}%)'); |
| 260 } | 265 } |
| 261 | 266 |
| 262 log(String message) => compiler.log('[DartBackend] $message'); | 267 log(String message) => compiler.log('[DartBackend] $message'); |
| 263 | 268 |
| 269 @override |
| 264 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 270 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
| 265 // All platform classes must be resolved to ensure that their member names | 271 // All platform classes must be resolved to ensure that their member names |
| 266 // are preserved. | 272 // are preserved. |
| 267 loadedLibraries.forEachLibrary((LibraryElement library) { | 273 loadedLibraries.forEachLibrary((LibraryElement library) { |
| 268 if (library.isPlatformLibrary) { | 274 if (library.isPlatformLibrary) { |
| 269 library.forEachLocalMember((Element element) { | 275 library.forEachLocalMember((Element element) { |
| 270 if (element.isClass) { | 276 if (element.isClass) { |
| 271 ClassElement classElement = element; | 277 ClassElement classElement = element; |
| 272 classElement.ensureResolved(compiler); | 278 classElement.ensureResolved(compiler); |
| 273 } | 279 } |
| 274 }); | 280 }); |
| 275 } | 281 } |
| 276 }); | 282 }); |
| 277 if (useMirrorHelperLibrary && | 283 if (useMirrorHelperLibrary && |
| 278 loadedLibraries.containsLibrary(Compiler.DART_MIRRORS)) { | 284 loadedLibraries.containsLibrary(Compiler.DART_MIRRORS)) { |
| 279 return compiler.libraryLoader.loadLibrary( | 285 return compiler.libraryLoader.loadLibrary( |
| 280 compiler.translateResolvedUri( | 286 compiler.translateResolvedUri( |
| 281 loadedLibraries.getLibrary(Compiler.DART_MIRRORS), | 287 loadedLibraries.getLibrary(Compiler.DART_MIRRORS), |
| 282 MirrorRenamerImpl.DART_MIRROR_HELPER, null)). | 288 MirrorRenamerImpl.DART_MIRROR_HELPER, null)). |
| 283 then((LibraryElement library) { | 289 then((LibraryElement library) { |
| 284 mirrorRenamer = new MirrorRenamerImpl(compiler, this, library); | 290 mirrorRenamer = new MirrorRenamerImpl(compiler, this, library); |
| 285 }); | 291 }); |
| 286 } | 292 } |
| 287 return new Future.value(); | 293 return new Future.value(); |
| 288 } | 294 } |
| 289 | 295 |
| 296 @override |
| 290 void registerStaticUse(Element element, Enqueuer enqueuer) { | 297 void registerStaticUse(Element element, Enqueuer enqueuer) { |
| 291 if (element == compiler.mirrorSystemGetNameFunction) { | 298 if (element == compiler.mirrorSystemGetNameFunction) { |
| 292 FunctionElement getNameFunction = mirrorRenamer.getNameFunction; | 299 FunctionElement getNameFunction = mirrorRenamer.getNameFunction; |
| 293 if (getNameFunction != null) { | 300 if (getNameFunction != null) { |
| 294 enqueuer.addToWorkList(getNameFunction); | 301 enqueuer.addToWorkList(getNameFunction); |
| 295 } | 302 } |
| 296 } | 303 } |
| 297 } | 304 } |
| 305 |
| 306 @override |
| 307 void registerInstantiatedType(InterfaceType type, Registry registry) { |
| 308 // Without patching, dart2dart has no way of performing sound tree-shaking |
| 309 // in face external functions. Therefore we employ another scheme: |
| 310 // |
| 311 // Based on the assumption that the platform code only relies on the |
| 312 // interfaces of it's own classes, we can approximate the semantics of |
| 313 // external functions by eagerly registering dynamic invocation of instance |
| 314 // members defined the platform interfaces. |
| 315 // |
| 316 // Since we only need to generate code for non-platform classes we can |
| 317 // restrict this registration to platform interfaces implemented by |
| 318 // instantiated non-platform classes. |
| 319 // |
| 320 // Consider for instance this program: |
| 321 // |
| 322 // import 'dart:math' show Random; |
| 323 // |
| 324 // class MyRandom implements Random { |
| 325 // int nextInt() => 0; |
| 326 // } |
| 327 // |
| 328 // main() { |
| 329 // print([0, 1, 2].shuffle(new MyRandom())); |
| 330 // } |
| 331 // |
| 332 // Here `MyRandom` is a subtype if `Random` defined in 'dart:math'. By the |
| 333 // assumption, all methods defined `Random` are potentially called, and |
| 334 // therefore, though there are no visible call sites from the user node, |
| 335 // dynamic invocation of for instance `nextInt` should be registered. In |
| 336 // this case, `nextInt` is actually called by the standard implementation of |
| 337 // `shuffle`. |
| 338 |
| 339 ClassElement cls = type.element; |
| 340 if (!cls.library.isPlatformLibrary) { |
| 341 for (Link<DartType> link = cls.allSupertypes; |
| 342 !link.isEmpty; |
| 343 link = link.tail) { |
| 344 InterfaceType supertype = link.head; |
| 345 ClassElement superclass = supertype.element; |
| 346 LibraryElement library = superclass.library; |
| 347 if (library.isPlatformLibrary) { |
| 348 if (_userImplementedPlatformClasses.add(superclass)) { |
| 349 // Register selectors for all instance methods since these might |
| 350 // be called on user classes from within the platform |
| 351 // implementation. |
| 352 superclass.forEachLocalMember((Element element) { |
| 353 if (element.isConstructor || element.isStatic) return; |
| 354 |
| 355 FunctionElement function = element.asFunctionElement(); |
| 356 if (function != null) { |
| 357 function.computeSignature(compiler); |
| 358 } |
| 359 Selector selector = new Selector.fromElement(element); |
| 360 if (selector.isGetter) { |
| 361 registry.registerDynamicGetter(selector); |
| 362 } else if (selector.isSetter) { |
| 363 registry.registerDynamicSetter(selector); |
| 364 } else { |
| 365 registry.registerDynamicInvocation(selector); |
| 366 } |
| 367 }); |
| 368 } |
| 369 } |
| 370 } |
| 371 } |
| 372 |
| 373 } |
| 298 } | 374 } |
| 299 | 375 |
| 300 class DartResolutionCallbacks extends ResolutionCallbacks { | 376 class DartResolutionCallbacks extends ResolutionCallbacks { |
| 301 final DartBackend backend; | 377 final DartBackend backend; |
| 302 | 378 |
| 303 DartResolutionCallbacks(this.backend); | 379 DartResolutionCallbacks(this.backend); |
| 304 | 380 |
| 305 void onTypeLiteral(DartType type, Registry registry) { | 381 void onTypeLiteral(DartType type, Registry registry) { |
| 306 if (type.isInterfaceType) { | 382 if (type.isInterfaceType) { |
| 307 backend.usedTypeLiterals.add(type.element); | 383 backend.usedTypeLiterals.add(type.element); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 } | 517 } |
| 442 | 518 |
| 443 ConstantExpression compileMetadata(MetadataAnnotation metadata, | 519 ConstantExpression compileMetadata(MetadataAnnotation metadata, |
| 444 Node node, | 520 Node node, |
| 445 TreeElements elements) { | 521 TreeElements elements) { |
| 446 return measure(() { | 522 return measure(() { |
| 447 return constantCompiler.compileMetadata(metadata, node, elements); | 523 return constantCompiler.compileMetadata(metadata, node, elements); |
| 448 }); | 524 }); |
| 449 } | 525 } |
| 450 } | 526 } |
| OLD | NEW |