Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 340783011: Take inheritance into account when computing the elements accessible by mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 /// True if a call to disableTreeShaking has been seen. 258 /// True if a call to disableTreeShaking has been seen.
259 bool isTreeShakingDisabled = false; 259 bool isTreeShakingDisabled = false;
260 260
261 /// True if there isn't sufficient @MirrorsUsed data. 261 /// True if there isn't sufficient @MirrorsUsed data.
262 bool hasInsufficientMirrorsUsed = false; 262 bool hasInsufficientMirrorsUsed = false;
263 263
264 /// List of constants from metadata. If metadata must be preserved, 264 /// List of constants from metadata. If metadata must be preserved,
265 /// these constants must be registered. 265 /// these constants must be registered.
266 final List<Dependency> metadataConstants = <Dependency>[]; 266 final List<Dependency> metadataConstants = <Dependency>[];
267 267
268 /// List of symbols that the user has requested for reflection.
269 final Set<String> symbolsUsed = new Set<String>();
270
271 /// List of elements that the user has requested for reflection. 268 /// List of elements that the user has requested for reflection.
272 final Set<Element> targetsUsed = new Set<Element>(); 269 final Set<Element> targetsUsed = new Set<Element>();
273 270
274 /// List of annotations provided by user that indicate that the annotated 271 /// List of annotations provided by user that indicate that the annotated
275 /// element must be retained. 272 /// element must be retained.
276 final Set<Element> metaTargetsUsed = new Set<Element>(); 273 final Set<Element> metaTargetsUsed = new Set<Element>();
277 274
275 /// Set of methods that are needed by reflection. Computed using
276 /// [computeMembersNeededForReflection] on first use.
277 Iterable<Element> _membersNeededForReflection = null;
278 Iterable<Element> get membersNeededForReflection {
279 assert(_membersNeededForReflection != null);
280 return _membersNeededForReflection;
281 }
282
283 /// List of symbols that the user has requested for reflection.
284 final Set<String> symbolsUsed = new Set<String>();
285
278 /// List of elements that the backend may use. 286 /// List of elements that the backend may use.
279 final Set<Element> helpersUsed = new Set<Element>(); 287 final Set<Element> helpersUsed = new Set<Element>();
280 288
281
282 /// Set of typedefs that are used as type literals. 289 /// Set of typedefs that are used as type literals.
283 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>(); 290 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>();
284 291
285 /// All the checked mode helpers. 292 /// All the checked mode helpers.
286 static const checkedModeHelpers = CheckedModeHelper.helpers; 293 static const checkedModeHelpers = CheckedModeHelper.helpers;
287 294
288 // Checked mode helpers indexed by name. 295 // Checked mode helpers indexed by name.
289 Map<String, CheckedModeHelper> checkedModeHelperByName = 296 Map<String, CheckedModeHelper> checkedModeHelperByName =
290 new Map<String, CheckedModeHelper>.fromIterable( 297 new Map<String, CheckedModeHelper>.fromIterable(
291 checkedModeHelpers, 298 checkedModeHelpers,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 if (invokedReflectively(element.enclosingElement)) return true; 353 if (invokedReflectively(element.enclosingElement)) return true;
347 } 354 }
348 355
349 if (element.isField) { 356 if (element.isField) {
350 if (Elements.isStaticOrTopLevel(element) 357 if (Elements.isStaticOrTopLevel(element)
351 && (element.isFinal || element.isConst)) { 358 && (element.isFinal || element.isConst)) {
352 return false; 359 return false;
353 } 360 }
354 } 361 }
355 362
356 return isNeededForReflection(element.declaration); 363 return isAccessibleByReflection(element.declaration);
357 } 364 }
358 365
359 bool canBeUsedForGlobalOptimizations(Element element) { 366 bool canBeUsedForGlobalOptimizations(Element element) {
360 return !usedByBackend(element) && !invokedReflectively(element); 367 return !usedByBackend(element) && !invokedReflectively(element);
361 } 368 }
362 369
363 bool isInterceptorClass(ClassElement element) { 370 bool isInterceptorClass(ClassElement element) {
364 if (element == null) return false; 371 if (element == null) return false;
365 if (Elements.isNativeOrExtendsNative(element)) return true; 372 if (Elements.isNativeOrExtendsNative(element)) return true;
366 if (interceptedClasses.contains(element)) return true; 373 if (interceptedClasses.contains(element)) return true;
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 if (e != null) enqueue(world, e, registry); 774 if (e != null) enqueue(world, e, registry);
768 } 775 }
769 if (TRACE_CALLS) { 776 if (TRACE_CALLS) {
770 traceHelper = compiler.findHelper('traceHelper'); 777 traceHelper = compiler.findHelper('traceHelper');
771 assert(traceHelper != null); 778 assert(traceHelper != null);
772 enqueueInResolution(traceHelper, registry); 779 enqueueInResolution(traceHelper, registry);
773 } 780 }
774 registerCheckedModeHelpers(registry); 781 registerCheckedModeHelpers(registry);
775 } 782 }
776 783
777 onResolutionComplete() => rti.computeClassesNeedingRti(); 784 onResolutionComplete() {
785 computeMembersNeededForReflection();
786 rti.computeClassesNeedingRti();
787 }
778 788
779 void onStringInterpolation(Registry registry) { 789 void onStringInterpolation(Registry registry) {
780 assert(registry.isForResolution); 790 assert(registry.isForResolution);
781 registerBackendStaticInvocation(getStringInterpolationHelper(), registry); 791 registerBackendStaticInvocation(getStringInterpolationHelper(), registry);
782 } 792 }
783 793
784 void onCatchStatement(Registry registry) { 794 void onCatchStatement(Registry registry) {
785 assert(registry.isForResolution); 795 assert(registry.isForResolution);
786 registerBackendStaticInvocation(getExceptionUnwrapper(), registry); 796 registerBackendStaticInvocation(getExceptionUnwrapper(), registry);
787 registerBackendInstantiation(jsPlainJavaScriptObjectClass, registry); 797 registerBackendInstantiation(jsPlainJavaScriptObjectClass, registry);
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 /// Called when resolving the `Symbol` constructor. 1577 /// Called when resolving the `Symbol` constructor.
1568 void onSymbolConstructor(Registry registry) { 1578 void onSymbolConstructor(Registry registry) {
1569 assert(registry.isForResolution); 1579 assert(registry.isForResolution);
1570 // Make sure that _internals.Symbol.validated is registered. 1580 // Make sure that _internals.Symbol.validated is registered.
1571 assert(compiler.symbolValidatedConstructor != null); 1581 assert(compiler.symbolValidatedConstructor != null);
1572 registerBackendStaticInvocation(compiler.symbolValidatedConstructor, 1582 registerBackendStaticInvocation(compiler.symbolValidatedConstructor,
1573 registry); 1583 registry);
1574 } 1584 }
1575 1585
1576 /// Should [element] (a getter) be retained for reflection? 1586 /// Should [element] (a getter) be retained for reflection?
1577 bool shouldRetainGetter(Element element) => isNeededForReflection(element); 1587 bool shouldRetainGetter(Element element) {
1588 return isAccessibleByReflection(element);
1589 }
1578 1590
1579 /// Should [element] (a setter) be retained for reflection? 1591 /// Should [element] (a setter) be retained for reflection?
1580 bool shouldRetainSetter(Element element) => isNeededForReflection(element); 1592 bool shouldRetainSetter(Element element) {
1593 return isAccessibleByReflection(element);
1594 }
1581 1595
1582 /// Should [name] be retained for reflection? 1596 /// Should [name] be retained for reflection?
1583 bool shouldRetainName(String name) { 1597 bool shouldRetainName(String name) {
1584 if (hasInsufficientMirrorsUsed) return mustPreserveNames; 1598 if (hasInsufficientMirrorsUsed) return mustPreserveNames;
1585 if (name == '') return false; 1599 if (name == '') return false;
1586 return symbolsUsed.contains(name); 1600 return symbolsUsed.contains(name);
1587 } 1601 }
1588 1602
1589 bool get rememberLazies => isTreeShakingDisabled; 1603 bool get rememberLazies => isTreeShakingDisabled;
1590 1604
1591 bool retainMetadataOf(Element element) { 1605 bool retainMetadataOf(Element element) {
1592 if (mustRetainMetadata) hasRetainedMetadata = true; 1606 if (mustRetainMetadata) hasRetainedMetadata = true;
1593 if (mustRetainMetadata && isNeededForReflection(element)) { 1607 if (mustRetainMetadata && referencedFromMirrorSystem(element)) {
1594 for (MetadataAnnotation metadata in element.metadata) { 1608 for (MetadataAnnotation metadata in element.metadata) {
1595 metadata.ensureResolved(compiler); 1609 metadata.ensureResolved(compiler);
1596 Constant constant = constants.getConstantForMetadata(metadata); 1610 Constant constant = constants.getConstantForMetadata(metadata);
1597 constants.addCompileTimeConstantForEmission(constant); 1611 constants.addCompileTimeConstantForEmission(constant);
1598 } 1612 }
1599 return true; 1613 return true;
1600 } 1614 }
1601 return false; 1615 return false;
1602 } 1616 }
1603 1617
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 /** 1782 /**
1769 * Returns `true` if [element] can be accessed through reflection, that is, 1783 * Returns `true` if [element] can be accessed through reflection, that is,
1770 * is in the set of elements covered by a `MirrorsUsed` annotation. 1784 * is in the set of elements covered by a `MirrorsUsed` annotation.
1771 * 1785 *
1772 * This property is used to tag emitted elements with a marker which is 1786 * This property is used to tag emitted elements with a marker which is
1773 * checked by the runtime system to throw an exception if an element is 1787 * checked by the runtime system to throw an exception if an element is
1774 * accessed (invoked, get, set) that is not accessible for the reflective 1788 * accessed (invoked, get, set) that is not accessible for the reflective
1775 * system. 1789 * system.
1776 */ 1790 */
1777 bool isAccessibleByReflection(Element element) { 1791 bool isAccessibleByReflection(Element element) {
1778 // TODO(ahe): This isn't sufficient: simply importing dart:mirrors 1792 if (element.isClass) {
1779 // causes hasInsufficientMirrorsUsed to become true. 1793 element = getDartClass(element);
1780 if (hasInsufficientMirrorsUsed) return true; 1794 }
1781 return isNeededForReflection(element); 1795 // We have to treat closure classes specially here, as they only come into
1796 // existence after [membersNeededForReflection] has been computed.
1797 if (element is SynthesizedCallMethodElementX) {
1798 SynthesizedCallMethodElementX closure = element;
1799 element = closure.expression;
Johnni Winther 2014/06/27 07:43:01 This could also be computed as closure.closureClas
herhut 2014/06/27 12:34:37 I think we have decided not to expose those fields
1800 } else if (element is ClosureClassElement) {
1801 ClosureClassElement closure = element;
1802 element = closure.methodElement;
1803 }
1804 return membersNeededForReflection.contains(element);
1782 } 1805 }
1783 1806
1784 /** 1807 /**
1785 * Returns `true` if the emitter must emit the element even though there 1808 * Returns true if the element has to be resolved due to a mirrorsUsed
1786 * is no direct use in the program, but because the reflective system may 1809 * annotation. If we have insufficient mirrors used annotations, we only
1787 * need to access it. 1810 * keep additonal elements if treeshaking has been disabled.
1788 */ 1811 */
1789 bool isNeededForReflection(Element element) { 1812 bool requiredByMirrorSystem(Element element) {
1790 if (!isTreeShakingDisabled) return false; 1813 return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
1791 element = getDartClass(element); 1814 matchesMirrorsMetaTarget(element) ||
1792 if (hasInsufficientMirrorsUsed) return isTreeShakingDisabled; 1815 targetsUsed.contains(element);
1793 /// Record the name of [element] in [symbolsUsed]. Return true for 1816 }
1794 /// convenience.
1795 bool registerNameOf(Element element) {
1796 symbolsUsed.add(element.name);
1797 if (element.isConstructor) {
1798 symbolsUsed.add(element.enclosingClass.name);
1799 }
1800 return true;
1801 }
1802 1817
1803 Element enclosing = element.enclosingElement; 1818 /**
1804 if (enclosing != null && isNeededForReflection(enclosing)) { 1819 * Returns true of the element matches a mirrorsUsed annotation. If
Johnni Winther 2014/06/27 07:43:01 'of' -> 'if'.
herhut 2014/06/27 12:34:37 Done.
1805 return registerNameOf(element); 1820 * we have insufficient mirrorsUsed information, this returns true for
1806 } 1821 * all elements, as they might all be potentially referenced.
1822 */
1823 bool referencedFromMirrorSystem(Element element, [recursive = true]) {
1824 Element enclosing = recursive ? element.enclosingElement : null;
1807 1825
1808 if (isNeededThroughMetaTarget(element)) { 1826 return hasInsufficientMirrorsUsed ||
1809 return registerNameOf(element); 1827 matchesMirrorsMetaTarget(element) ||
1810 } 1828 targetsUsed.contains(element) ||
1811 1829 (enclosing != null && referencedFromMirrorSystem(enclosing));
1812 if (!targetsUsed.isEmpty && targetsUsed.contains(element)) {
1813 return registerNameOf(element);
1814 }
1815
1816 // TODO(kasperl): Consider caching this information. It is consulted
1817 // multiple times because of the way we deal with the enclosing element.
1818 return false;
1819 } 1830 }
1820 1831
1821 /** 1832 /**
1822 * Returns `true` if the element is needed because it has an annotation 1833 * Returns `true` if the element is needed because it has an annotation
1823 * of a type that is used as a meta target for reflection. 1834 * of a type that is used as a meta target for reflection.
1824 */ 1835 */
1825 bool isNeededThroughMetaTarget(Element element) { 1836 bool matchesMirrorsMetaTarget(Element element) {
1826 if (metaTargetsUsed.isEmpty) return false; 1837 if (metaTargetsUsed.isEmpty) return false;
1827 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { 1838 for (Link link = element.metadata; !link.isEmpty; link = link.tail) {
1828 MetadataAnnotation metadata = link.head; 1839 MetadataAnnotation metadata = link.head;
1829 // TODO(kasperl): It would be nice if we didn't have to resolve 1840 // TODO(kasperl): It would be nice if we didn't have to resolve
1830 // all metadata but only stuff that potentially would match one 1841 // all metadata but only stuff that potentially would match one
1831 // of the used meta targets. 1842 // of the used meta targets.
1832 metadata.ensureResolved(compiler); 1843 metadata.ensureResolved(compiler);
1833 Constant value = metadata.value; 1844 Constant value = metadata.value;
1834 if (value == null) continue; 1845 if (value == null) continue;
1835 DartType type = value.computeType(compiler); 1846 DartType type = value.computeType(compiler);
1836 if (metaTargetsUsed.contains(type.element)) return true; 1847 if (metaTargetsUsed.contains(type.element)) return true;
1837 } 1848 }
1838 return false; 1849 return false;
1839 } 1850 }
1840 1851
1852 /**
1853 * Visits all classes and computes whether its members are needed for
1854 * reflection.
1855 *
1856 * We have to precompute this set as we cannot easily answer the need for
1857 * reflection locally when looking at the member: We lack the information by
1858 * which classes a member is inherited. Called after resolution is complete.
1859 *
1860 * We filter out private libraries here, as their elements should not
1861 * be visible by reflection unless some other interfaces makes them
1862 * accessible.
1863 */
1864 computeMembersNeededForReflection() {
1865 if (_membersNeededForReflection != null) return;
1866 if (compiler.mirrorsLibrary == null) {
1867 _membersNeededForReflection = const [];
1868 }
1869 // Compute a mapping from class to the closures it contains, so we
1870 // can include include the correct ones when including the class.
Johnni Winther 2014/06/27 07:43:01 'include include' -> 'include'.
herhut 2014/06/27 12:34:37 Done.
1871 Map<ClassElement, List<Element>> closureMap =
1872 new Map<ClassElement, List<Element>>();
1873 for (Element clos in compiler.resolverWorld.allClosures) {
Johnni Winther 2014/06/27 07:43:01 'Element clos' -> 'FunctionElement closure'.
herhut 2014/06/27 12:34:37 Done.
1874 closureMap.putIfAbsent(clos.enclosingClass, () => []).add(clos);
1875 }
1876 Set<Element> reflectableMembers = new Set<Element>();
1877 ResolutionEnqueuer resolution = compiler.enqueuer.resolution;
1878 for (ClassElement cls in resolution.universe.instantiatedClasses) {
1879 // Do not process internal classes.
1880 if (cls.library.isInternalLibrary) continue;
1881 if (cls.isInjected) continue;
Johnni Winther 2014/06/27 07:43:01 Merge conditions.
herhut 2014/06/27 12:34:37 Done.
1882 if (referencedFromMirrorSystem(cls)) {
1883 Set<Name> memberNames = new LinkedHashSet<Name>(
karlklose 2014/06/27 07:45:57 Consider moving this logic to its own method.
herhut 2014/06/27 12:34:37 It has side effects on reflectableMembers and I'd
1884 equals: (Name a, Name b) => a.isSimilarTo(b),
1885 hashCode: (Name a) => a.similarHashCode);
1886 // 1) the class (should be life)
Johnni Winther 2014/06/27 07:43:01 'life' -> 'live' here and more below.
karlklose 2014/06/27 07:45:57 'life' -> 'live'. (Also below.)
herhut 2014/06/27 12:34:37 Done.
herhut 2014/06/27 12:34:37 Done.
1887 assert(invariant(cls, resolution.isLive(cls)));
1888 reflectableMembers.add(cls);
1889 // 2) its constructors (if life)
1890 cls.constructors.forEach((Element constructor) {
karlklose 2014/06/27 07:45:57 How about: cls.constructors .where(resolut
herhut 2014/06/27 12:34:37 constructors is a Link<Element> and has no filter
1891 if (resolution.isLive(constructor)) {
1892 reflectableMembers.add(constructor);
1893 }
1894 });
1895 // 3) all members, including fields via getter/setters (if life)
1896 cls.forEachClassMember((Member member) {
1897 if (resolution.isLive(member.element)) {
1898 memberNames.add(member.name);
1899 reflectableMembers.add(member.element);
1900 }
1901 });
1902 // 4) all overriding members of subclasses/subtypes (should be life)
1903 if (compiler.world.hasAnySubtype(cls)) {
1904 for (ClassElement subcls in compiler.world.subtypesOf(cls)) {
1905 subcls.forEachClassMember((Member member) {
1906 if (memberNames.contains(member.name)) {
1907 assert(invariant(member.element,
1908 resolution.isLive(member.element)));
1909 reflectableMembers.add(member.element);
1910 }
1911 });
1912 }
1913 }
1914 // 5) all its closures
1915 List<Element> closures = closureMap[cls];
1916 if (closures != null) {
1917 reflectableMembers.addAll(closures);
1918 }
1919 } else {
1920 // check members themselves
1921 cls.constructors.forEach((ConstructorElement element) {
karlklose 2014/06/27 07:45:57 Could you share the code of this closure with the
herhut 2014/06/27 12:34:37 I would need an adapter anyway from member to memb
1922 if (!compiler.enqueuer.resolution.isLive(element)) return;
Johnni Winther 2014/06/27 07:43:01 [cls] should be live if the constructor is.
herhut 2014/06/27 12:34:37 Yes, but [cls] is not reflectable. This handles th
1923 if (referencedFromMirrorSystem(element, false)) {
1924 reflectableMembers.add(element);
1925 }
1926 });
1927 cls.forEachClassMember((Member member) {
1928 if (!compiler.enqueuer.resolution.isLive(member.element)) return;
1929 if (referencedFromMirrorSystem(member.element, false)) {
1930 reflectableMembers.add(member.element);
1931 }
1932 });
1933 // Also add in closures
1934 List<Element> closures = closureMap[cls];
1935 if (closures != null) {
1936 for (Element closure in closures) {
1937 if (referencedFromMirrorSystem(closure.enclosingMember, false)) {
1938 reflectableMembers.add(closure);
1939 }
1940 }
1941 }
1942 }
1943 }
1944 // We also need top-level non-class elements like static functions and
1945 // global fields. We use the resolution queue to decide which elements are
1946 // part of the live world.
1947 for (LibraryElement lib in compiler.libraries.values) {
1948 if (lib.isInternalLibrary) continue;
1949 lib.forEachLocalMember((Element member) {
1950 if (!member.isClass &&
1951 compiler.enqueuer.resolution.isLive(member) &&
1952 referencedFromMirrorSystem(member)) {
1953 reflectableMembers.add(member);
1954 }
1955 });
1956 }
1957 // Lastly, we add in all the closures found if they match.
1958 for (Element clos in compiler.resolverWorld.allClosures) {
Johnni Winther 2014/06/27 07:43:01 'Element clos' -> 'FunctionElement closure'.
herhut 2014/06/27 12:34:37 Done.
1959 if (clos.enclosingMember == null ||
1960 referencedFromMirrorSystem(clos.enclosingMember)) {
1961 reflectableMembers.add(clos);
1962 }
1963 }
1964 // And their superclasses.
1965 reflectableMembers.add(compiler.closureClass);
Johnni Winther 2014/06/27 07:43:01 Only if 'allClosures' is non-empty?
herhut 2014/06/27 12:34:37 The [Closure] class could still be part of a Mirro
1966 reflectableMembers.add(compiler.boundClosureClass);
Johnni Winther 2014/06/27 07:43:01 Only if we have tear-offs?
herhut 2014/06/27 12:34:37 See above.
1967 // Register all symbols of reflectable elements
1968 for (Element element in reflectableMembers) {
1969 symbolsUsed.add(element.name);
1970 }
1971 _membersNeededForReflection = reflectableMembers;
1972 }
1973
1841 jsAst.Call generateIsJsIndexableCall(jsAst.Expression use1, 1974 jsAst.Call generateIsJsIndexableCall(jsAst.Expression use1,
1842 jsAst.Expression use2) { 1975 jsAst.Expression use2) {
1843 String dispatchPropertyName = 'init.dispatchPropertyName'; 1976 String dispatchPropertyName = 'init.dispatchPropertyName';
1844 1977
1845 // We pass the dispatch property record to the isJsIndexable 1978 // We pass the dispatch property record to the isJsIndexable
1846 // helper rather than reading it inside the helper to increase the 1979 // helper rather than reading it inside the helper to increase the
1847 // chance of making the dispatch record access monomorphic. 1980 // chance of making the dispatch record access monomorphic.
1848 jsAst.PropertyAccess record = new jsAst.PropertyAccess( 1981 jsAst.PropertyAccess record = new jsAst.PropertyAccess(
1849 use2, js(dispatchPropertyName)); 1982 use2, js(dispatchPropertyName));
1850 1983
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 if (target.isField) { 2026 if (target.isField) {
1894 staticFields.add(target); 2027 staticFields.add(target);
1895 } else if (target.isLibrary || target.isClass) { 2028 } else if (target.isLibrary || target.isClass) {
1896 addFieldsInContainer(target); 2029 addFieldsInContainer(target);
1897 } 2030 }
1898 } 2031 }
1899 return staticFields; 2032 return staticFields;
1900 } 2033 }
1901 2034
1902 /// Called when [enqueuer] is empty, but before it is closed. 2035 /// Called when [enqueuer] is empty, but before it is closed.
1903 void onQueueEmpty(Enqueuer enqueuer) { 2036 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) {
1904 // Add elements referenced only via custom elements. Return early if any 2037 // Add elements referenced only via custom elements. Return early if any
1905 // elements are added to avoid counting the elements as due to mirrors. 2038 // elements are added to avoid counting the elements as due to mirrors.
1906 customElementsAnalysis.onQueueEmpty(enqueuer); 2039 customElementsAnalysis.onQueueEmpty(enqueuer);
1907 if (!enqueuer.queueIsEmpty) return; 2040 if (!enqueuer.queueIsEmpty) return false;
1908 2041
1909 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { 2042 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) {
1910 preMirrorsMethodCount = generatedCode.length; 2043 preMirrorsMethodCount = generatedCode.length;
1911 } 2044 }
1912 2045
1913 if (isTreeShakingDisabled) { 2046 if (isTreeShakingDisabled) {
1914 enqueuer.enqueueEverything(); 2047 enqueuer.enqueueReflectiveElements(recentClasses);
1915 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { 2048 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) {
1916 // Add all static elements (not classes) that have been requested for 2049 // Add all static elements (not classes) that have been requested for
1917 // reflection. If there is no mirror-usage these are probably not 2050 // reflection. If there is no mirror-usage these are probably not
1918 // necessary, but the backend relies on them being resolved. 2051 // necessary, but the backend relies on them being resolved.
1919 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); 2052 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets());
1920 } 2053 }
1921 2054
1922 if (mustPreserveNames) compiler.log('Preserving names.'); 2055 if (mustPreserveNames) compiler.log('Preserving names.');
1923 2056
1924 if (mustRetainMetadata) { 2057 if (mustRetainMetadata) {
1925 compiler.log('Retaining metadata.'); 2058 compiler.log('Retaining metadata.');
1926 2059
1927 compiler.libraries.values.forEach(retainMetadataOf); 2060 compiler.libraries.values.forEach(retainMetadataOf);
1928 for (Dependency dependency in metadataConstants) { 2061 for (Dependency dependency in metadataConstants) {
1929 registerCompileTimeConstant( 2062 registerCompileTimeConstant(
1930 dependency.constant, dependency.registry); 2063 dependency.constant, dependency.registry);
1931 } 2064 }
1932 metadataConstants.clear(); 2065 metadataConstants.clear();
1933 } 2066 }
2067 return true;
1934 } 2068 }
1935 2069
1936 void onElementResolved(Element element, TreeElements elements) { 2070 void onElementResolved(Element element, TreeElements elements) {
1937 LibraryElement library = element.library; 2071 LibraryElement library = element.library;
1938 if (!library.isPlatformLibrary && !library.canUseNative) return; 2072 if (!library.isPlatformLibrary && !library.canUseNative) return;
1939 bool hasNoInline = false; 2073 bool hasNoInline = false;
1940 bool hasNoThrows = false; 2074 bool hasNoThrows = false;
1941 bool hasNoSideEffects = false; 2075 bool hasNoSideEffects = false;
1942 for (MetadataAnnotation metadata in element.metadata) { 2076 for (MetadataAnnotation metadata in element.metadata) {
1943 metadata.ensureResolved(compiler); 2077 metadata.ensureResolved(compiler);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 } 2127 }
1994 2128
1995 /// Records that [constant] is used by the element behind [registry]. 2129 /// Records that [constant] is used by the element behind [registry].
1996 class Dependency { 2130 class Dependency {
1997 final Constant constant; 2131 final Constant constant;
1998 // TODO(johnniwinther): Change to [Element] when dependency nodes are added. 2132 // TODO(johnniwinther): Change to [Element] when dependency nodes are added.
1999 final Registry registry; 2133 final Registry registry;
2000 2134
2001 const Dependency(this.constant, this.registry); 2135 const Dependency(this.constant, this.registry);
2002 } 2136 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698