| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import '../closure.dart'; | 5 import '../closure.dart'; |
| 6 import '../common.dart'; | 6 import '../common.dart'; |
| 7 import '../common_elements.dart'; | 7 import '../common_elements.dart'; |
| 8 import '../compiler.dart'; | 8 import '../compiler.dart'; |
| 9 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 } | 386 } |
| 387 | 387 |
| 388 bool isAccessibleByReflection(Element element) { | 388 bool isAccessibleByReflection(Element element) { |
| 389 if (element.isLibrary) { | 389 if (element.isLibrary) { |
| 390 return false; | 390 return false; |
| 391 } else if (element.isClass) { | 391 } else if (element.isClass) { |
| 392 return isClassAccessibleByReflection(element); | 392 return isClassAccessibleByReflection(element); |
| 393 } else if (element.isTypedef) { | 393 } else if (element.isTypedef) { |
| 394 return isTypedefAccessibleByReflection(element); | 394 return isTypedefAccessibleByReflection(element); |
| 395 } else { | 395 } else { |
| 396 return isMemberAccessibleByReflection(element); | 396 MemberElement member = element; |
| 397 return isMemberAccessibleByReflection(member); |
| 397 } | 398 } |
| 398 } | 399 } |
| 399 | 400 |
| 400 ClassElement _getDartClass(ClassElement cls) { | 401 ClassElement _getDartClass(ClassElement cls) { |
| 401 if (cls == _commonElements.jsIntClass) { | 402 if (cls == _commonElements.jsIntClass) { |
| 402 return _commonElements.intClass; | 403 return _commonElements.intClass; |
| 403 } else if (cls == _commonElements.jsBoolClass) { | 404 } else if (cls == _commonElements.jsBoolClass) { |
| 404 return _commonElements.boolClass; | 405 return _commonElements.boolClass; |
| 405 } else if (cls == _commonElements.jsNumberClass) { | 406 } else if (cls == _commonElements.jsNumberClass) { |
| 406 return _commonElements.numClass; | 407 return _commonElements.numClass; |
| 407 } else if (cls == _commonElements.jsDoubleClass) { | 408 } else if (cls == _commonElements.jsDoubleClass) { |
| 408 return _commonElements.doubleClass; | 409 return _commonElements.doubleClass; |
| 409 } else if (cls == _commonElements.jsStringClass) { | 410 } else if (cls == _commonElements.jsStringClass) { |
| 410 return _commonElements.stringClass; | 411 return _commonElements.stringClass; |
| 411 } else if (cls == _commonElements.jsArrayClass) { | 412 } else if (cls == _commonElements.jsArrayClass) { |
| 412 return _commonElements.listClass; | 413 return _commonElements.listClass; |
| 413 } else if (cls == _commonElements.jsNullClass) { | 414 } else if (cls == _commonElements.jsNullClass) { |
| 414 return _commonElements.nullClass; | 415 return _commonElements.nullClass; |
| 415 } else { | 416 } else { |
| 416 return cls; | 417 return cls; |
| 417 } | 418 } |
| 418 } | 419 } |
| 419 | 420 |
| 420 bool isMemberAccessibleByReflection(MemberElement element) { | 421 bool isMemberAccessibleByReflection(MemberEntity element) { |
| 421 return _membersNeededForReflection.contains(element); | 422 return _membersNeededForReflection.contains(element); |
| 422 } | 423 } |
| 423 | 424 |
| 424 /// Returns true if this element has to be enqueued due to | 425 /// Returns true if this element has to be enqueued due to |
| 425 /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if | 426 /// mirror usage. Might be a subset of [referencedFromMirrorSystem] if |
| 426 /// normal tree shaking is still active ([isTreeShakingDisabled] is false). | 427 /// normal tree shaking is still active ([isTreeShakingDisabled] is false). |
| 427 bool requiredByMirrorSystem(Element element) { | 428 bool requiredByMirrorSystem(Element element) { |
| 428 return hasInsufficientMirrorsUsed && isTreeShakingDisabled || | 429 return hasInsufficientMirrorsUsed && isTreeShakingDisabled || |
| 429 matchesMirrorsMetaTarget(element) || | 430 matchesMirrorsMetaTarget(element) || |
| 430 classesInMirrorsUsedTargets.contains(element) || | 431 classesInMirrorsUsedTargets.contains(element) || |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 ConstantValue value = | 507 ConstantValue value = |
| 507 _compiler.constants.getConstantValue(metadata.constant); | 508 _compiler.constants.getConstantValue(metadata.constant); |
| 508 if (value == null) continue; | 509 if (value == null) continue; |
| 509 DartType type = value.getType(_commonElements); | 510 DartType type = value.getType(_commonElements); |
| 510 if (type is InterfaceType && metaTargetsUsed.contains(type.element)) | 511 if (type is InterfaceType && metaTargetsUsed.contains(type.element)) |
| 511 return true; | 512 return true; |
| 512 } | 513 } |
| 513 return false; | 514 return false; |
| 514 } | 515 } |
| 515 | 516 |
| 517 void createImmutableSets() { |
| 518 _classesNeededForReflection = const ImmutableEmptySet<ClassElement>(); |
| 519 _typedefsNeededForReflection = const ImmutableEmptySet<TypedefElement>(); |
| 520 _membersNeededForReflection = const ImmutableEmptySet<MemberElement>(); |
| 521 _closuresNeededForReflection = |
| 522 const ImmutableEmptySet<LocalFunctionElement>(); |
| 523 } |
| 524 |
| 516 /** | 525 /** |
| 517 * Visits all classes and computes whether its members are needed for | 526 * Visits all classes and computes whether its members are needed for |
| 518 * reflection. | 527 * reflection. |
| 519 * | 528 * |
| 520 * We have to precompute this set as we cannot easily answer the need for | 529 * We have to precompute this set as we cannot easily answer the need for |
| 521 * reflection locally when looking at the member: We lack the information by | 530 * reflection locally when looking at the member: We lack the information by |
| 522 * which classes a member is inherited. Called after resolution is complete. | 531 * which classes a member is inherited. Called after resolution is complete. |
| 523 * | 532 * |
| 524 * We filter out private libraries here, as their elements should not | 533 * We filter out private libraries here, as their elements should not |
| 525 * be visible by reflection unless some other interfaces makes them | 534 * be visible by reflection unless some other interfaces makes them |
| 526 * accessible. | 535 * accessible. |
| 527 */ | 536 */ |
| 528 void computeMembersNeededForReflection( | 537 void computeMembersNeededForReflection( |
| 529 ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) { | 538 ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) { |
| 530 if (_membersNeededForReflection != null) return; | 539 if (_membersNeededForReflection != null) return; |
| 531 if (closedWorld.commonElements.mirrorsLibrary == null) { | 540 if (closedWorld.commonElements.mirrorsLibrary == null) { |
| 532 _classesNeededForReflection = const ImmutableEmptySet<ClassElement>(); | 541 createImmutableSets(); |
| 533 _typedefsNeededForReflection = const ImmutableEmptySet<TypedefElement>(); | |
| 534 _membersNeededForReflection = const ImmutableEmptySet<MemberElement>(); | |
| 535 _closuresNeededForReflection = | |
| 536 const ImmutableEmptySet<LocalFunctionElement>(); | |
| 537 return; | 542 return; |
| 538 } | 543 } |
| 539 _classesNeededForReflection = new Set<ClassElement>(); | 544 _classesNeededForReflection = new Set<ClassElement>(); |
| 540 _typedefsNeededForReflection = new Set<TypedefElement>(); | 545 _typedefsNeededForReflection = new Set<TypedefElement>(); |
| 541 _membersNeededForReflection = new Set<MemberElement>(); | 546 _membersNeededForReflection = new Set<MemberElement>(); |
| 542 _closuresNeededForReflection = new Set<LocalFunctionElement>(); | 547 _closuresNeededForReflection = new Set<LocalFunctionElement>(); |
| 543 | 548 |
| 544 // Compute a mapping from class to the closures it contains, so we | 549 // Compute a mapping from class to the closures it contains, so we |
| 545 // can include the correct ones when including the class. | 550 // can include the correct ones when including the class. |
| 546 Map<ClassElement, List<LocalFunctionElement>> closureMap = | 551 Map<ClassElement, List<LocalFunctionElement>> closureMap = |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 } | 695 } |
| 691 | 696 |
| 692 /// Called when `const Symbol(name)` is seen. | 697 /// Called when `const Symbol(name)` is seen. |
| 693 void registerConstSymbol(String name) { | 698 void registerConstSymbol(String name) { |
| 694 symbolsUsed.add(name); | 699 symbolsUsed.add(name); |
| 695 if (name.endsWith('=')) { | 700 if (name.endsWith('=')) { |
| 696 symbolsUsed.add(name.substring(0, name.length - 1)); | 701 symbolsUsed.add(name.substring(0, name.length - 1)); |
| 697 } | 702 } |
| 698 } | 703 } |
| 699 } | 704 } |
| OLD | NEW |