| Index: pkg/compiler/lib/src/js_backend/mirrors_data.dart
|
| diff --git a/pkg/compiler/lib/src/js_backend/mirrors_data.dart b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
|
| index a946faf39df1b2acea32fc5013a9ae0b52135ac2..758682e1e015cf0df6198987af20a264356ecb30 100644
|
| --- a/pkg/compiler/lib/src/js_backend/mirrors_data.dart
|
| +++ b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
|
| @@ -2,12 +2,11 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -import '../closure.dart';
|
| import '../common.dart';
|
| import '../common_elements.dart';
|
| import '../compiler.dart';
|
| import '../constants/values.dart';
|
| -import '../elements/elements.dart';
|
| +import '../elements/elements.dart' show AbstractFieldElement, Element;
|
| import '../elements/entities.dart';
|
| import '../elements/names.dart';
|
| import '../elements/types.dart';
|
| @@ -146,15 +145,13 @@ abstract class MirrorsDataBuilder {
|
| void registerConstSymbol(String name);
|
|
|
| void maybeMarkClosureAsNeededForReflection(
|
| - ClosureClassElement globalizedElement,
|
| - MethodElement callFunction,
|
| - LocalFunctionElement function);
|
| + ClassEntity closureClass, FunctionEntity callMethod, Local localFunction);
|
|
|
| void computeMembersNeededForReflection(
|
| ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld);
|
| }
|
|
|
| -class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| +abstract class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| /// True if a call to preserveMetadataMarker has been seen. This means that
|
| /// metadata must be retained for dart:mirrors to work correctly.
|
| bool mustRetainMetadata = false;
|
| @@ -237,7 +234,7 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| }
|
|
|
| @override
|
| - bool retainMetadataOfMember(covariant MemberElement element) {
|
| + bool retainMetadataOfMember(MemberEntity element) {
|
| if (mustRetainMetadata) {
|
| hasRetainedMetadata = true;
|
| if (isMemberReferencedFromMirrorSystem(element)) {
|
| @@ -289,11 +286,11 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| return false;
|
| }
|
|
|
| - Iterable<ConstantValue> getLibraryMetadata(LibraryElement element) {
|
| + Iterable<ConstantValue> getLibraryMetadata(LibraryEntity element) {
|
| return _elementEnvironment.getLibraryMetadata(element);
|
| }
|
|
|
| - Iterable<ConstantValue> getClassMetadata(ClassElement element) {
|
| + Iterable<ConstantValue> getClassMetadata(ClassEntity element) {
|
| return _elementEnvironment.getClassMetadata(element);
|
| }
|
|
|
| @@ -303,7 +300,7 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| includeParameterMetadata: includeParameterMetadata);
|
| }
|
|
|
| - Iterable<ConstantValue> getTypedefMetadata(TypedefElement element) {
|
| + Iterable<ConstantValue> getTypedefMetadata(TypedefEntity element) {
|
| return _elementEnvironment.getTypedefMetadata(element);
|
| }
|
|
|
| @@ -469,7 +466,7 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| librariesInMirrorsUsedTargets.contains(element);
|
| }
|
|
|
| - bool _libraryMatchesMirrorsMetaTarget(LibraryElement element) {
|
| + bool _libraryMatchesMirrorsMetaTarget(LibraryEntity element) {
|
| if (metaTargetsUsed.isEmpty) return false;
|
| return _matchesMirrorsMetaTarget(getLibraryMetadata(element));
|
| }
|
| @@ -479,13 +476,13 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| return _matchesMirrorsMetaTarget(getClassMetadata(element));
|
| }
|
|
|
| - bool _memberMatchesMirrorsMetaTarget(MemberElement element) {
|
| + bool _memberMatchesMirrorsMetaTarget(MemberEntity element) {
|
| if (metaTargetsUsed.isEmpty) return false;
|
| return _matchesMirrorsMetaTarget(
|
| getMemberMetadata(element, includeParameterMetadata: false));
|
| }
|
|
|
| - bool _typedefMatchesMirrorsMetaTarget(TypedefElement element) {
|
| + bool _typedefMatchesMirrorsMetaTarget(TypedefEntity element) {
|
| if (metaTargetsUsed.isEmpty) return false;
|
| return _matchesMirrorsMetaTarget(getTypedefMetadata(element));
|
| }
|
| @@ -505,11 +502,41 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| }
|
|
|
| void createImmutableSets() {
|
| - _classesNeededForReflection = const ImmutableEmptySet<ClassElement>();
|
| - _typedefsNeededForReflection = const ImmutableEmptySet<TypedefElement>();
|
| - _membersNeededForReflection = const ImmutableEmptySet<MemberElement>();
|
| - _closuresNeededForReflection =
|
| - const ImmutableEmptySet<LocalFunctionElement>();
|
| + _classesNeededForReflection = const ImmutableEmptySet<ClassEntity>();
|
| + _typedefsNeededForReflection = const ImmutableEmptySet<TypedefEntity>();
|
| + _membersNeededForReflection = const ImmutableEmptySet<MemberEntity>();
|
| + _closuresNeededForReflection = const ImmutableEmptySet<Local>();
|
| + }
|
| +
|
| + bool isLibraryInternal(LibraryEntity library) {
|
| + return library.canonicalUri.scheme == 'dart' &&
|
| + library.canonicalUri.path.startsWith('_');
|
| + }
|
| +
|
| + /// Whether [cls] is 'injected'.
|
| + ///
|
| + /// An injected class is declared in a patch library with no corresponding
|
| + /// class in the origin library.
|
| + // TODO(redemption): Detect injected classes from .dill.
|
| + bool isClassInjected(ClassEntity cls) => false;
|
| +
|
| + bool isClassResolved(ClassEntity cls) => true;
|
| +
|
| + void forEachConstructor(
|
| + ClassEntity cls, void f(ConstructorEntity constructor)) {
|
| + _elementEnvironment.forEachConstructor(cls, f);
|
| + }
|
| +
|
| + void forEachClassMember(
|
| + ClassEntity cls, void f(MemberEntity member, Name memberName)) {
|
| + _elementEnvironment.forEachClassMember(cls,
|
| + (ClassEntity declarer, MemberEntity member) {
|
| + if (member.isSetter) {
|
| + f(member, member.memberName.setter);
|
| + } else {
|
| + f(member, member.memberName.getter);
|
| + }
|
| + });
|
| }
|
|
|
| /**
|
| @@ -546,45 +573,37 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| .add(closure);
|
| }
|
| bool foundClosure = false;
|
| - for (ClassElement cls in worldBuilder.directlyInstantiatedClasses) {
|
| + for (ClassEntity cls in worldBuilder.directlyInstantiatedClasses) {
|
| // Do not process internal classes.
|
| - if (cls.library.isInternalLibrary || cls.isInjected) continue;
|
| + if (isLibraryInternal(cls.library) || isClassInjected(cls)) continue;
|
| if (isClassReferencedFromMirrorSystem(cls)) {
|
| Set<Name> memberNames = new Set<Name>();
|
| // 1) the class (should be resolved)
|
| - assert(cls.isResolved, failedAt(cls));
|
| + assert(isClassResolved(cls), failedAt(cls));
|
| _classesNeededForReflection.add(cls);
|
| // 2) its constructors (if resolved)
|
| - cls.constructors.forEach((Element _constructor) {
|
| - ConstructorElement constructor = _constructor;
|
| + forEachConstructor(cls, (ConstructorEntity constructor) {
|
| if (worldBuilder.isMemberUsed(constructor)) {
|
| _membersNeededForReflection.add(constructor);
|
| }
|
| });
|
| // 3) all members, including fields via getter/setters (if resolved)
|
| - cls.forEachClassMember((Member member) {
|
| - MemberElement element = member.element;
|
| - if (worldBuilder.isMemberUsed(element)) {
|
| - memberNames.add(member.name);
|
| - _membersNeededForReflection.add(element);
|
| - element.nestedClosures.forEach((FunctionElement _callFunction) {
|
| - SynthesizedCallMethodElementX callFunction = _callFunction;
|
| - _membersNeededForReflection.add(callFunction);
|
| - _classesNeededForReflection.add(callFunction.closureClass);
|
| - });
|
| + forEachClassMember(cls, (MemberEntity member, Name memberName) {
|
| + if (worldBuilder.isMemberUsed(member)) {
|
| + memberNames.add(memberName);
|
| + _membersNeededForReflection.add(member);
|
| }
|
| });
|
| // 4) all overriding members of subclasses/subtypes (should be resolved)
|
| if (closedWorld.hasAnyStrictSubtype(cls)) {
|
| - closedWorld.forEachStrictSubtypeOf(cls, (ClassEntity _subcls) {
|
| - ClassElement subcls = _subcls;
|
| - subcls.forEachClassMember((Member member) {
|
| - if (memberNames.contains(member.name)) {
|
| + closedWorld.forEachStrictSubtypeOf(cls, (ClassEntity subcls) {
|
| + forEachClassMember(subcls, (MemberEntity member, Name memberName) {
|
| + if (memberNames.contains(memberName)) {
|
| // TODO(20993): find out why this assertion fails.
|
| // assert(worldBuilder.isMemberUsed(member.element),
|
| // failedAt(member.element));
|
| - if (worldBuilder.isMemberUsed(member.element)) {
|
| - _membersNeededForReflection.add(member.element);
|
| + if (worldBuilder.isMemberUsed(member)) {
|
| + _membersNeededForReflection.add(member);
|
| }
|
| }
|
| });
|
| @@ -598,17 +617,16 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| }
|
| } else {
|
| // check members themselves
|
| - cls.constructors.forEach((Element _element) {
|
| - ConstructorElement element = _element;
|
| + forEachConstructor(cls, (ConstructorEntity element) {
|
| if (!worldBuilder.isMemberUsed(element)) return;
|
| if (_memberReferencedFromMirrorSystem(element)) {
|
| _membersNeededForReflection.add(element);
|
| }
|
| });
|
| - cls.forEachClassMember((Member member) {
|
| - if (!worldBuilder.isMemberUsed(member.element)) return;
|
| - if (_memberReferencedFromMirrorSystem(member.element)) {
|
| - _membersNeededForReflection.add(member.element);
|
| + forEachClassMember(cls, (MemberEntity member, _) {
|
| + if (!worldBuilder.isMemberUsed(member)) return;
|
| + if (_memberReferencedFromMirrorSystem(member)) {
|
| + _membersNeededForReflection.add(member);
|
| }
|
| });
|
| // Also add in closures. Those might be reflectable is their enclosing
|
| @@ -628,11 +646,9 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
| // We also need top-level non-class elements like static functions and
|
| // global fields. We use the resolution queue to decide which elements are
|
| // part of the live world.
|
| - for (LibraryElement lib in _compiler.libraryLoader.libraries) {
|
| - if (lib.isInternalLibrary) continue;
|
| - lib.forEachLocalMember((Element element) {
|
| - if (element.isClass || element.isTypedef) return;
|
| - MemberElement member = element;
|
| + for (LibraryEntity lib in _elementEnvironment.libraries) {
|
| + if (isLibraryInternal(lib)) continue;
|
| + _elementEnvironment.forEachLibraryMember(lib, (MemberEntity member) {
|
| if (worldBuilder.isMemberUsed(member) &&
|
| isMemberReferencedFromMirrorSystem(member)) {
|
| _membersNeededForReflection.add(member);
|
| @@ -683,13 +699,11 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder {
|
|
|
| // TODO(20791): compute closure classes after resolution and move this code to
|
| // [computeMembersNeededForReflection].
|
| - void maybeMarkClosureAsNeededForReflection(
|
| - ClosureClassElement globalizedElement,
|
| - MethodElement callFunction,
|
| - LocalFunctionElement function) {
|
| - if (!_closuresNeededForReflection.contains(function)) return;
|
| - _membersNeededForReflection.add(callFunction);
|
| - _classesNeededForReflection.add(globalizedElement);
|
| + void maybeMarkClosureAsNeededForReflection(ClassEntity closureClass,
|
| + FunctionEntity callMethod, Local localFunction) {
|
| + if (!_closuresNeededForReflection.contains(localFunction)) return;
|
| + _membersNeededForReflection.add(callMethod);
|
| + _classesNeededForReflection.add(closureClass);
|
| }
|
|
|
| /// Called when `const Symbol(name)` is seen.
|
|
|