Chromium Code Reviews| 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..c97f05a17fee4fd6bd4045e7d326ccfca7af8534 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,36 @@ 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('_'); |
| + } |
| + |
| + bool isClassInjected(ClassEntity cls) => false; |
|
Siggi Cherem (dart-lang)
2017/07/14 17:52:04
might be nice to add a doc explaining what it mean
Johnni Winther
2017/07/17 09:07:20
Done.
|
| + |
| + 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 +568,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 +612,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 +641,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 +694,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. |