| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
| 8 | 8 |
| 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 return constantCompilerTask.jsConstantCompiler; | 315 return constantCompilerTask.jsConstantCompiler; |
| 316 } | 316 } |
| 317 | 317 |
| 318 static Namer determineNamer(Compiler compiler) { | 318 static Namer determineNamer(Compiler compiler) { |
| 319 return compiler.enableMinification ? | 319 return compiler.enableMinification ? |
| 320 new MinifyNamer(compiler) : | 320 new MinifyNamer(compiler) : |
| 321 new Namer(compiler); | 321 new Namer(compiler); |
| 322 } | 322 } |
| 323 | 323 |
| 324 bool usedByBackend(Element element) { | 324 bool usedByBackend(Element element) { |
| 325 if (element.isParameter() | 325 if (element.isParameter |
| 326 || element.isFieldParameter() | 326 || element.isFieldParameter |
| 327 || element.isField()) { | 327 || element.isField) { |
| 328 if (usedByBackend(element.enclosingElement)) return true; | 328 if (usedByBackend(element.enclosingElement)) return true; |
| 329 } | 329 } |
| 330 return helpersUsed.contains(element.declaration); | 330 return helpersUsed.contains(element.declaration); |
| 331 } | 331 } |
| 332 | 332 |
| 333 bool invokedReflectively(Element element) { | 333 bool invokedReflectively(Element element) { |
| 334 if (element.isParameter() || element.isFieldParameter()) { | 334 if (element.isParameter || element.isFieldParameter) { |
| 335 if (invokedReflectively(element.enclosingElement)) return true; | 335 if (invokedReflectively(element.enclosingElement)) return true; |
| 336 } | 336 } |
| 337 | 337 |
| 338 if (element.isField()) { | 338 if (element.isField) { |
| 339 if (Elements.isStaticOrTopLevel(element) | 339 if (Elements.isStaticOrTopLevel(element) |
| 340 && (element.modifiers.isFinal() || element.modifiers.isConst())) { | 340 && (element.modifiers.isFinal || element.modifiers.isConst)) { |
| 341 return false; | 341 return false; |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 | 344 |
| 345 return isNeededForReflection(element.declaration); | 345 return isNeededForReflection(element.declaration); |
| 346 } | 346 } |
| 347 | 347 |
| 348 bool canBeUsedForGlobalOptimizations(Element element) { | 348 bool canBeUsedForGlobalOptimizations(Element element) { |
| 349 return !usedByBackend(element) && !invokedReflectively(element); | 349 return !usedByBackend(element) && !invokedReflectively(element); |
| 350 } | 350 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 361 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); | 361 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); |
| 362 String name = namer.getOneShotInterceptorName(selector, classes); | 362 String name = namer.getOneShotInterceptorName(selector, classes); |
| 363 if (!oneShotInterceptors.containsKey(name)) { | 363 if (!oneShotInterceptors.containsKey(name)) { |
| 364 registerSpecializedGetInterceptor(classes); | 364 registerSpecializedGetInterceptor(classes); |
| 365 oneShotInterceptors[name] = selector; | 365 oneShotInterceptors[name] = selector; |
| 366 } | 366 } |
| 367 return name; | 367 return name; |
| 368 } | 368 } |
| 369 | 369 |
| 370 bool isInterceptedMethod(Element element) { | 370 bool isInterceptedMethod(Element element) { |
| 371 if (!element.isInstanceMember()) return false; | 371 if (!element.isInstanceMember) return false; |
| 372 if (element.isGenerativeConstructorBody()) { | 372 if (element.isGenerativeConstructorBody) { |
| 373 return Elements.isNativeOrExtendsNative(element.getEnclosingClass()); | 373 return Elements.isNativeOrExtendsNative(element.enclosingClass); |
| 374 } | 374 } |
| 375 return interceptedElements[element.name] != null; | 375 return interceptedElements[element.name] != null; |
| 376 } | 376 } |
| 377 | 377 |
| 378 bool fieldHasInterceptedGetter(Element element) { | 378 bool fieldHasInterceptedGetter(Element element) { |
| 379 assert(element.isField()); | 379 assert(element.isField); |
| 380 return interceptedElements[element.name] != null; | 380 return interceptedElements[element.name] != null; |
| 381 } | 381 } |
| 382 | 382 |
| 383 bool fieldHasInterceptedSetter(Element element) { | 383 bool fieldHasInterceptedSetter(Element element) { |
| 384 assert(element.isField()); | 384 assert(element.isField); |
| 385 return interceptedElements[element.name] != null; | 385 return interceptedElements[element.name] != null; |
| 386 } | 386 } |
| 387 | 387 |
| 388 bool isInterceptedName(String name) { | 388 bool isInterceptedName(String name) { |
| 389 return interceptedElements[name] != null; | 389 return interceptedElements[name] != null; |
| 390 } | 390 } |
| 391 | 391 |
| 392 bool isInterceptedSelector(Selector selector) { | 392 bool isInterceptedSelector(Selector selector) { |
| 393 return interceptedElements[selector.name] != null; | 393 return interceptedElements[selector.name] != null; |
| 394 } | 394 } |
| 395 | 395 |
| 396 /** | 396 /** |
| 397 * Returns `true` iff [selector] matches an element defined in a class mixed | 397 * Returns `true` iff [selector] matches an element defined in a class mixed |
| 398 * into an intercepted class. These selectors are not eligible for the 'dummy | 398 * into an intercepted class. These selectors are not eligible for the 'dummy |
| 399 * explicit receiver' optimization. | 399 * explicit receiver' optimization. |
| 400 */ | 400 */ |
| 401 bool isInterceptedMixinSelector(Selector selector) { | 401 bool isInterceptedMixinSelector(Selector selector) { |
| 402 Set<Element> elements = interceptedMixinElements.putIfAbsent( | 402 Set<Element> elements = interceptedMixinElements.putIfAbsent( |
| 403 selector.name, | 403 selector.name, |
| 404 () { | 404 () { |
| 405 Set<Element> elements = interceptedElements[selector.name]; | 405 Set<Element> elements = interceptedElements[selector.name]; |
| 406 if (elements == null) return null; | 406 if (elements == null) return null; |
| 407 return elements | 407 return elements |
| 408 .where((element) => | 408 .where((element) => |
| 409 classesMixedIntoInterceptedClasses.contains( | 409 classesMixedIntoInterceptedClasses.contains( |
| 410 element.getEnclosingClass())) | 410 element.enclosingClass)) |
| 411 .toSet(); | 411 .toSet(); |
| 412 }); | 412 }); |
| 413 | 413 |
| 414 if (elements == null) return false; | 414 if (elements == null) return false; |
| 415 if (elements.isEmpty) return false; | 415 if (elements.isEmpty) return false; |
| 416 return elements.any((element) => selector.applies(element, compiler)); | 416 return elements.any((element) => selector.applies(element, compiler)); |
| 417 } | 417 } |
| 418 | 418 |
| 419 final Map<String, Set<ClassElement>> interceptedClassesCache = | 419 final Map<String, Set<ClassElement>> interceptedClassesCache = |
| 420 new Map<String, Set<ClassElement>>(); | 420 new Map<String, Set<ClassElement>>(); |
| 421 | 421 |
| 422 /** | 422 /** |
| 423 * Returns a set of interceptor classes that contain a member named | 423 * Returns a set of interceptor classes that contain a member named |
| 424 * [name]. Returns [:null:] if there is no class. | 424 * [name]. Returns [:null:] if there is no class. |
| 425 */ | 425 */ |
| 426 Set<ClassElement> getInterceptedClassesOn(String name) { | 426 Set<ClassElement> getInterceptedClassesOn(String name) { |
| 427 Set<Element> intercepted = interceptedElements[name]; | 427 Set<Element> intercepted = interceptedElements[name]; |
| 428 if (intercepted == null) return null; | 428 if (intercepted == null) return null; |
| 429 return interceptedClassesCache.putIfAbsent(name, () { | 429 return interceptedClassesCache.putIfAbsent(name, () { |
| 430 // Populate the cache by running through all the elements and | 430 // Populate the cache by running through all the elements and |
| 431 // determine if the given selector applies to them. | 431 // determine if the given selector applies to them. |
| 432 Set<ClassElement> result = new Set<ClassElement>(); | 432 Set<ClassElement> result = new Set<ClassElement>(); |
| 433 for (Element element in intercepted) { | 433 for (Element element in intercepted) { |
| 434 ClassElement classElement = element.getEnclosingClass(); | 434 ClassElement classElement = element.enclosingClass; |
| 435 if (Elements.isNativeOrExtendsNative(classElement) | 435 if (Elements.isNativeOrExtendsNative(classElement) |
| 436 || interceptedClasses.contains(classElement)) { | 436 || interceptedClasses.contains(classElement)) { |
| 437 result.add(classElement); | 437 result.add(classElement); |
| 438 } | 438 } |
| 439 if (classesMixedIntoInterceptedClasses.contains(classElement)) { | 439 if (classesMixedIntoInterceptedClasses.contains(classElement)) { |
| 440 Set<ClassElement> nativeSubclasses = | 440 Set<ClassElement> nativeSubclasses = |
| 441 nativeSubclassesOfMixin(classElement); | 441 nativeSubclassesOfMixin(classElement); |
| 442 if (nativeSubclasses != null) result.addAll(nativeSubclasses); | 442 if (nativeSubclasses != null) result.addAll(nativeSubclasses); |
| 443 } | 443 } |
| 444 } | 444 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 459 result.add(subclass); | 459 result.add(subclass); |
| 460 } | 460 } |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 } | 463 } |
| 464 return result; | 464 return result; |
| 465 } | 465 } |
| 466 | 466 |
| 467 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { | 467 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { |
| 468 return specialOperatorEqClasses.contains( | 468 return specialOperatorEqClasses.contains( |
| 469 operatorEqfunction.getEnclosingClass()); | 469 operatorEqfunction.enclosingClass); |
| 470 } | 470 } |
| 471 | 471 |
| 472 void initializeHelperClasses() { | 472 void initializeHelperClasses() { |
| 473 getInterceptorMethod = compiler.findInterceptor('getInterceptor'); | 473 getInterceptorMethod = compiler.findInterceptor('getInterceptor'); |
| 474 interceptedNames = compiler.findInterceptor('interceptedNames'); | 474 interceptedNames = compiler.findInterceptor('interceptedNames'); |
| 475 mapTypeToInterceptor = compiler.findInterceptor('mapTypeToInterceptor'); | 475 mapTypeToInterceptor = compiler.findInterceptor('mapTypeToInterceptor'); |
| 476 getNativeInterceptorMethod = | 476 getNativeInterceptorMethod = |
| 477 compiler.findInterceptor('getNativeInterceptor'); | 477 compiler.findInterceptor('getNativeInterceptor'); |
| 478 | 478 |
| 479 // These methods are overwritten with generated versions. | 479 // These methods are overwritten with generated versions. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 if (jsFixedArrayClass != null) { | 521 if (jsFixedArrayClass != null) { |
| 522 jsFixedArrayClass.ensureResolved(compiler); | 522 jsFixedArrayClass.ensureResolved(compiler); |
| 523 } | 523 } |
| 524 if (jsExtendableArrayClass != null) { | 524 if (jsExtendableArrayClass != null) { |
| 525 jsExtendableArrayClass.ensureResolved(compiler); | 525 jsExtendableArrayClass.ensureResolved(compiler); |
| 526 } | 526 } |
| 527 | 527 |
| 528 jsIndexableClass.ensureResolved(compiler); | 528 jsIndexableClass.ensureResolved(compiler); |
| 529 jsIndexableLength = compiler.lookupElementIn( | 529 jsIndexableLength = compiler.lookupElementIn( |
| 530 jsIndexableClass, 'length'); | 530 jsIndexableClass, 'length'); |
| 531 if (jsIndexableLength != null && jsIndexableLength.isAbstractField()) { | 531 if (jsIndexableLength != null && jsIndexableLength.isAbstractField) { |
| 532 AbstractFieldElement element = jsIndexableLength; | 532 AbstractFieldElement element = jsIndexableLength; |
| 533 jsIndexableLength = element.getter; | 533 jsIndexableLength = element.getter; |
| 534 } | 534 } |
| 535 | 535 |
| 536 jsArrayClass.ensureResolved(compiler); | 536 jsArrayClass.ensureResolved(compiler); |
| 537 jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); | 537 jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); |
| 538 jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); | 538 jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); |
| 539 jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); | 539 jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); |
| 540 | 540 |
| 541 jsStringClass.ensureResolved(compiler); | 541 jsStringClass.ensureResolved(compiler); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 noThrowsClass = compiler.findHelper('NoThrows'); | 574 noThrowsClass = compiler.findHelper('NoThrows'); |
| 575 noInlineClass = compiler.findHelper('NoInline'); | 575 noInlineClass = compiler.findHelper('NoInline'); |
| 576 irRepresentationClass = compiler.findHelper('IrRepresentation'); | 576 irRepresentationClass = compiler.findHelper('IrRepresentation'); |
| 577 } | 577 } |
| 578 | 578 |
| 579 void validateInterceptorImplementsAllObjectMethods( | 579 void validateInterceptorImplementsAllObjectMethods( |
| 580 ClassElement interceptorClass) { | 580 ClassElement interceptorClass) { |
| 581 if (interceptorClass == null) return; | 581 if (interceptorClass == null) return; |
| 582 interceptorClass.ensureResolved(compiler); | 582 interceptorClass.ensureResolved(compiler); |
| 583 compiler.objectClass.forEachMember((_, Element member) { | 583 compiler.objectClass.forEachMember((_, Element member) { |
| 584 if (member.isGenerativeConstructor()) return; | 584 if (member.isGenerativeConstructor) return; |
| 585 Element interceptorMember = interceptorClass.lookupMember(member.name); | 585 Element interceptorMember = interceptorClass.lookupMember(member.name); |
| 586 // Interceptors must override all Object methods due to calling convention | 586 // Interceptors must override all Object methods due to calling convention |
| 587 // differences. | 587 // differences. |
| 588 assert(interceptorMember.getEnclosingClass() == interceptorClass); | 588 assert(interceptorMember.enclosingClass == interceptorClass); |
| 589 }); | 589 }); |
| 590 } | 590 } |
| 591 | 591 |
| 592 void addInterceptorsForNativeClassMembers( | 592 void addInterceptorsForNativeClassMembers( |
| 593 ClassElement cls, Enqueuer enqueuer) { | 593 ClassElement cls, Enqueuer enqueuer) { |
| 594 if (enqueuer.isResolutionQueue) { | 594 if (enqueuer.isResolutionQueue) { |
| 595 cls.ensureResolved(compiler); | 595 cls.ensureResolved(compiler); |
| 596 cls.forEachMember((ClassElement classElement, Element member) { | 596 cls.forEachMember((ClassElement classElement, Element member) { |
| 597 if (member.name == Compiler.CALL_OPERATOR_NAME) { | 597 if (member.name == Compiler.CALL_OPERATOR_NAME) { |
| 598 compiler.reportError( | 598 compiler.reportError( |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, elements); | 752 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, elements); |
| 753 } else if (cls == mapLiteralClass) { | 753 } else if (cls == mapLiteralClass) { |
| 754 // For map literals, the dependency between the implementation class | 754 // For map literals, the dependency between the implementation class |
| 755 // and [Map] is not visible, so we have to add it manually. | 755 // and [Map] is not visible, so we have to add it manually. |
| 756 Element getFactory(String name, int arity) { | 756 Element getFactory(String name, int arity) { |
| 757 // The constructor is on the patch class, but dart2js unit tests don't | 757 // The constructor is on the patch class, but dart2js unit tests don't |
| 758 // have a patch class. | 758 // have a patch class. |
| 759 ClassElement implementation = cls.patch != null ? cls.patch : cls; | 759 ClassElement implementation = cls.patch != null ? cls.patch : cls; |
| 760 return implementation.lookupConstructor( | 760 return implementation.lookupConstructor( |
| 761 new Selector.callConstructor( | 761 new Selector.callConstructor( |
| 762 name, mapLiteralClass.getLibrary(), arity), | 762 name, mapLiteralClass.library, arity), |
| 763 (element) { | 763 (element) { |
| 764 compiler.internalError(mapLiteralClass, | 764 compiler.internalError(mapLiteralClass, |
| 765 "Map literal class $mapLiteralClass missing " | 765 "Map literal class $mapLiteralClass missing " |
| 766 "'$name' constructor" | 766 "'$name' constructor" |
| 767 " ${mapLiteralClass.constructors}"); | 767 " ${mapLiteralClass.constructors}"); |
| 768 }); | 768 }); |
| 769 } | 769 } |
| 770 mapLiteralConstructor = getFactory('_literal', 1); | 770 mapLiteralConstructor = getFactory('_literal', 1); |
| 771 mapLiteralConstructorEmpty = getFactory('_empty', 0); | 771 mapLiteralConstructorEmpty = getFactory('_empty', 0); |
| 772 enqueueInResolution(mapLiteralConstructor, elements); | 772 enqueueInResolution(mapLiteralConstructor, elements); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 } | 893 } |
| 894 | 894 |
| 895 void registerTypeLiteral(Element element, | 895 void registerTypeLiteral(Element element, |
| 896 Enqueuer enqueuer, | 896 Enqueuer enqueuer, |
| 897 TreeElements elements) { | 897 TreeElements elements) { |
| 898 enqueuer.registerInstantiatedClass(typeImplementation, elements); | 898 enqueuer.registerInstantiatedClass(typeImplementation, elements); |
| 899 enqueueInResolution(getCreateRuntimeType(), elements); | 899 enqueueInResolution(getCreateRuntimeType(), elements); |
| 900 // TODO(ahe): Might want to register [element] as an instantiated class | 900 // TODO(ahe): Might want to register [element] as an instantiated class |
| 901 // when reflection is used. However, as long as we disable tree-shaking | 901 // when reflection is used. However, as long as we disable tree-shaking |
| 902 // eagerly it doesn't matter. | 902 // eagerly it doesn't matter. |
| 903 if (element.isTypedef()) { | 903 if (element.isTypedef) { |
| 904 typedefTypeLiterals.add(element); | 904 typedefTypeLiterals.add(element); |
| 905 } | 905 } |
| 906 customElementsAnalysis.registerTypeLiteral(element, enqueuer); | 906 customElementsAnalysis.registerTypeLiteral(element, enqueuer); |
| 907 } | 907 } |
| 908 | 908 |
| 909 void registerStackTraceInCatch(TreeElements elements) { | 909 void registerStackTraceInCatch(TreeElements elements) { |
| 910 enqueueInResolution(getTraceFromException(), elements); | 910 enqueueInResolution(getTraceFromException(), elements); |
| 911 } | 911 } |
| 912 | 912 |
| 913 void registerGetRuntimeTypeArgument(TreeElements elements) { | 913 void registerGetRuntimeTypeArgument(TreeElements elements) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 if (inCheckedMode) { | 999 if (inCheckedMode) { |
| 1000 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); | 1000 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); |
| 1001 } | 1001 } |
| 1002 } | 1002 } |
| 1003 enqueueClass(world, compiler.listClass, elements); | 1003 enqueueClass(world, compiler.listClass, elements); |
| 1004 } | 1004 } |
| 1005 if (type is FunctionType) { | 1005 if (type is FunctionType) { |
| 1006 enqueueInResolution( | 1006 enqueueInResolution( |
| 1007 compiler.findHelper('functionTypeTestMetaHelper'), elements); | 1007 compiler.findHelper('functionTypeTestMetaHelper'), elements); |
| 1008 } | 1008 } |
| 1009 if (type.element.isNative()) { | 1009 if (type.element.isNative) { |
| 1010 // We will neeed to add the "$is" and "$as" properties on the | 1010 // We will neeed to add the "$is" and "$as" properties on the |
| 1011 // JavaScript object prototype, so we make sure | 1011 // JavaScript object prototype, so we make sure |
| 1012 // [:defineProperty:] is compiled. | 1012 // [:defineProperty:] is compiled. |
| 1013 enqueue(world, | 1013 enqueue(world, |
| 1014 compiler.findHelper('defineProperty'), | 1014 compiler.findHelper('defineProperty'), |
| 1015 elements); | 1015 elements); |
| 1016 } | 1016 } |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 void registerAsCheck(DartType type, Enqueuer world, TreeElements elements) { | 1019 void registerAsCheck(DartType type, Enqueuer world, TreeElements elements) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 void registerRequiredType(DartType type, Element enclosingElement) { | 1089 void registerRequiredType(DartType type, Element enclosingElement) { |
| 1090 // If [argument] has type variables or is a type variable, this method | 1090 // If [argument] has type variables or is a type variable, this method |
| 1091 // registers a RTI dependency between the class where the type variable is | 1091 // registers a RTI dependency between the class where the type variable is |
| 1092 // defined (that is the enclosing class of the current element being | 1092 // defined (that is the enclosing class of the current element being |
| 1093 // resolved) and the class of [type]. If the class of [type] requires RTI, | 1093 // resolved) and the class of [type]. If the class of [type] requires RTI, |
| 1094 // then the class of the type variable does too. | 1094 // then the class of the type variable does too. |
| 1095 ClassElement contextClass = Types.getClassContext(type); | 1095 ClassElement contextClass = Types.getClassContext(type); |
| 1096 if (contextClass != null) { | 1096 if (contextClass != null) { |
| 1097 assert(contextClass == enclosingElement.getEnclosingClass().declaration); | 1097 assert(contextClass == enclosingElement.enclosingClass.declaration); |
| 1098 rti.registerRtiDependency(type.element, contextClass); | 1098 rti.registerRtiDependency(type.element, contextClass); |
| 1099 } | 1099 } |
| 1100 } | 1100 } |
| 1101 | 1101 |
| 1102 void registerClassUsingVariableExpression(ClassElement cls) { | 1102 void registerClassUsingVariableExpression(ClassElement cls) { |
| 1103 rti.classesUsingTypeVariableExpression.add(cls); | 1103 rti.classesUsingTypeVariableExpression.add(cls); |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 bool classNeedsRti(ClassElement cls) { | 1106 bool classNeedsRti(ClassElement cls) { |
| 1107 return rti.classesNeedingRti.contains(cls.declaration) || | 1107 return rti.classesNeedingRti.contains(cls.declaration) || |
| 1108 compiler.enabledRuntimeType; | 1108 compiler.enabledRuntimeType; |
| 1109 } | 1109 } |
| 1110 | 1110 |
| 1111 bool isDefaultNoSuchMethodImplementation(Element element) { | 1111 bool isDefaultNoSuchMethodImplementation(Element element) { |
| 1112 assert(element.name == Compiler.NO_SUCH_METHOD); | 1112 assert(element.name == Compiler.NO_SUCH_METHOD); |
| 1113 ClassElement classElement = element.getEnclosingClass(); | 1113 ClassElement classElement = element.enclosingClass; |
| 1114 return classElement == compiler.objectClass | 1114 return classElement == compiler.objectClass |
| 1115 || classElement == jsInterceptorClass | 1115 || classElement == jsInterceptorClass |
| 1116 || classElement == jsNullClass; | 1116 || classElement == jsNullClass; |
| 1117 } | 1117 } |
| 1118 | 1118 |
| 1119 bool isDefaultEqualityImplementation(Element element) { | 1119 bool isDefaultEqualityImplementation(Element element) { |
| 1120 assert(element.name == '=='); | 1120 assert(element.name == '=='); |
| 1121 ClassElement classElement = element.getEnclosingClass(); | 1121 ClassElement classElement = element.enclosingClass; |
| 1122 return classElement == compiler.objectClass | 1122 return classElement == compiler.objectClass |
| 1123 || classElement == jsInterceptorClass | 1123 || classElement == jsInterceptorClass |
| 1124 || classElement == jsNullClass; | 1124 || classElement == jsNullClass; |
| 1125 } | 1125 } |
| 1126 | 1126 |
| 1127 bool methodNeedsRti(FunctionElement function) { | 1127 bool methodNeedsRti(FunctionElement function) { |
| 1128 return rti.methodsNeedingRti.contains(function) || | 1128 return rti.methodsNeedingRti.contains(function) || |
| 1129 compiler.enabledRuntimeType; | 1129 compiler.enabledRuntimeType; |
| 1130 } | 1130 } |
| 1131 | 1131 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 enqueue(MapConstant.DART_CLASS); | 1171 enqueue(MapConstant.DART_CLASS); |
| 1172 enqueue(MapConstant.DART_PROTO_CLASS); | 1172 enqueue(MapConstant.DART_PROTO_CLASS); |
| 1173 enqueue(MapConstant.DART_STRING_CLASS); | 1173 enqueue(MapConstant.DART_STRING_CLASS); |
| 1174 enqueue(MapConstant.DART_GENERAL_CLASS); | 1174 enqueue(MapConstant.DART_GENERAL_CLASS); |
| 1175 } | 1175 } |
| 1176 | 1176 |
| 1177 void codegen(CodegenWorkItem work) { | 1177 void codegen(CodegenWorkItem work) { |
| 1178 Element element = work.element; | 1178 Element element = work.element; |
| 1179 var kind = element.kind; | 1179 var kind = element.kind; |
| 1180 if (kind == ElementKind.TYPEDEF) return; | 1180 if (kind == ElementKind.TYPEDEF) return; |
| 1181 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) { | 1181 if (element.isConstructor && element.enclosingClass == jsNullClass) { |
| 1182 // Work around a problem compiling JSNull's constructor. | 1182 // Work around a problem compiling JSNull's constructor. |
| 1183 return; | 1183 return; |
| 1184 } | 1184 } |
| 1185 if (kind.category == ElementCategory.VARIABLE) { | 1185 if (kind.category == ElementCategory.VARIABLE) { |
| 1186 Constant initialValue = constants.getConstantForVariable(element); | 1186 Constant initialValue = constants.getConstantForVariable(element); |
| 1187 if (initialValue != null) { | 1187 if (initialValue != null) { |
| 1188 registerCompileTimeConstant(initialValue, work.resolutionTree); | 1188 registerCompileTimeConstant(initialValue, work.resolutionTree); |
| 1189 constants.addCompileTimeConstantForEmission(initialValue); | 1189 constants.addCompileTimeConstantForEmission(initialValue); |
| 1190 // We don't need to generate code for static or top-level | 1190 // We don't need to generate code for static or top-level |
| 1191 // variables. For instance variables, we may need to generate | 1191 // variables. For instance variables, we may need to generate |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1208 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { | 1208 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { |
| 1209 return new native.NativeResolutionEnqueuer(world, compiler); | 1209 return new native.NativeResolutionEnqueuer(world, compiler); |
| 1210 } | 1210 } |
| 1211 | 1211 |
| 1212 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { | 1212 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { |
| 1213 return new native.NativeCodegenEnqueuer(world, compiler, emitter); | 1213 return new native.NativeCodegenEnqueuer(world, compiler, emitter); |
| 1214 } | 1214 } |
| 1215 | 1215 |
| 1216 ClassElement defaultSuperclass(ClassElement element) { | 1216 ClassElement defaultSuperclass(ClassElement element) { |
| 1217 // Native classes inherit from Interceptor. | 1217 // Native classes inherit from Interceptor. |
| 1218 return element.isNative() ? jsInterceptorClass : compiler.objectClass; | 1218 return element.isNative ? jsInterceptorClass : compiler.objectClass; |
| 1219 } | 1219 } |
| 1220 | 1220 |
| 1221 /** | 1221 /** |
| 1222 * Unit test hook that returns code of an element as a String. | 1222 * Unit test hook that returns code of an element as a String. |
| 1223 * | 1223 * |
| 1224 * Invariant: [element] must be a declaration element. | 1224 * Invariant: [element] must be a declaration element. |
| 1225 */ | 1225 */ |
| 1226 String assembleCode(Element element) { | 1226 String assembleCode(Element element) { |
| 1227 assert(invariant(element, element.isDeclaration)); | 1227 assert(invariant(element, element.isDeclaration)); |
| 1228 return jsAst.prettyPrint(generatedCode[element], compiler).getText(); | 1228 return jsAst.prettyPrint(generatedCode[element], compiler).getText(); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 if (element == disableTreeShakingMarker) { | 1579 if (element == disableTreeShakingMarker) { |
| 1580 compiler.disableTypeInferenceForMirrors = true; | 1580 compiler.disableTypeInferenceForMirrors = true; |
| 1581 isTreeShakingDisabled = true; | 1581 isTreeShakingDisabled = true; |
| 1582 typeVariableHandler.onTreeShakingDisabled(enqueuer); | 1582 typeVariableHandler.onTreeShakingDisabled(enqueuer); |
| 1583 } else if (element == preserveNamesMarker) { | 1583 } else if (element == preserveNamesMarker) { |
| 1584 mustPreserveNames = true; | 1584 mustPreserveNames = true; |
| 1585 } else if (element == preserveMetadataMarker) { | 1585 } else if (element == preserveMetadataMarker) { |
| 1586 mustRetainMetadata = true; | 1586 mustRetainMetadata = true; |
| 1587 } else if (element == getIsolateAffinityTagMarker) { | 1587 } else if (element == getIsolateAffinityTagMarker) { |
| 1588 needToInitializeIsolateAffinityTag = true; | 1588 needToInitializeIsolateAffinityTag = true; |
| 1589 } else if (element.isDeferredLoaderGetter()) { | 1589 } else if (element.isDeferredLoaderGetter) { |
| 1590 // TODO(sigurdm): Create a function registerLoadLibraryAccess. | 1590 // TODO(sigurdm): Create a function registerLoadLibraryAccess. |
| 1591 if (compiler.loadLibraryFunction == null) { | 1591 if (compiler.loadLibraryFunction == null) { |
| 1592 compiler.loadLibraryFunction = | 1592 compiler.loadLibraryFunction = |
| 1593 compiler.findHelper("_loadLibraryWrapper"); | 1593 compiler.findHelper("_loadLibraryWrapper"); |
| 1594 enqueueInResolution(compiler.loadLibraryFunction, | 1594 enqueueInResolution(compiler.loadLibraryFunction, |
| 1595 compiler.globalDependencies); | 1595 compiler.globalDependencies); |
| 1596 } | 1596 } |
| 1597 } | 1597 } |
| 1598 customElementsAnalysis.registerStaticUse(element, enqueuer); | 1598 customElementsAnalysis.registerStaticUse(element, enqueuer); |
| 1599 } | 1599 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1666 Set<Element> metaTargets) { | 1666 Set<Element> metaTargets) { |
| 1667 if (symbols == null && targets == null && metaTargets == null) { | 1667 if (symbols == null && targets == null && metaTargets == null) { |
| 1668 // The user didn't specify anything, or there are imports of | 1668 // The user didn't specify anything, or there are imports of |
| 1669 // 'dart:mirrors' without @MirrorsUsed. | 1669 // 'dart:mirrors' without @MirrorsUsed. |
| 1670 hasInsufficientMirrorsUsed = true; | 1670 hasInsufficientMirrorsUsed = true; |
| 1671 return; | 1671 return; |
| 1672 } | 1672 } |
| 1673 if (symbols != null) symbolsUsed.addAll(symbols); | 1673 if (symbols != null) symbolsUsed.addAll(symbols); |
| 1674 if (targets != null) { | 1674 if (targets != null) { |
| 1675 for (Element target in targets) { | 1675 for (Element target in targets) { |
| 1676 if (target.isAbstractField()) { | 1676 if (target.isAbstractField) { |
| 1677 AbstractFieldElement field = target; | 1677 AbstractFieldElement field = target; |
| 1678 targetsUsed.add(field.getter); | 1678 targetsUsed.add(field.getter); |
| 1679 targetsUsed.add(field.setter); | 1679 targetsUsed.add(field.setter); |
| 1680 } else { | 1680 } else { |
| 1681 targetsUsed.add(target); | 1681 targetsUsed.add(target); |
| 1682 } | 1682 } |
| 1683 } | 1683 } |
| 1684 } | 1684 } |
| 1685 if (metaTargets != null) metaTargetsUsed.addAll(metaTargets); | 1685 if (metaTargets != null) metaTargetsUsed.addAll(metaTargets); |
| 1686 } | 1686 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1706 * is no direct use in the program, but because the reflective system may | 1706 * is no direct use in the program, but because the reflective system may |
| 1707 * need to access it. | 1707 * need to access it. |
| 1708 */ | 1708 */ |
| 1709 bool isNeededForReflection(Element element) { | 1709 bool isNeededForReflection(Element element) { |
| 1710 element = getDartClass(element); | 1710 element = getDartClass(element); |
| 1711 if (hasInsufficientMirrorsUsed) return isTreeShakingDisabled; | 1711 if (hasInsufficientMirrorsUsed) return isTreeShakingDisabled; |
| 1712 /// Record the name of [element] in [symbolsUsed]. Return true for | 1712 /// Record the name of [element] in [symbolsUsed]. Return true for |
| 1713 /// convenience. | 1713 /// convenience. |
| 1714 bool registerNameOf(Element element) { | 1714 bool registerNameOf(Element element) { |
| 1715 symbolsUsed.add(element.name); | 1715 symbolsUsed.add(element.name); |
| 1716 if (element.isConstructor()) { | 1716 if (element.isConstructor) { |
| 1717 symbolsUsed.add(element.getEnclosingClass().name); | 1717 symbolsUsed.add(element.enclosingClass.name); |
| 1718 } | 1718 } |
| 1719 return true; | 1719 return true; |
| 1720 } | 1720 } |
| 1721 | 1721 |
| 1722 Element enclosing = element.enclosingElement; | 1722 Element enclosing = element.enclosingElement; |
| 1723 if (enclosing != null && isNeededForReflection(enclosing)) { | 1723 if (enclosing != null && isNeededForReflection(enclosing)) { |
| 1724 return registerNameOf(element); | 1724 return registerNameOf(element); |
| 1725 } | 1725 } |
| 1726 | 1726 |
| 1727 if (isNeededThroughMetaTarget(element)) { | 1727 if (isNeededThroughMetaTarget(element)) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 } | 1792 } |
| 1793 | 1793 |
| 1794 /// Returns all static fields that are referenced through [targetsUsed]. | 1794 /// Returns all static fields that are referenced through [targetsUsed]. |
| 1795 /// If the target is a library or class all nested static fields are | 1795 /// If the target is a library or class all nested static fields are |
| 1796 /// included too. | 1796 /// included too. |
| 1797 Iterable<Element> _findStaticFieldTargets() { | 1797 Iterable<Element> _findStaticFieldTargets() { |
| 1798 List staticFields = []; | 1798 List staticFields = []; |
| 1799 | 1799 |
| 1800 void addFieldsInContainer(ScopeContainerElement container) { | 1800 void addFieldsInContainer(ScopeContainerElement container) { |
| 1801 container.forEachLocalMember((Element member) { | 1801 container.forEachLocalMember((Element member) { |
| 1802 if (!member.isInstanceMember() && member.isField()) { | 1802 if (!member.isInstanceMember && member.isField) { |
| 1803 staticFields.add(member); | 1803 staticFields.add(member); |
| 1804 } else if (member.isClass()) { | 1804 } else if (member.isClass) { |
| 1805 addFieldsInContainer(member); | 1805 addFieldsInContainer(member); |
| 1806 } | 1806 } |
| 1807 }); | 1807 }); |
| 1808 } | 1808 } |
| 1809 | 1809 |
| 1810 for (Element target in targetsUsed) { | 1810 for (Element target in targetsUsed) { |
| 1811 if (target == null) continue; | 1811 if (target == null) continue; |
| 1812 if (target.isField()) { | 1812 if (target.isField) { |
| 1813 staticFields.add(target); | 1813 staticFields.add(target); |
| 1814 } else if (target.isLibrary() || target.isClass()) { | 1814 } else if (target.isLibrary || target.isClass) { |
| 1815 addFieldsInContainer(target); | 1815 addFieldsInContainer(target); |
| 1816 } | 1816 } |
| 1817 } | 1817 } |
| 1818 return staticFields; | 1818 return staticFields; |
| 1819 } | 1819 } |
| 1820 | 1820 |
| 1821 /// Called when [enqueuer] is empty, but before it is closed. | 1821 /// Called when [enqueuer] is empty, but before it is closed. |
| 1822 void onQueueEmpty(Enqueuer enqueuer) { | 1822 void onQueueEmpty(Enqueuer enqueuer) { |
| 1823 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { | 1823 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { |
| 1824 preMirrorsMethodCount = generatedCode.length; | 1824 preMirrorsMethodCount = generatedCode.length; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1843 registerCompileTimeConstant( | 1843 registerCompileTimeConstant( |
| 1844 dependency.constant, dependency.user); | 1844 dependency.constant, dependency.user); |
| 1845 } | 1845 } |
| 1846 metadataConstants.clear(); | 1846 metadataConstants.clear(); |
| 1847 } | 1847 } |
| 1848 | 1848 |
| 1849 customElementsAnalysis.onQueueEmpty(enqueuer); | 1849 customElementsAnalysis.onQueueEmpty(enqueuer); |
| 1850 } | 1850 } |
| 1851 | 1851 |
| 1852 void onElementResolved(Element element, TreeElements elements) { | 1852 void onElementResolved(Element element, TreeElements elements) { |
| 1853 LibraryElement library = element.getLibrary(); | 1853 LibraryElement library = element.library; |
| 1854 if (!library.isPlatformLibrary && !library.canUseNative) return; | 1854 if (!library.isPlatformLibrary && !library.canUseNative) return; |
| 1855 bool hasNoInline = false; | 1855 bool hasNoInline = false; |
| 1856 bool hasNoThrows = false; | 1856 bool hasNoThrows = false; |
| 1857 bool hasNoSideEffects = false; | 1857 bool hasNoSideEffects = false; |
| 1858 for (MetadataAnnotation metadata in element.metadata) { | 1858 for (MetadataAnnotation metadata in element.metadata) { |
| 1859 metadata.ensureResolved(compiler); | 1859 metadata.ensureResolved(compiler); |
| 1860 if (!metadata.value.isConstructedObject) continue; | 1860 if (!metadata.value.isConstructedObject) continue; |
| 1861 ObjectConstant value = metadata.value; | 1861 ObjectConstant value = metadata.value; |
| 1862 ClassElement cls = value.type.element; | 1862 ClassElement cls = value.type.element; |
| 1863 if (cls == noInlineClass) { | 1863 if (cls == noInlineClass) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1908 } | 1908 } |
| 1909 } | 1909 } |
| 1910 | 1910 |
| 1911 /// Records that [constant] is used by [user.element]. | 1911 /// Records that [constant] is used by [user.element]. |
| 1912 class Dependency { | 1912 class Dependency { |
| 1913 final Constant constant; | 1913 final Constant constant; |
| 1914 final TreeElements user; | 1914 final TreeElements user; |
| 1915 | 1915 |
| 1916 const Dependency(this.constant, this.user); | 1916 const Dependency(this.constant, this.user); |
| 1917 } | 1917 } |
| OLD | NEW |