[dart2js] Handle private names correctly in K/J-model

The library wasn't taken into account when handling computing class
members in the K/J-model and not handled correctly when computing
applicable selectors. This made dart2js unable to handle members with
a name private to a different library than the enclosing library.

Fixes #33732
Fixes #49226

Change-Id: I5ba143d87662bbd42e0ff02355054e4a937be8f8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252665
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
Johnni Winther 2022-08-11 06:56:32 +00:00 committed by Commit Bot
parent 94d797ebee
commit 50ac2500a1
50 changed files with 617 additions and 297 deletions

View file

@ -6,6 +6,7 @@ import '../common.dart';
import '../constants/constant_system.dart' as constant_system; import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart'; import '../constants/values.dart';
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../inferrer/abstract_value_domain.dart'; import '../inferrer/abstract_value_domain.dart';
import '../js_backend/native_data.dart' show NativeBasicData; import '../js_backend/native_data.dart' show NativeBasicData;
@ -325,8 +326,9 @@ abstract class CommonElements {
T _findClassMember<T extends MemberEntity>(ClassEntity cls, String name, T _findClassMember<T extends MemberEntity>(ClassEntity cls, String name,
{bool setter = false, bool required = true}) { {bool setter = false, bool required = true}) {
return _env.lookupLocalClassMember(cls, name, return _env.lookupLocalClassMember(
setter: setter, required: required) as T; cls, Name(name, cls.library.canonicalUri, isSetter: setter),
required: required) as T;
} }
ConstructorEntity _findConstructor(ClassEntity cls, String name, ConstructorEntity _findConstructor(ClassEntity cls, String name,
@ -371,8 +373,10 @@ abstract class CommonElements {
/// Returns the field that holds the internal name in the implementation class /// Returns the field that holds the internal name in the implementation class
/// for `Symbol`. /// for `Symbol`.
FieldEntity get symbolField => _symbolImplementationField ??= FieldEntity get symbolField =>
_env.lookupLocalClassMember(symbolImplementationClass, '_name', _symbolImplementationField ??= _env.lookupLocalClassMember(
symbolImplementationClass,
PrivateName('_name', symbolImplementationClass.library.canonicalUri),
required: true) as FieldEntity; required: true) as FieldEntity;
InterfaceType get symbolImplementationType => InterfaceType get symbolImplementationType =>
@ -395,10 +399,13 @@ abstract class CommonElements {
late final ConstructorEntity mapLiteralConstructorEmpty = late final ConstructorEntity mapLiteralConstructorEmpty =
_env.lookupConstructor(mapLiteralClass, '_empty'); _env.lookupConstructor(mapLiteralClass, '_empty');
late final FunctionEntity mapLiteralUntypedMaker = late final FunctionEntity mapLiteralUntypedMaker =
_env.lookupLocalClassMember(mapLiteralClass, '_makeLiteral') _env.lookupLocalClassMember(mapLiteralClass,
PrivateName('_makeLiteral', mapLiteralClass.library.canonicalUri))
as FunctionEntity;
late final FunctionEntity mapLiteralUntypedEmptyMaker =
_env.lookupLocalClassMember(mapLiteralClass,
PrivateName('_makeEmpty', mapLiteralClass.library.canonicalUri))
as FunctionEntity; as FunctionEntity;
late final FunctionEntity mapLiteralUntypedEmptyMaker = _env
.lookupLocalClassMember(mapLiteralClass, '_makeEmpty') as FunctionEntity;
late final ClassEntity setLiteralClass = late final ClassEntity setLiteralClass =
_findClass(_env.lookupLibrary(Uris.dart_collection), 'LinkedHashSet')!; _findClass(_env.lookupLibrary(Uris.dart_collection), 'LinkedHashSet')!;
@ -408,13 +415,17 @@ abstract class CommonElements {
late final ConstructorEntity setLiteralConstructorEmpty = late final ConstructorEntity setLiteralConstructorEmpty =
_env.lookupConstructor(setLiteralClass, '_empty'); _env.lookupConstructor(setLiteralClass, '_empty');
late final FunctionEntity setLiteralUntypedMaker = late final FunctionEntity setLiteralUntypedMaker =
_env.lookupLocalClassMember(setLiteralClass, '_makeLiteral') _env.lookupLocalClassMember(setLiteralClass,
PrivateName('_makeLiteral', setLiteralClass.library.canonicalUri))
as FunctionEntity;
late final FunctionEntity setLiteralUntypedEmptyMaker =
_env.lookupLocalClassMember(setLiteralClass,
PrivateName('_makeEmpty', setLiteralClass.library.canonicalUri))
as FunctionEntity; as FunctionEntity;
late final FunctionEntity setLiteralUntypedEmptyMaker = _env
.lookupLocalClassMember(setLiteralClass, '_makeEmpty') as FunctionEntity;
late final FunctionEntity objectNoSuchMethod = _env.lookupLocalClassMember( late final FunctionEntity objectNoSuchMethod = _env.lookupLocalClassMember(
objectClass, Identifiers.noSuchMethod_) as FunctionEntity; objectClass, const PublicName(Identifiers.noSuchMethod_))
as FunctionEntity;
bool isDefaultNoSuchMethodImplementation(FunctionEntity element) { bool isDefaultNoSuchMethodImplementation(FunctionEntity element) {
ClassEntity? classElement = element.enclosingClass; ClassEntity? classElement = element.enclosingClass;
@ -446,15 +457,16 @@ abstract class CommonElements {
_findAsyncHelperFunction("_wrapJsFunctionForAsync"); _findAsyncHelperFunction("_wrapJsFunctionForAsync");
FunctionEntity get yieldStar => _env.lookupLocalClassMember( FunctionEntity get yieldStar => _env.lookupLocalClassMember(
_findAsyncHelperClass("_IterationMarker"), "yieldStar") as FunctionEntity; _findAsyncHelperClass("_IterationMarker"),
const PublicName("yieldStar")) as FunctionEntity;
FunctionEntity get yieldSingle => _env.lookupLocalClassMember( FunctionEntity get yieldSingle => _env.lookupLocalClassMember(
_findAsyncHelperClass("_IterationMarker"), "yieldSingle") _findAsyncHelperClass("_IterationMarker"),
as FunctionEntity; const PublicName("yieldSingle")) as FunctionEntity;
FunctionEntity get syncStarUncaughtError => _env.lookupLocalClassMember( FunctionEntity get syncStarUncaughtError => _env.lookupLocalClassMember(
_findAsyncHelperClass("_IterationMarker"), "uncaughtError") _findAsyncHelperClass("_IterationMarker"),
as FunctionEntity; const PublicName("uncaughtError")) as FunctionEntity;
FunctionEntity get asyncStarHelper => FunctionEntity get asyncStarHelper =>
_findAsyncHelperFunction("_asyncStarHelper"); _findAsyncHelperFunction("_asyncStarHelper");
@ -463,8 +475,8 @@ abstract class CommonElements {
_findAsyncHelperFunction("_streamOfController"); _findAsyncHelperFunction("_streamOfController");
FunctionEntity get endOfIteration => _env.lookupLocalClassMember( FunctionEntity get endOfIteration => _env.lookupLocalClassMember(
_findAsyncHelperClass("_IterationMarker"), "endOfIteration") _findAsyncHelperClass("_IterationMarker"),
as FunctionEntity; const PublicName("endOfIteration")) as FunctionEntity;
ClassEntity get syncStarIterable => ClassEntity get syncStarIterable =>
_findAsyncHelperClass("_SyncStarIterable"); _findAsyncHelperClass("_SyncStarIterable");
@ -1247,17 +1259,16 @@ abstract class ElementEnvironment {
/// Lookup the member [name] in [cls], fail if the class is missing and /// Lookup the member [name] in [cls], fail if the class is missing and
/// [required]. /// [required].
MemberEntity? lookupLocalClassMember(ClassEntity cls, String name, MemberEntity? lookupLocalClassMember(ClassEntity cls, Name name,
{bool setter = false, bool required = false}); {bool required = false});
/// Lookup the member [name] in [cls] and its superclasses. /// Lookup the member [name] in [cls] and its superclasses.
/// ///
/// Return `null` if the member is not found in the class or any superclass. /// Return `null` if the member is not found in the class or any superclass.
MemberEntity? lookupClassMember(ClassEntity cls, String name, MemberEntity? lookupClassMember(ClassEntity cls, Name name) {
{bool setter = false}) {
ClassEntity? clsLocal = cls; ClassEntity? clsLocal = cls;
while (clsLocal != null) { while (clsLocal != null) {
final entity = lookupLocalClassMember(clsLocal, name, setter: setter); final entity = lookupLocalClassMember(clsLocal, name);
if (entity != null) return entity; if (entity != null) return entity;
clsLocal = getSuperClass(clsLocal); clsLocal = getSuperClass(clsLocal);

View file

@ -78,6 +78,8 @@ class Names {
/// The name of the dynamic type. /// The name of the dynamic type.
static const Name dynamic_ = PublicName('dynamic'); static const Name dynamic_ = PublicName('dynamic');
static const Name EQUALS_NAME = PublicName("==");
/// The name of the iterator property used in for-each loops. /// The name of the iterator property used in for-each loops.
static const Name iterator = PublicName(Identifiers.iterator); static const Name iterator = PublicName(Identifiers.iterator);

View file

@ -28,6 +28,7 @@ import 'deferred_load/output_unit.dart' show OutputUnit, deferredPartFileName;
import 'dump_info_javascript_monitor.dart'; import 'dump_info_javascript_monitor.dart';
import 'elements/entities.dart'; import 'elements/entities.dart';
import 'elements/entity_utils.dart' as entity_utils; import 'elements/entity_utils.dart' as entity_utils;
import 'elements/names.dart';
import 'inferrer/abstract_value_domain.dart'; import 'inferrer/abstract_value_domain.dart';
import 'inferrer/types.dart' import 'inferrer/types.dart'
show GlobalTypeInferenceMemberResult, GlobalTypeInferenceResults; show GlobalTypeInferenceMemberResult, GlobalTypeInferenceResults;
@ -281,8 +282,8 @@ class ElementInfoCollector {
size: dumpInfoTask.sizeOf(element)); size: dumpInfoTask.sizeOf(element));
state.entityToInfo[element] = closureInfo; state.entityToInfo[element] = closureInfo;
FunctionEntity callMethod = closedWorld.elementEnvironment FunctionEntity callMethod =
.lookupClassMember(element, Identifiers.call); closedWorld.elementEnvironment.lookupClassMember(element, Names.call);
FunctionInfo functionInfo = visitFunction(callMethod); FunctionInfo functionInfo = visitFunction(callMethod);
if (functionInfo == null) return null; if (functionInfo == null) return null;
@ -570,10 +571,12 @@ class KernelInfoCollector {
clazz.members.forEach((ir.Member member) { clazz.members.forEach((ir.Member member) {
final isSetter = member is ir.Procedure && member.isSetter; final isSetter = member is ir.Procedure && member.isSetter;
// clazz.members includes constructors // clazz.members includes constructors
MemberEntity memberEntity = environment.lookupLocalClassMember( final name = Name(member.name.text,
classEntity, member.name.text, member.name.isPrivate ? member.name.library.importUri : null,
setter: isSetter) ?? isSetter: isSetter);
environment.lookupConstructor(classEntity, member.name.text); MemberEntity memberEntity =
environment.lookupLocalClassMember(classEntity, name) ??
environment.lookupConstructor(classEntity, member.name.text);
if (memberEntity == null) return; if (memberEntity == null) return;
if (member.function != null) { if (member.function != null) {
@ -701,7 +704,7 @@ class KernelInfoCollector {
final closureInfo = ClosureInfo.fromKernel(name: value.disambiguatedName); final closureInfo = ClosureInfo.fromKernel(name: value.disambiguatedName);
FunctionEntity callMethod = closedWorld.elementEnvironment FunctionEntity callMethod = closedWorld.elementEnvironment
.lookupClassMember(closureClassEntity, Identifiers.call); .lookupClassMember(closureClassEntity, Names.call);
final functionInfo = visitFunction(key.function, final functionInfo = visitFunction(key.function,
functionEntity: callMethod, localFunctionInfo: value); functionEntity: callMethod, localFunctionInfo: value);
@ -993,8 +996,8 @@ class DumpInfoAnnotator {
kClosureInfo.outputUnit = _unitInfoForClass(element); kClosureInfo.outputUnit = _unitInfoForClass(element);
kClosureInfo.size = dumpInfoTask.sizeOf(element); kClosureInfo.size = dumpInfoTask.sizeOf(element);
FunctionEntity callMethod = closedWorld.elementEnvironment FunctionEntity callMethod =
.lookupClassMember(element, Identifiers.call); closedWorld.elementEnvironment.lookupClassMember(element, Names.call);
final functionInfo = final functionInfo =
visitFunction(callMethod, disambiguatedElementName, isClosure: true); visitFunction(callMethod, disambiguatedElementName, isClosure: true);

View file

@ -6,18 +6,16 @@ library dart2js.elements.names;
import 'package:front_end/src/api_unstable/dart2js.dart' show $_; import 'package:front_end/src/api_unstable/dart2js.dart' show $_;
import 'entities.dart' show LibraryEntity;
/// A [Name] represents the abstraction of a Dart identifier which takes privacy /// A [Name] represents the abstraction of a Dart identifier which takes privacy
/// and setter into account. /// and setter into account.
// TODO(johnniwinther): Try to share logic with [Selector]. // TODO(johnniwinther): Try to share logic with [Selector].
abstract class Name { abstract class Name {
/// Create a [Name] for an identifier [text]. If [text] begins with '_' a /// Create a [Name] for an identifier [text]. If [text] begins with '_' a
/// private name with respect to [library] is created. If [isSetter] is `true` /// private name with respect to library [uri] is created. If [isSetter] is
/// the created name represents the setter name 'text='. /// `true` the created name represents the setter name 'text='.
factory Name(String text, LibraryEntity? library, {bool isSetter = false}) { factory Name(String text, Uri? uri, {bool isSetter = false}) {
if (isPrivateName(text)) { if (isPrivateName(text)) {
return PrivateName(text, library!, isSetter: isSetter); return PrivateName(text, uri!, isSetter: isSetter);
} }
return PublicName(text, isSetter: isSetter); return PublicName(text, isSetter: isSetter);
} }
@ -34,14 +32,14 @@ abstract class Name {
/// is returned. /// is returned.
Name get getter; Name get getter;
/// Returns the seeter name corresponding to this name. If this name is a /// Returns the setter name corresponding to this name. If this name is a
/// getter name 'v' then the name 'v=' is returned, otherwsie the name itself /// getter name 'v' then the name 'v=' is returned, otherwise the name itself
/// is returned. /// is returned.
Name get setter; Name get setter;
/// Returns `true` if an entity of this name is accessible from library /// Returns `true` if an entity of this name is accessible from library
/// [element]. /// [element].
bool isAccessibleFrom(LibraryEntity element); bool isAccessibleFrom(Uri uri);
/// Returns `true` if this name is private. /// Returns `true` if this name is private.
bool get isPrivate; bool get isPrivate;
@ -51,8 +49,15 @@ abstract class Name {
bool isSimilarTo(Name other); bool isSimilarTo(Name other);
int get similarHashCode; int get similarHashCode;
/// Returns `true` if this name has the name [text] and [library] as [other].
///
/// This is similar to `==` but doesn't take `isSetter` into account.
bool matches(Name other);
/// If this name is private, returns the [Uri] for the library from which the
/// name originates. Otherwise, returns `null`.
// TODO(sra): Should this rather throw for public names? // TODO(sra): Should this rather throw for public names?
LibraryEntity? get library; Uri? get uri;
/// Returns `true` when [s] is private if used as an identifier. /// Returns `true` when [s] is private if used as an identifier.
static bool isPrivateName(String s) => !s.isEmpty && s.codeUnitAt(0) == $_; static bool isPrivateName(String s) => !s.isEmpty && s.codeUnitAt(0) == $_;
@ -76,7 +81,7 @@ class PublicName implements Name {
Name get setter => isSetter ? this : PublicName(text, isSetter: true); Name get setter => isSetter ? this : PublicName(text, isSetter: true);
@override @override
bool isAccessibleFrom(LibraryEntity element) => true; bool isAccessibleFrom(Uri uri) => true;
@override @override
bool get isPrivate => false; bool get isPrivate => false;
@ -97,7 +102,10 @@ class PublicName implements Name {
int get similarHashCode => text.hashCode + 11 * isSetter.hashCode; int get similarHashCode => text.hashCode + 11 * isSetter.hashCode;
@override @override
LibraryEntity? get library => null; bool matches(Name other) => text == other.text;
@override
Uri? get uri => null;
@override @override
String toString() => isSetter ? '$text=' : text; String toString() => isSetter ? '$text=' : text;
@ -105,34 +113,37 @@ class PublicName implements Name {
class PrivateName extends PublicName { class PrivateName extends PublicName {
@override @override
final LibraryEntity library; final Uri uri;
PrivateName(String text, this.library, {bool isSetter = false}) PrivateName(String text, this.uri, {bool isSetter = false})
: super(text, isSetter: isSetter); : super(text, isSetter: isSetter);
@override @override
Name get getter => isSetter ? PrivateName(text, library) : this; Name get getter => isSetter ? PrivateName(text, uri) : this;
@override @override
Name get setter { Name get setter {
return isSetter ? this : PrivateName(text, library, isSetter: true); return isSetter ? this : PrivateName(text, uri, isSetter: true);
} }
@override @override
bool isAccessibleFrom(LibraryEntity element) => library == element; bool isAccessibleFrom(Uri uri) => this.uri == uri;
@override @override
bool get isPrivate => true; bool get isPrivate => true;
@override @override
int get hashCode => super.hashCode + 13 * library.hashCode; int get hashCode => super.hashCode + 13 * uri.hashCode;
@override @override
bool operator ==(other) { bool operator ==(other) {
if (other is! PrivateName) return false; if (other is! PrivateName) return false;
return super == (other) && library == other.library; return super == (other) && uri == other.uri;
} }
@override @override
String toString() => '${library.name}#${super.toString()}'; bool matches(Name other) => super.matches(other) && uri == other.uri;
@override
String toString() => '${uri}#${super.toString()}';
} }

View file

@ -1472,7 +1472,7 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation>
// We have something like `Uint32List(len)`. // We have something like `Uint32List(len)`.
int length = _findLength(arguments); int length = _findLength(arguments);
MemberEntity member = _elementMap.elementEnvironment MemberEntity member = _elementMap.elementEnvironment
.lookupClassMember(constructor.enclosingClass, '[]'); .lookupClassMember(constructor.enclosingClass, Names.INDEX_NAME);
TypeInformation elementType = _inferrer.returnTypeOfMember(member); TypeInformation elementType = _inferrer.returnTypeOfMember(member);
return _inferrer.concreteTypes.putIfAbsent( return _inferrer.concreteTypes.putIfAbsent(
node, node,

View file

@ -560,10 +560,10 @@ class InferrerEngine implements interfaces.InferrerEngine {
/// implement `call`. /// implement `call`.
FunctionEntity _lookupCallMethod(ClassEntity cls) { FunctionEntity _lookupCallMethod(ClassEntity cls) {
FunctionEntity function = FunctionEntity function =
_elementEnvironment.lookupClassMember(cls, Identifiers.call); _elementEnvironment.lookupClassMember(cls, Names.call);
if (function == null || function.isAbstract) { if (function == null || function.isAbstract) {
function = function =
_elementEnvironment.lookupClassMember(cls, Identifiers.noSuchMethod_); _elementEnvironment.lookupClassMember(cls, Names.noSuchMethod_);
} }
return function; return function;
} }

View file

@ -8,6 +8,7 @@ import 'package:kernel/core_types.dart' as ir;
import '../common.dart'; import '../common.dart';
import '../common/elements.dart'; import '../common/elements.dart';
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../ordered_typeset.dart'; import '../ordered_typeset.dart';
import '../universe/call_structure.dart'; import '../universe/call_structure.dart';
@ -20,6 +21,11 @@ abstract class IrToElementMap {
/// Returns the [DartType] corresponding to [type]. /// Returns the [DartType] corresponding to [type].
DartType getDartType(ir.DartType type); DartType getDartType(ir.DartType type);
/// Returns the [Name] corresponding to [name].
///
/// If [setter] is `true`, the setter name is returned.
Name getName(ir.Name name, {bool setter = false});
/// Returns the [MemberEntity] corresponding to the member [node]. /// Returns the [MemberEntity] corresponding to the member [node].
MemberEntity getMember(ir.Member node); MemberEntity getMember(ir.Member node);

View file

@ -648,7 +648,8 @@ class Namer extends ModularNamer {
// Public names are easy. // Public names are easy.
if (!originalName.isPrivate) return text; if (!originalName.isPrivate) return text;
LibraryEntity library = originalName.library; LibraryEntity library =
_elementEnvironment.lookupLibrary(originalName.uri, required: true);
// The first library asking for a short private name wins. // The first library asking for a short private name wins.
LibraryEntity owner = LibraryEntity owner =
@ -888,13 +889,13 @@ class Namer extends ModularNamer {
// No superclass uses the disambiguated name as a property name, so we can // No superclass uses the disambiguated name as a property name, so we can
// use it for this field. This generates nicer field names since otherwise // use it for this field. This generates nicer field names since otherwise
// the field name would have to be mangled. // the field name would have to be mangled.
return _disambiguateMember(Name(element.name, element.library)); return _disambiguateMember(
Name(element.name, element.library.canonicalUri));
} }
bool _isShadowingSuperField(FieldEntity element) { bool _isShadowingSuperField(FieldEntity element) {
assert(element.isField); assert(element.isField);
String fieldName = element.name; Name fieldName = element.memberName;
bool isPrivate = Name.isPrivateName(fieldName);
LibraryEntity memberLibrary = element.library; LibraryEntity memberLibrary = element.library;
ClassEntity lookupClass = ClassEntity lookupClass =
_elementEnvironment.getSuperClass(element.enclosingClass); _elementEnvironment.getSuperClass(element.enclosingClass);
@ -903,7 +904,7 @@ class Namer extends ModularNamer {
_elementEnvironment.lookupLocalClassMember(lookupClass, fieldName); _elementEnvironment.lookupLocalClassMember(lookupClass, fieldName);
if (foundMember != null) { if (foundMember != null) {
if (foundMember.isField) { if (foundMember.isField) {
if (!isPrivate || memberLibrary == foundMember.library) { if (!fieldName.isPrivate || memberLibrary == foundMember.library) {
// Private fields can only be shadowed by a field declared in the // Private fields can only be shadowed by a field declared in the
// same library. // same library.
return true; return true;
@ -1030,8 +1031,10 @@ class Namer extends ModularNamer {
jsAst.Name _disambiguateMember(Name originalName, jsAst.Name _disambiguateMember(Name originalName,
[List<String> suffixes = const []]) { [List<String> suffixes = const []]) {
// Build a string encoding the library name, if the name is private. // Build a string encoding the library name, if the name is private.
String libraryKey = String libraryKey = originalName.isPrivate
originalName.isPrivate ? _generateLibraryKey(originalName.library) : ''; ? _generateLibraryKey(
_elementEnvironment.lookupLibrary(originalName.uri, required: true))
: '';
// In the unique key, separate the name parts by '@'. // In the unique key, separate the name parts by '@'.
// This avoids clashes since the original names cannot contain that symbol. // This avoids clashes since the original names cannot contain that symbol.

View file

@ -7,7 +7,7 @@
library js_backend.backend.resolution_listener; library js_backend.backend.resolution_listener;
import '../common/elements.dart' show KCommonElements, KElementEnvironment; import '../common/elements.dart' show KCommonElements, KElementEnvironment;
import '../common/names.dart' show Identifiers; import '../common/names.dart' show Identifiers, Names;
import '../constants/values.dart'; import '../constants/values.dart';
import '../deferred_load/deferred_load.dart'; import '../deferred_load/deferred_load.dart';
import '../elements/entities.dart'; import '../elements/entities.dart';
@ -160,8 +160,8 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
enqueuer.applyImpact(_customElementsAnalysis.flush()); enqueuer.applyImpact(_customElementsAnalysis.flush());
for (ClassEntity cls in recentClasses) { for (ClassEntity cls in recentClasses) {
MemberEntity element = _elementEnvironment.lookupLocalClassMember( MemberEntity element =
cls, Identifiers.noSuchMethod_); _elementEnvironment.lookupLocalClassMember(cls, Names.noSuchMethod_);
if (element != null && if (element != null &&
element.isInstanceMember && element.isInstanceMember &&
element.isFunction && element.isFunction &&

View file

@ -9,7 +9,7 @@ library js_backend.runtime_types;
import '../common.dart'; import '../common.dart';
import '../common/elements.dart' import '../common/elements.dart'
show ElementEnvironment, JCommonElements, JElementEnvironment; show ElementEnvironment, JCommonElements, JElementEnvironment;
import '../common/names.dart' show Identifiers; import '../common/names.dart' show Names;
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../js/js.dart' as jsAst; import '../js/js.dart' as jsAst;
@ -769,7 +769,7 @@ ClassFunctionType _computeFunctionType(
if (cls.isClosure) { if (cls.isClosure) {
// Use signature function if available. // Use signature function if available.
signatureFunction = signatureFunction =
elementEnvironment.lookupLocalClassMember(cls, Identifiers.signature); elementEnvironment.lookupLocalClassMember(cls, Names.signature);
if (signatureFunction == null) { if (signatureFunction == null) {
// In Dart 2, a closure only needs its function type if it has a // In Dart 2, a closure only needs its function type if it has a
// signature function. // signature function.
@ -780,7 +780,7 @@ ClassFunctionType _computeFunctionType(
return null; return null;
} }
MemberEntity call = MemberEntity call =
elementEnvironment.lookupLocalClassMember(cls, Identifiers.call); elementEnvironment.lookupLocalClassMember(cls, Names.call);
if (call != null && call.isFunction) { if (call != null && call.isFunction) {
FunctionEntity callFunction = call; FunctionEntity callFunction = call;
FunctionType callType = elementEnvironment.getFunctionType(callFunction); FunctionType callType = elementEnvironment.getFunctionType(callFunction);

View file

@ -60,7 +60,7 @@ class JRecordField extends JField implements JRecordFieldInterface {
JRecordField(String name, this.box, {required bool isConst}) JRecordField(String name, this.box, {required bool isConst})
: super(box.container.library as JLibrary, box.container as JClass, : super(box.container.library as JLibrary, box.container as JClass,
Name(name, box.container.library), Name(name, box.container.library.canonicalUri),
isStatic: false, isAssignable: true, isConst: isConst); isStatic: false, isAssignable: true, isConst: isConst);
factory JRecordField.readFromDataSource(DataSourceReader source) { factory JRecordField.readFromDataSource(DataSourceReader source) {
@ -163,7 +163,7 @@ class JClosureField extends JField implements PrivatelyNamedJSEntity {
: this.internal( : this.internal(
containingClass.closureClassEntity.library, containingClass.closureClassEntity.library,
containingClass.closureClassEntity as JClosureClass, containingClass.closureClassEntity as JClosureClass,
Name(name, containingClass.closureClassEntity.library), Name(name, containingClass.closureClassEntity.library.canonicalUri),
declaredName, declaredName,
isAssignable: isAssignable, isAssignable: isAssignable,
isConst: isConst); isConst: isConst);
@ -183,7 +183,7 @@ class JClosureField extends JField implements PrivatelyNamedJSEntity {
bool isAssignable = source.readBool(); bool isAssignable = source.readBool();
source.end(tag); source.end(tag);
return JClosureField.internal( return JClosureField.internal(
cls.library, cls, Name(name, cls.library), declaredName, cls.library, cls, Name(name, cls.library.canonicalUri), declaredName,
isAssignable: isAssignable, isConst: isConst); isAssignable: isAssignable, isConst: isConst);
} }

View file

@ -172,7 +172,8 @@ class JsKernelToElementMap
LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex); LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
IndexedClass newClass = IndexedClass newClass =
JClass(newLibrary, oldClass.name, isAbstract: oldClass.isAbstract); JClass(newLibrary, oldClass.name, isAbstract: oldClass.isAbstract);
JClassEnv newEnv = env.convert(_elementMap, liveMemberUsage); JClassEnv newEnv = env.convert(_elementMap, liveMemberUsage,
(ir.Library library) => libraryMap[library]);
classMap[env.cls] = classes.register(newClass, data.convert(), newEnv); classMap[env.cls] = classes.register(newClass, data.convert(), newEnv);
assert(newClass.classIndex == oldClass.classIndex); assert(newClass.classIndex == oldClass.classIndex);
libraries.getEnv(newClass.library).registerClass(newClass.name, newEnv); libraries.getEnv(newClass.library).registerClass(newClass.name, newEnv);
@ -194,8 +195,7 @@ class JsKernelToElementMap
ClassEntity newClass = ClassEntity newClass =
oldClass != null ? classes.getEntity(oldClass.classIndex) : null; oldClass != null ? classes.getEntity(oldClass.classIndex) : null;
IndexedMember newMember; IndexedMember newMember;
Name memberName = Name(oldMember.memberName.text, newLibrary, Name memberName = oldMember.memberName;
isSetter: oldMember.memberName.isSetter);
if (oldMember.isField) { if (oldMember.isField) {
IndexedField field = oldMember; IndexedField field = oldMember;
newMember = JField(newLibrary, newClass, memberName, newMember = JField(newLibrary, newClass, memberName,
@ -610,11 +610,10 @@ class JsKernelToElementMap
}); });
} }
MemberEntity lookupClassMember(IndexedClass cls, String name, MemberEntity lookupClassMember(IndexedClass cls, Name name) {
{bool setter = false}) {
assert(checkFamily(cls)); assert(checkFamily(cls));
JClassEnv classEnv = classes.getEnv(cls); JClassEnv classEnv = classes.getEnv(cls);
return classEnv.lookupMember(this, name, setter: setter); return classEnv.lookupMember(this, name);
} }
ConstructorEntity lookupConstructor(IndexedClass cls, String name) { ConstructorEntity lookupConstructor(IndexedClass cls, String name) {
@ -647,7 +646,7 @@ class JsKernelToElementMap
assert(checkFamily(cls)); assert(checkFamily(cls));
if (data is JClassDataImpl && !data.isCallTypeComputed) { if (data is JClassDataImpl && !data.isCallTypeComputed) {
MemberEntity callMember = MemberEntity callMember =
_elementEnvironment.lookupClassMember(cls, Identifiers.call); _elementEnvironment.lookupClassMember(cls, Names.call);
if (callMember is FunctionEntity && if (callMember is FunctionEntity &&
callMember.isFunction && callMember.isFunction &&
!callMember.isAbstract) { !callMember.isAbstract) {
@ -1237,8 +1236,9 @@ class JsKernelToElementMap
} }
@override @override
Name getName(ir.Name name) { Name getName(ir.Name name, {bool setter = false}) {
return Name(name.text, name.isPrivate ? getLibrary(name.library) : null); return Name(name.text, name.isPrivate ? name.library.importUri : null,
isSetter: setter);
} }
@override @override
@ -1305,13 +1305,13 @@ class JsKernelToElementMap
Selector getGetterSelector(ir.Name irName) { Selector getGetterSelector(ir.Name irName) {
Name name = Name name =
Name(irName.text, irName.isPrivate ? getLibrary(irName.library) : null); Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
return Selector.getter(name); return Selector.getter(name);
} }
Selector getSetterSelector(ir.Name irName) { Selector getSetterSelector(ir.Name irName) {
Name name = Name name =
Name(irName.text, irName.isPrivate ? getLibrary(irName.library) : null); Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
return Selector.setter(name); return Selector.setter(name);
} }
@ -1526,8 +1526,8 @@ class JsKernelToElementMap
FunctionEntity getSuperNoSuchMethod(ClassEntity cls) { FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
while (cls != null) { while (cls != null) {
cls = elementEnvironment.getSuperClass(cls); cls = elementEnvironment.getSuperClass(cls);
MemberEntity member = elementEnvironment.lookupLocalClassMember( MemberEntity member =
cls, Identifiers.noSuchMethod_); elementEnvironment.lookupLocalClassMember(cls, Names.noSuchMethod_);
if (member != null && !member.isAbstract) { if (member != null && !member.isAbstract) {
if (member.isFunction) { if (member.isFunction) {
FunctionEntity function = member; FunctionEntity function = member;
@ -1541,7 +1541,7 @@ class JsKernelToElementMap
} }
} }
FunctionEntity function = elementEnvironment.lookupLocalClassMember( FunctionEntity function = elementEnvironment.lookupLocalClassMember(
commonElements.objectClass, Identifiers.noSuchMethod_); commonElements.objectClass, Names.noSuchMethod_);
assert(function != null, assert(function != null,
failedAt(cls, "No super noSuchMethod found for class $cls.")); failedAt(cls, "No super noSuchMethod found for class $cls."));
return function; return function;
@ -1759,7 +1759,7 @@ class JsKernelToElementMap
InterfaceType memberThisType, InterfaceType memberThisType,
ir.VariableDeclaration variable, ir.VariableDeclaration variable,
BoxLocal boxLocal, BoxLocal boxLocal,
Map<String, MemberEntity> memberMap) { Map<Name, MemberEntity> memberMap) {
JRecordField boxedField = JRecordField boxedField =
JRecordField(variable.name, boxLocal, isConst: variable.isConst); JRecordField(variable.name, boxLocal, isConst: variable.isConst);
members.register( members.register(
@ -1768,7 +1768,7 @@ class JsKernelToElementMap
ClosureMemberDefinition(computeSourceSpanFromTreeNode(variable), ClosureMemberDefinition(computeSourceSpanFromTreeNode(variable),
MemberKind.closureField, variable), MemberKind.closureField, variable),
memberThisType)); memberThisType));
memberMap[boxedField.name] = boxedField; memberMap[boxedField.memberName] = boxedField;
return boxedField; return boxedField;
} }
@ -1783,7 +1783,7 @@ class JsKernelToElementMap
if (info.boxedVariables.isNotEmpty) { if (info.boxedVariables.isNotEmpty) {
NodeBox box = info.capturedVariablesAccessor; NodeBox box = info.capturedVariablesAccessor;
Map<String, IndexedMember> memberMap = {}; Map<Name, IndexedMember> memberMap = {};
closureMigrated.JRecord container = closureMigrated.JRecord container =
closureMigrated.JRecord(member.library, box.name); closureMigrated.JRecord(member.library, box.name);
BoxLocal boxLocal = BoxLocal(container); BoxLocal boxLocal = BoxLocal(container);
@ -1851,7 +1851,7 @@ class JsKernelToElementMap
} }
String name = _computeClosureName(node); String name = _computeClosureName(node);
SourceSpan location = computeSourceSpanFromTreeNode(node); SourceSpan location = computeSourceSpanFromTreeNode(node);
Map<String, IndexedMember> memberMap = {}; Map<Name, IndexedMember> memberMap = {};
JClass classEntity = closureMigrated.JClosureClass(enclosingLibrary, name); JClass classEntity = closureMigrated.JClosureClass(enclosingLibrary, name);
// Create a classData and set up the interfaces and subclass // Create a classData and set up the interfaces and subclass
@ -1918,7 +1918,7 @@ class JsKernelToElementMap
closureData.callType, closureData.callType,
node, node,
typeVariableAccess)); typeVariableAccess));
memberMap[callMethod.name] = closureClassInfo.callMethod = callMethod; memberMap[callMethod.memberName] = closureClassInfo.callMethod = callMethod;
return closureClassInfo; return closureClassInfo;
} }
@ -1928,7 +1928,7 @@ class JsKernelToElementMap
InterfaceType memberThisType, InterfaceType memberThisType,
KernelScopeInfo info, KernelScopeInfo info,
Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope, Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope,
Map<String, MemberEntity> memberMap) { Map<Name, MemberEntity> memberMap) {
// TODO(efortuna): Limit field number usage to when we need to distinguish // TODO(efortuna): Limit field number usage to when we need to distinguish
// between two variables with the same name from different scopes. // between two variables with the same name from different scopes.
int fieldNumber = 0; int fieldNumber = 0;
@ -2027,7 +2027,7 @@ class JsKernelToElementMap
ir.VariableDeclaration capturedLocal, ir.VariableDeclaration capturedLocal,
JsClosureClassInfo closureClassInfo, JsClosureClassInfo closureClassInfo,
InterfaceType memberThisType, InterfaceType memberThisType,
Map<String, MemberEntity> memberMap, Map<Name, MemberEntity> memberMap,
ir.TreeNode sourceNode, ir.TreeNode sourceNode,
Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope, Map<ir.VariableDeclaration, JRecordField> recordFieldsVisibleInScope,
int fieldNumber) { int fieldNumber) {
@ -2051,7 +2051,7 @@ class JsKernelToElementMap
ClosureMemberDefinition(computeSourceSpanFromTreeNode(sourceNode), ClosureMemberDefinition(computeSourceSpanFromTreeNode(sourceNode),
MemberKind.closureField, sourceNode), MemberKind.closureField, sourceNode),
memberThisType)); memberThisType));
memberMap[closureField.name] = closureField; memberMap[closureField.memberName] = closureField;
closureClassInfo.registerFieldForLocal(recordField.box, closureField); closureClassInfo.registerFieldForLocal(recordField.box, closureField);
closureClassInfo.registerFieldForBoxedVariable(capturedLocal, recordField); closureClassInfo.registerFieldForBoxedVariable(capturedLocal, recordField);
return true; return true;
@ -2059,7 +2059,7 @@ class JsKernelToElementMap
void _constructSignatureMethod( void _constructSignatureMethod(
JsClosureClassInfo closureClassInfo, JsClosureClassInfo closureClassInfo,
Map<String, MemberEntity> memberMap, Map<Name, MemberEntity> memberMap,
ir.FunctionNode closureSourceNode, ir.FunctionNode closureSourceNode,
InterfaceType memberThisType, InterfaceType memberThisType,
SourceSpan location, SourceSpan location,
@ -2074,7 +2074,7 @@ class JsKernelToElementMap
memberThisType, memberThisType,
closureSourceNode.typeParameters, closureSourceNode.typeParameters,
typeVariableAccess)); typeVariableAccess));
memberMap[signatureMethod.name] = memberMap[signatureMethod.memberName] =
closureClassInfo.signatureMethod = signatureMethod; closureClassInfo.signatureMethod = signatureMethod;
} }
@ -2082,7 +2082,7 @@ class JsKernelToElementMap
String name, String name,
JsClosureClassInfo closureClassInfo, JsClosureClassInfo closureClassInfo,
InterfaceType memberThisType, InterfaceType memberThisType,
Map<String, MemberEntity> memberMap, Map<Name, MemberEntity> memberMap,
ir.TreeNode sourceNode, ir.TreeNode sourceNode,
bool isConst, bool isConst,
bool isAssignable, bool isAssignable,
@ -2097,7 +2097,7 @@ class JsKernelToElementMap
ClosureMemberDefinition(computeSourceSpanFromTreeNode(sourceNode), ClosureMemberDefinition(computeSourceSpanFromTreeNode(sourceNode),
MemberKind.closureField, sourceNode), MemberKind.closureField, sourceNode),
memberThisType)); memberThisType));
memberMap[closureField.name] = closureField; memberMap[closureField.memberName] = closureField;
return closureField; return closureField;
} }
@ -2361,10 +2361,9 @@ class JsElementEnvironment extends ElementEnvironment
} }
@override @override
MemberEntity lookupLocalClassMember(ClassEntity cls, String name, MemberEntity lookupLocalClassMember(ClassEntity cls, Name name,
{bool setter = false, bool required = false}) { {bool required = false}) {
MemberEntity member = MemberEntity member = elementMap.lookupClassMember(cls, name);
elementMap.lookupClassMember(cls, name, setter: setter);
if (member == null && required) { if (member == null && required) {
throw failedAt(CURRENT_ELEMENT_SPANNABLE, throw failedAt(CURRENT_ELEMENT_SPANNABLE,
"The member '$name' was not found in ${cls.name}."); "The member '$name' was not found in ${cls.name}.");

View file

@ -281,8 +281,8 @@ class JGenerativeConstructor extends JConstructor {
bool isExternal = source.readBool(); bool isExternal = source.readBool();
bool isConst = source.readBool(); bool isConst = source.readBool();
source.end(tag); source.end(tag);
return JGenerativeConstructor( return JGenerativeConstructor(enclosingClass,
enclosingClass, Name(name, enclosingClass.library), parameterStructure, Name(name, enclosingClass.library.canonicalUri), parameterStructure,
isExternal: isExternal, isConst: isConst); isExternal: isExternal, isConst: isConst);
} }
@ -331,8 +331,8 @@ class JFactoryConstructor extends JConstructor {
bool isConst = source.readBool(); bool isConst = source.readBool();
bool isFromEnvironmentConstructor = source.readBool(); bool isFromEnvironmentConstructor = source.readBool();
source.end(tag); source.end(tag);
return JFactoryConstructor( return JFactoryConstructor(enclosingClass,
enclosingClass, Name(name, enclosingClass.library), parameterStructure, Name(name, enclosingClass.library.canonicalUri), parameterStructure,
isExternal: isExternal, isExternal: isExternal,
isConst: isConst, isConst: isConst,
isFromEnvironmentConstructor: isFromEnvironmentConstructor); isFromEnvironmentConstructor: isFromEnvironmentConstructor);
@ -423,7 +423,7 @@ class JMethod extends JFunction {
library = enclosingClass.library; library = enclosingClass.library;
break; break;
} }
String name = source.readString(); Name memberName = source.readMemberName();
ParameterStructure parameterStructure = ParameterStructure parameterStructure =
ParameterStructure.readFromDataSource(source); ParameterStructure.readFromDataSource(source);
AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values); AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
@ -431,8 +431,8 @@ class JMethod extends JFunction {
bool isExternal = source.readBool(); bool isExternal = source.readBool();
bool isAbstract = source.readBool(); bool isAbstract = source.readBool();
source.end(tag); source.end(tag);
return JMethod(library, enclosingClass, Name(name, library), return JMethod(
parameterStructure, asyncMarker, library, enclosingClass, memberName, parameterStructure, asyncMarker,
isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
} }
@ -447,7 +447,7 @@ class JMethod extends JFunction {
sink.writeEnum(MemberContextKind.library); sink.writeEnum(MemberContextKind.library);
sink.writeLibrary(library); sink.writeLibrary(library);
} }
sink.writeString(name); sink.writeMemberName(memberName);
parameterStructure.writeToDataSink(sink); parameterStructure.writeToDataSink(sink);
sink.writeEnum(asyncMarker); sink.writeEnum(asyncMarker);
sink.writeBool(isStatic); sink.writeBool(isStatic);
@ -531,13 +531,13 @@ class JGetter extends JFunction {
library = enclosingClass.library; library = enclosingClass.library;
break; break;
} }
String name = source.readString(); Name memberName = source.readMemberName();
AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values); AsyncMarker asyncMarker = source.readEnum(AsyncMarker.values);
bool isStatic = source.readBool(); bool isStatic = source.readBool();
bool isExternal = source.readBool(); bool isExternal = source.readBool();
bool isAbstract = source.readBool(); bool isAbstract = source.readBool();
source.end(tag); source.end(tag);
return JGetter(library, enclosingClass, Name(name, library), asyncMarker, return JGetter(library, enclosingClass, memberName, asyncMarker,
isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
} }
@ -552,7 +552,7 @@ class JGetter extends JFunction {
sink.writeEnum(MemberContextKind.library); sink.writeEnum(MemberContextKind.library);
sink.writeLibrary(library); sink.writeLibrary(library);
} }
sink.writeString(name); sink.writeMemberName(memberName);
sink.writeEnum(asyncMarker); sink.writeEnum(asyncMarker);
sink.writeBool(isStatic); sink.writeBool(isStatic);
sink.writeBool(isExternal); sink.writeBool(isExternal);
@ -597,12 +597,12 @@ class JSetter extends JFunction {
library = enclosingClass.library; library = enclosingClass.library;
break; break;
} }
String name = source.readString(); Name memberName = source.readMemberName();
bool isStatic = source.readBool(); bool isStatic = source.readBool();
bool isExternal = source.readBool(); bool isExternal = source.readBool();
bool isAbstract = source.readBool(); bool isAbstract = source.readBool();
source.end(tag); source.end(tag);
return JSetter(library, enclosingClass, Name(name, library, isSetter: true), return JSetter(library, enclosingClass, memberName,
isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract); isStatic: isStatic, isExternal: isExternal, isAbstract: isAbstract);
} }
@ -617,7 +617,7 @@ class JSetter extends JFunction {
sink.writeEnum(MemberContextKind.library); sink.writeEnum(MemberContextKind.library);
sink.writeLibrary(library); sink.writeLibrary(library);
} }
sink.writeString(name); sink.writeMemberName(memberName);
sink.writeBool(isStatic); sink.writeBool(isStatic);
sink.writeBool(isExternal); sink.writeBool(isExternal);
sink.writeBool(isAbstract); sink.writeBool(isAbstract);
@ -664,12 +664,12 @@ class JField extends JMember implements FieldEntity, IndexedField {
library = enclosingClass.library; library = enclosingClass.library;
break; break;
} }
String name = source.readString(); Name memberName = source.readMemberName();
bool isStatic = source.readBool(); bool isStatic = source.readBool();
bool isAssignable = source.readBool(); bool isAssignable = source.readBool();
bool isConst = source.readBool(); bool isConst = source.readBool();
source.end(tag); source.end(tag);
return JField(library, enclosingClass, Name(name, library), return JField(library, enclosingClass, memberName,
isStatic: isStatic, isAssignable: isAssignable, isConst: isConst); isStatic: isStatic, isAssignable: isAssignable, isConst: isConst);
} }
@ -684,7 +684,7 @@ class JField extends JMember implements FieldEntity, IndexedField {
sink.writeEnum(MemberContextKind.library); sink.writeEnum(MemberContextKind.library);
sink.writeLibrary(library); sink.writeLibrary(library);
} }
sink.writeString(name); sink.writeMemberName(memberName);
sink.writeBool(isStatic); sink.writeBool(isStatic);
sink.writeBool(isAssignable); sink.writeBool(isAssignable);
sink.writeBool(isConst); sink.writeBool(isConst);

View file

@ -11,6 +11,7 @@ import 'package:kernel/ast.dart' as ir;
import '../constants/values.dart'; import '../constants/values.dart';
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/indexed.dart'; import '../elements/indexed.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../ir/element_map.dart'; import '../ir/element_map.dart';
import '../ir/static_type_cache.dart'; import '../ir/static_type_cache.dart';
@ -217,8 +218,7 @@ abstract class JClassEnv {
/// Return the [MemberEntity] for the member [name] in the class. If [setter] /// Return the [MemberEntity] for the member [name] in the class. If [setter]
/// is `true`, the setter or assignable field corresponding to [name] is /// is `true`, the setter or assignable field corresponding to [name] is
/// returned. /// returned.
MemberEntity lookupMember(IrToElementMap elementMap, String name, MemberEntity lookupMember(IrToElementMap elementMap, Name name);
{bool setter = false});
/// Calls [f] for each member of [cls]. /// Calls [f] for each member of [cls].
void forEachMember(IrToElementMap elementMap, void f(MemberEntity member)); void forEachMember(IrToElementMap elementMap, void f(MemberEntity member));
@ -244,8 +244,7 @@ class JClassEnvImpl implements JClassEnv {
@override @override
final ir.Class cls; final ir.Class cls;
final Map<String, ir.Member> _constructorMap; final Map<String, ir.Member> _constructorMap;
final Map<String, ir.Member> _memberMap; final Map<Name, ir.Member> _memberMap;
final Map<String, ir.Member> _setterMap;
final List<ir.Member> _members; // in declaration order. final List<ir.Member> _members; // in declaration order.
@override @override
final bool isMixinApplicationWithMembers; final bool isMixinApplicationWithMembers;
@ -253,23 +252,20 @@ class JClassEnvImpl implements JClassEnv {
/// Constructor bodies created for this class. /// Constructor bodies created for this class.
List<ConstructorBodyEntity> _constructorBodyList; List<ConstructorBodyEntity> _constructorBodyList;
JClassEnvImpl(this.cls, this._constructorMap, this._memberMap, JClassEnvImpl(this.cls, this._constructorMap, this._memberMap, this._members,
this._setterMap, this._members, this.isMixinApplicationWithMembers); this.isMixinApplicationWithMembers);
factory JClassEnvImpl.readFromDataSource(DataSourceReader source) { factory JClassEnvImpl.readFromDataSource(DataSourceReader source) {
source.begin(tag); source.begin(tag);
ir.Class cls = source.readClassNode(); ir.Class cls = source.readClassNode();
Map<String, ir.Member> constructorMap = Map<String, ir.Member> constructorMap =
source.readStringMap(source.readMemberNode); source.readStringMap(source.readMemberNode);
Map<String, ir.Member> memberMap = Map<Name, ir.Member> memberMap = source.readNameMap(source.readMemberNode);
source.readStringMap(source.readMemberNode);
Map<String, ir.Member> setterMap =
source.readStringMap(source.readMemberNode);
List<ir.Member> members = source.readMemberNodes(); List<ir.Member> members = source.readMemberNodes();
bool isSuperMixinApplication = source.readBool(); bool isSuperMixinApplication = source.readBool();
source.end(tag); source.end(tag);
return JClassEnvImpl(cls, constructorMap, memberMap, setterMap, members, return JClassEnvImpl(
isSuperMixinApplication); cls, constructorMap, memberMap, members, isSuperMixinApplication);
} }
@override @override
@ -278,8 +274,7 @@ class JClassEnvImpl implements JClassEnv {
sink.begin(tag); sink.begin(tag);
sink.writeClassNode(cls); sink.writeClassNode(cls);
sink.writeStringMap(_constructorMap, sink.writeMemberNode); sink.writeStringMap(_constructorMap, sink.writeMemberNode);
sink.writeStringMap(_memberMap, sink.writeMemberNode); sink.writeNameMap(_memberMap, sink.writeMemberNode);
sink.writeStringMap(_setterMap, sink.writeMemberNode);
sink.writeMemberNodes(_members); sink.writeMemberNodes(_members);
sink.writeBool(isMixinApplicationWithMembers); sink.writeBool(isMixinApplicationWithMembers);
sink.end(tag); sink.end(tag);
@ -289,9 +284,8 @@ class JClassEnvImpl implements JClassEnv {
bool get isUnnamedMixinApplication => cls.isAnonymousMixin; bool get isUnnamedMixinApplication => cls.isAnonymousMixin;
@override @override
MemberEntity lookupMember(IrToElementMap elementMap, String name, MemberEntity lookupMember(IrToElementMap elementMap, Name name) {
{bool setter = false}) { ir.Member member = _memberMap[name];
ir.Member member = setter ? _setterMap[name] : _memberMap[name];
return member != null ? elementMap.getMember(member) : null; return member != null ? elementMap.getMember(member) : null;
} }
@ -332,14 +326,14 @@ class RecordEnv implements JClassEnv {
/// debugging data stream. /// debugging data stream.
static const String tag = 'record-env'; static const String tag = 'record-env';
final Map<String, IndexedMember> _memberMap; final Map<Name, IndexedMember> _memberMap;
RecordEnv(this._memberMap); RecordEnv(this._memberMap);
factory RecordEnv.readFromDataSource(DataSourceReader source) { factory RecordEnv.readFromDataSource(DataSourceReader source) {
source.begin(tag); source.begin(tag);
Map<String, IndexedMember> _memberMap = Map<Name, IndexedMember> _memberMap =
source.readStringMap(() => source.readMember()); source.readNameMap(() => source.readMember());
source.end(tag); source.end(tag);
return RecordEnv(_memberMap); return RecordEnv(_memberMap);
} }
@ -348,7 +342,7 @@ class RecordEnv implements JClassEnv {
void writeToDataSink(DataSinkWriter sink) { void writeToDataSink(DataSinkWriter sink) {
sink.writeEnum(JClassEnvKind.record); sink.writeEnum(JClassEnvKind.record);
sink.begin(tag); sink.begin(tag);
sink.writeStringMap( sink.writeNameMap(
_memberMap, (IndexedMember member) => sink.writeMember(member)); _memberMap, (IndexedMember member) => sink.writeMember(member));
sink.end(tag); sink.end(tag);
} }
@ -376,8 +370,7 @@ class RecordEnv implements JClassEnv {
} }
@override @override
MemberEntity lookupMember(IrToElementMap elementMap, String name, MemberEntity lookupMember(IrToElementMap elementMap, Name name) {
{bool setter = false}) {
return _memberMap[name]; return _memberMap[name];
} }
@ -396,12 +389,12 @@ class ClosureClassEnv extends RecordEnv {
/// debugging data stream. /// debugging data stream.
static const String tag = 'closure-class-env'; static const String tag = 'closure-class-env';
ClosureClassEnv(Map<String, MemberEntity> memberMap) : super(memberMap); ClosureClassEnv(Map<Name, MemberEntity> memberMap) : super(memberMap);
factory ClosureClassEnv.readFromDataSource(DataSourceReader source) { factory ClosureClassEnv.readFromDataSource(DataSourceReader source) {
source.begin(tag); source.begin(tag);
Map<String, IndexedMember> _memberMap = Map<Name, IndexedMember> _memberMap =
source.readStringMap(() => source.readMember()); source.readNameMap(() => source.readMember());
source.end(tag); source.end(tag);
return ClosureClassEnv(_memberMap); return ClosureClassEnv(_memberMap);
} }
@ -410,20 +403,10 @@ class ClosureClassEnv extends RecordEnv {
void writeToDataSink(DataSinkWriter sink) { void writeToDataSink(DataSinkWriter sink) {
sink.writeEnum(JClassEnvKind.closure); sink.writeEnum(JClassEnvKind.closure);
sink.begin(tag); sink.begin(tag);
sink.writeStringMap( sink.writeNameMap(
_memberMap, (IndexedMember member) => sink.writeMember(member)); _memberMap, (IndexedMember member) => sink.writeMember(member));
sink.end(tag); sink.end(tag);
} }
@override
MemberEntity lookupMember(IrToElementMap elementMap, String name,
{bool setter = false}) {
if (setter) {
// All closure fields are final.
return null;
}
return super.lookupMember(elementMap, name, setter: setter);
}
} }
/// Enum used for identifying [JClassData] subclasses in serialization. /// Enum used for identifying [JClassData] subclasses in serialization.

View file

@ -545,11 +545,9 @@ class JsClosedWorld implements JClosedWorld {
@override @override
bool hasElementIn(ClassEntity cls, Name name, Entity element) { bool hasElementIn(ClassEntity cls, Name name, Entity element) {
while (cls != null) { while (cls != null) {
MemberEntity member = elementEnvironment MemberEntity member =
.lookupLocalClassMember(cls, name.text, setter: name.isSetter); elementEnvironment.lookupLocalClassMember(cls, name);
if (member != null && if (member != null && !member.isAbstract) {
!member.isAbstract &&
(!name.isPrivate || member.library == name.library)) {
return member == element; return member == element;
} }
cls = elementEnvironment.getSuperClass(cls); cls = elementEnvironment.getSuperClass(cls);
@ -563,8 +561,8 @@ class JsClosedWorld implements JClosedWorld {
{ClassEntity stopAtSuperclass}) { {ClassEntity stopAtSuperclass}) {
assert(classHierarchy.isInstantiated(cls), assert(classHierarchy.isInstantiated(cls),
failedAt(cls, '$cls has not been instantiated.')); failedAt(cls, '$cls has not been instantiated.'));
MemberEntity element = elementEnvironment MemberEntity element =
.lookupClassMember(cls, selector.name, setter: selector.isSetter); elementEnvironment.lookupClassMember(cls, selector.memberName);
if (element == null) return false; if (element == null) return false;
if (element.isAbstract) { if (element.isAbstract) {

View file

@ -14,7 +14,6 @@ import '../constants/values.dart';
import '../deferred_load/output_unit.dart' show OutputUnit, OutputUnitData; import '../deferred_load/output_unit.dart' show OutputUnit, OutputUnitData;
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/indexed.dart'; import '../elements/indexed.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../inferrer/abstract_value_strategy.dart'; import '../inferrer/abstract_value_strategy.dart';
import '../ir/closure.dart'; import '../ir/closure.dart';
@ -302,17 +301,7 @@ class JsClosedWorldBuilder {
Set<FunctionEntity> methodsNeedingSignature = Set<FunctionEntity> methodsNeedingSignature =
map.toBackendFunctionSet(rtiNeed.methodsNeedingSignature); map.toBackendFunctionSet(rtiNeed.methodsNeedingSignature);
Set<Selector> selectorsNeedingTypeArguments = Set<Selector> selectorsNeedingTypeArguments =
rtiNeed.selectorsNeedingTypeArguments.map((Selector selector) { rtiNeed.selectorsNeedingTypeArguments;
if (selector.memberName.isPrivate) {
return Selector(
selector.kind,
PrivateName(selector.memberName.text,
map.toBackendLibrary(selector.memberName.library),
isSetter: selector.memberName.isSetter),
selector.callStructure);
}
return selector;
}).toSet();
return RuntimeTypesNeedImpl( return RuntimeTypesNeedImpl(
_elementEnvironment, _elementEnvironment,
classesNeedingTypeArguments, classesNeedingTypeArguments,

View file

@ -258,11 +258,11 @@ class KernelToElementMap
return cls; return cls;
} }
MemberEntity lookupClassMember(IndexedClass cls, String name, MemberEntity lookupClassMember(IndexedClass cls, Name name,
{bool setter = false}) { {bool setter = false}) {
assert(checkFamily(cls)); assert(checkFamily(cls));
KClassEnv classEnv = classes.getEnv(cls); KClassEnv classEnv = classes.getEnv(cls);
return classEnv.lookupMember(this, name, setter: setter); return classEnv.lookupMember(this, name);
} }
ConstructorEntity lookupConstructor(IndexedClass cls, String name) { ConstructorEntity lookupConstructor(IndexedClass cls, String name) {
@ -303,7 +303,7 @@ class KernelToElementMap
assert(checkFamily(cls)); assert(checkFamily(cls));
if (data is KClassDataImpl && !data.isCallTypeComputed) { if (data is KClassDataImpl && !data.isCallTypeComputed) {
MemberEntity callMember = MemberEntity callMember =
_elementEnvironment.lookupClassMember(cls, Identifiers.call); _elementEnvironment.lookupClassMember(cls, Names.call);
if (callMember is FunctionEntity && if (callMember is FunctionEntity &&
callMember.isFunction && callMember.isFunction &&
!callMember.isAbstract) { !callMember.isAbstract) {
@ -898,10 +898,10 @@ class KernelToElementMap
: ir.EvaluationMode.strong); : ir.EvaluationMode.strong);
} }
/// Returns the [Name] corresponding to [name].
@override @override
Name getName(ir.Name name) { Name getName(ir.Name name, {bool setter = false}) {
return Name(name.text, name.isPrivate ? getLibrary(name.library) : null); return Name(name.text, name.isPrivate ? name.library.importUri : null,
isSetter: setter);
} }
/// Returns the [CallStructure] corresponding to the [arguments]. /// Returns the [CallStructure] corresponding to the [arguments].
@ -964,13 +964,13 @@ class KernelToElementMap
Selector getGetterSelector(ir.Name irName) { Selector getGetterSelector(ir.Name irName) {
Name name = Name name =
Name(irName.text, irName.isPrivate ? getLibrary(irName.library) : null); Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
return Selector.getter(name); return Selector.getter(name);
} }
Selector getSetterSelector(ir.Name irName) { Selector getSetterSelector(ir.Name irName) {
Name name = Name name =
Name(irName.text, irName.isPrivate ? getLibrary(irName.library) : null); Name(irName.text, irName.isPrivate ? irName.library.importUri : null);
return Selector.setter(name); return Selector.setter(name);
} }
@ -1221,8 +1221,8 @@ class KernelToElementMap
FunctionEntity getSuperNoSuchMethod(ClassEntity cls) { FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
while (cls != null) { while (cls != null) {
cls = elementEnvironment.getSuperClass(cls); cls = elementEnvironment.getSuperClass(cls);
MemberEntity member = elementEnvironment.lookupLocalClassMember( MemberEntity member =
cls, Identifiers.noSuchMethod_); elementEnvironment.lookupLocalClassMember(cls, Names.noSuchMethod_);
if (member != null && !member.isAbstract) { if (member != null && !member.isAbstract) {
if (member.isFunction) { if (member.isFunction) {
FunctionEntity function = member; FunctionEntity function = member;
@ -1236,7 +1236,7 @@ class KernelToElementMap
} }
} }
FunctionEntity function = elementEnvironment.lookupLocalClassMember( FunctionEntity function = elementEnvironment.lookupLocalClassMember(
commonElements.objectClass, Identifiers.noSuchMethod_); commonElements.objectClass, Names.noSuchMethod_);
assert(function != null, assert(function != null,
failedAt(cls, "No super noSuchMethod found for class $cls.")); failedAt(cls, "No super noSuchMethod found for class $cls."));
return function; return function;
@ -1899,10 +1899,9 @@ class KernelElementEnvironment extends ElementEnvironment
} }
@override @override
MemberEntity lookupLocalClassMember(ClassEntity cls, String name, MemberEntity lookupLocalClassMember(ClassEntity cls, Name name,
{bool setter = false, bool required = false}) { {bool required = false}) {
MemberEntity member = MemberEntity member = elementMap.lookupClassMember(cls, name);
elementMap.lookupClassMember(cls, name, setter: setter);
if (member == null && required) { if (member == null && required) {
throw failedAt(CURRENT_ELEMENT_SPANNABLE, throw failedAt(CURRENT_ELEMENT_SPANNABLE,
"The member '$name' was not found in ${cls.name}."); "The member '$name' was not found in ${cls.name}.");

View file

@ -16,6 +16,7 @@ import 'package:collection/collection.dart' show mergeSort; // a stable sort.
import '../common.dart'; import '../common.dart';
import '../constants/values.dart'; import '../constants/values.dart';
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../ir/element_map.dart'; import '../ir/element_map.dart';
import '../ir/static_type_cache.dart'; import '../ir/static_type_cache.dart';
@ -162,7 +163,7 @@ class KLibraryEnv {
/// Convert this [KLibraryEnv] to a corresponding [JLibraryEnv] containing /// Convert this [KLibraryEnv] to a corresponding [JLibraryEnv] containing
/// only the members in [liveMembers]. /// only the members in [liveMembers].
JLibraryEnv convert(IrToElementMap elementMap, JLibraryEnv convert(IrToElementMap kElementMap,
Map<MemberEntity, MemberUsage> liveMemberUsage) { Map<MemberEntity, MemberUsage> liveMemberUsage) {
Map<String, ir.Member> memberMap; Map<String, ir.Member> memberMap;
Map<String, ir.Member> setterMap; Map<String, ir.Member> setterMap;
@ -171,7 +172,7 @@ class KLibraryEnv {
} else { } else {
memberMap = <String, ir.Member>{}; memberMap = <String, ir.Member>{};
_memberMap.forEach((String name, ir.Member node) { _memberMap.forEach((String name, ir.Member node) {
MemberEntity member = elementMap.getMember(node); MemberEntity member = kElementMap.getMember(node);
if (liveMemberUsage.containsKey(member)) { if (liveMemberUsage.containsKey(member)) {
memberMap[name] = node; memberMap[name] = node;
} }
@ -182,7 +183,7 @@ class KLibraryEnv {
} else { } else {
setterMap = <String, ir.Member>{}; setterMap = <String, ir.Member>{};
_setterMap.forEach((String name, ir.Member node) { _setterMap.forEach((String name, ir.Member node) {
MemberEntity member = elementMap.getMember(node); MemberEntity member = kElementMap.getMember(node);
if (liveMemberUsage.containsKey(member)) { if (liveMemberUsage.containsKey(member)) {
setterMap[name] = node; setterMap[name] = node;
} }
@ -251,11 +252,8 @@ abstract class KClassEnv {
/// Ensures that all members have been computed for [cls]. /// Ensures that all members have been computed for [cls].
void ensureMembers(KernelToElementMap elementMap); void ensureMembers(KernelToElementMap elementMap);
/// Return the [MemberEntity] for the member [name] in the class. If [setter] /// Return the [MemberEntity] for the member [name] in the class.
/// is `true`, the setter or assignable field corresponding to [name] is MemberEntity lookupMember(IrToElementMap elementMap, Name name);
/// returned.
MemberEntity lookupMember(IrToElementMap elementMap, String name,
{bool setter = false});
/// Calls [f] for each member of [cls]. /// Calls [f] for each member of [cls].
void forEachMember(IrToElementMap elementMap, void f(MemberEntity member)); void forEachMember(IrToElementMap elementMap, void f(MemberEntity member));
@ -273,8 +271,13 @@ abstract class KClassEnv {
/// Convert this [KClassEnv] to the corresponding [JClassEnv] containing only /// Convert this [KClassEnv] to the corresponding [JClassEnv] containing only
/// the members in [liveMembers]. /// the members in [liveMembers].
JClassEnv convert(IrToElementMap elementMap, ///
Map<MemberEntity, MemberUsage> liveMemberUsage); /// [getJLibrary] returns the [LibraryEntity] in the J-model corresponding to
/// a [ir.Library] node.
JClassEnv convert(
IrToElementMap kElementMap,
Map<MemberEntity, MemberUsage> liveMemberUsage,
LibraryEntity Function(ir.Library library) getJLibrary);
/// Returns `true` if [node] is a known member of this class. /// Returns `true` if [node] is a known member of this class.
/// ///
@ -299,8 +302,7 @@ class KClassEnvImpl implements KClassEnv {
final ir.Class cls; final ir.Class cls;
Map<String, ir.Member> _constructorMap; Map<String, ir.Member> _constructorMap;
Map<String, ir.Member> _memberMap; Map<Name, ir.Member> _memberMap;
Map<String, ir.Member> _setterMap;
List<ir.Member> _members; // in declaration order. List<ir.Member> _members; // in declaration order.
bool _isMixinApplicationWithMembers; bool _isMixinApplicationWithMembers;
@ -310,7 +312,7 @@ class KClassEnvImpl implements KClassEnv {
KClassEnvImpl(this.cls); KClassEnvImpl(this.cls);
KClassEnvImpl.internal(this.cls, this._constructorMap, this._memberMap, KClassEnvImpl.internal(this.cls, this._constructorMap, this._memberMap,
this._setterMap, this._members, this._isMixinApplicationWithMembers); this._members, this._isMixinApplicationWithMembers);
@override @override
bool get isUnnamedMixinApplication => cls.isAnonymousMixin; bool get isUnnamedMixinApplication => cls.isAnonymousMixin;
@ -325,7 +327,6 @@ class KClassEnvImpl implements KClassEnv {
bool checkHasMember(ir.Member node) { bool checkHasMember(ir.Member node) {
if (_memberMap == null) return false; if (_memberMap == null) return false;
return _memberMap.values.contains(node) || return _memberMap.values.contains(node) ||
_setterMap.values.contains(node) ||
_constructorMap.values.contains(node); _constructorMap.values.contains(node);
} }
@ -337,8 +338,7 @@ class KClassEnvImpl implements KClassEnv {
void _ensureMaps(KernelToElementMap elementMap) { void _ensureMaps(KernelToElementMap elementMap) {
if (_memberMap != null) return; if (_memberMap != null) return;
_memberMap = <String, ir.Member>{}; _memberMap = <Name, ir.Member>{};
_setterMap = <String, ir.Member>{};
_constructorMap = <String, ir.Member>{}; _constructorMap = <String, ir.Member>{};
var members = <ir.Member>[]; var members = <ir.Member>[];
_isMixinApplicationWithMembers = false; _isMixinApplicationWithMembers = false;
@ -346,10 +346,10 @@ class KClassEnvImpl implements KClassEnv {
void addField(ir.Field member, {bool includeStatic}) { void addField(ir.Field member, {bool includeStatic}) {
if (!includeStatic && member.isStatic) return; if (!includeStatic && member.isStatic) return;
if (isRedirectingFactoryField(member)) return; if (isRedirectingFactoryField(member)) return;
var name = member.name.text; var name = elementMap.getName(member.name);
_memberMap[name] = member; _memberMap[name] = member;
if (member.hasSetter) { if (member.hasSetter) {
_setterMap[name] = member; _memberMap[name.setter] = member;
} }
members.add(member); members.add(member);
} }
@ -361,30 +361,18 @@ class KClassEnvImpl implements KClassEnv {
if (memberIsIgnorable(member, cls: cls)) return; if (memberIsIgnorable(member, cls: cls)) return;
if (!includeStatic && member.isStatic) return; if (!includeStatic && member.isStatic) return;
if (member.isNoSuchMethodForwarder) { if (member.isNoSuchMethodForwarder) {
// TODO(sigmund): remove once #33732 is fixed. if (!includeNoSuchMethodForwarders) {
if (!includeNoSuchMethodForwarders ||
member.name.isPrivate &&
member.name.libraryName != member.enclosingLibrary.reference) {
return; return;
} }
} }
var name = member.name.text;
if (member.kind == ir.ProcedureKind.Factory) { if (member.kind == ir.ProcedureKind.Factory) {
if (member.isRedirectingFactory) { if (member.isRedirectingFactory) {
// Don't include redirecting factories. // Don't include redirecting factories.
return; return;
} }
_constructorMap[name] = member; _constructorMap[member.name.text] = member;
} else if (member.kind == ir.ProcedureKind.Setter) {
_setterMap[name] = member;
members.add(member);
if (isFromMixinApplication) {
_isMixinApplicationWithMembers = true;
}
} else { } else {
assert(member.kind == ir.ProcedureKind.Method || var name = elementMap.getName(member.name, setter: member.isSetter);
member.kind == ir.ProcedureKind.Getter ||
member.kind == ir.ProcedureKind.Operator);
_memberMap[name] = member; _memberMap[name] = member;
members.add(member); members.add(member);
if (isFromMixinApplication) { if (isFromMixinApplication) {
@ -438,10 +426,9 @@ class KClassEnvImpl implements KClassEnv {
} }
@override @override
MemberEntity lookupMember(IrToElementMap elementMap, String name, MemberEntity lookupMember(IrToElementMap elementMap, Name name) {
{bool setter = false}) {
_ensureMaps(elementMap); _ensureMaps(elementMap);
ir.Member member = setter ? _setterMap[name] : _memberMap[name]; ir.Member member = _memberMap[name];
return member != null ? elementMap.getMember(member) : null; return member != null ? elementMap.getMember(member) : null;
} }
@ -480,57 +467,47 @@ class KClassEnvImpl implements KClassEnv {
} }
@override @override
JClassEnv convert(IrToElementMap elementMap, JClassEnv convert(
Map<MemberEntity, MemberUsage> liveMemberUsage) { IrToElementMap kElementMap,
Map<MemberEntity, MemberUsage> liveMemberUsage,
LibraryEntity Function(ir.Library library) getJLibrary) {
Map<String, ir.Member> constructorMap; Map<String, ir.Member> constructorMap;
Map<String, ir.Member> memberMap; Map<Name, ir.Member> memberMap;
Map<String, ir.Member> setterMap;
List<ir.Member> members; List<ir.Member> members;
if (_constructorMap == null) { if (_constructorMap == null) {
constructorMap = const <String, ir.Member>{}; constructorMap = const <String, ir.Member>{};
} else { } else {
constructorMap = <String, ir.Member>{}; constructorMap = <String, ir.Member>{};
_constructorMap.forEach((String name, ir.Member node) { _constructorMap.forEach((String name, ir.Member node) {
MemberEntity member = elementMap.getMember(node); MemberEntity member = kElementMap.getMember(node);
if (liveMemberUsage.containsKey(member)) { if (liveMemberUsage.containsKey(member)) {
constructorMap[name] = node; constructorMap[name] = node;
} }
}); });
} }
if (_memberMap == null) { if (_memberMap == null) {
memberMap = const <String, ir.Member>{}; memberMap = const <Name, ir.Member>{};
} else { } else {
memberMap = <String, ir.Member>{}; memberMap = <Name, ir.Member>{};
_memberMap.forEach((String name, ir.Member node) { _memberMap.forEach((Name name, ir.Member node) {
MemberEntity member = elementMap.getMember(node); MemberEntity member = kElementMap.getMember(node);
if (liveMemberUsage.containsKey(member)) { if (liveMemberUsage.containsKey(member)) {
memberMap[name] = node; memberMap[name] = node;
} }
}); });
} }
if (_setterMap == null) {
setterMap = const <String, ir.Member>{};
} else {
setterMap = <String, ir.Member>{};
_setterMap.forEach((String name, ir.Member node) {
MemberEntity member = elementMap.getMember(node);
if (liveMemberUsage.containsKey(member)) {
setterMap[name] = node;
}
});
}
if (_members == null) { if (_members == null) {
members = const <ir.Member>[]; members = const <ir.Member>[];
} else { } else {
members = <ir.Member>[]; members = <ir.Member>[];
_members.forEach((ir.Member node) { _members.forEach((ir.Member node) {
MemberEntity member = elementMap.getMember(node); MemberEntity member = kElementMap.getMember(node);
if (liveMemberUsage.containsKey(member)) { if (liveMemberUsage.containsKey(member)) {
members.add(node); members.add(node);
} }
}); });
} }
return JClassEnvImpl(cls, constructorMap, memberMap, setterMap, members, return JClassEnvImpl(cls, constructorMap, memberMap, members,
_isMixinApplicationWithMembers ?? false); _isMixinApplicationWithMembers ?? false);
} }
} }

View file

@ -831,8 +831,8 @@ class KernelImpactConverter implements ImpactRegistry {
} }
ClassEntity? cls = type.element; ClassEntity? cls = type.element;
while (cls != null) { while (cls != null) {
MemberEntity member = MemberEntity member = elementMap.elementEnvironment
elementMap.elementEnvironment.lookupClassMember(cls, '==')!; .lookupClassMember(cls, Names.EQUALS_NAME)!;
if (member.isAbstract) { if (member.isAbstract) {
cls = elementMap.elementEnvironment.getSuperClass(cls); cls = elementMap.elementEnvironment.getSuperClass(cls);
} else { } else {

View file

@ -120,7 +120,7 @@ class KernelFrontendStrategy
(_, MemberEntity member) { (_, MemberEntity member) {
if (!member.isInstanceMember) return; if (!member.isInstanceMember) return;
MemberEntity interceptorMember = elementEnvironment MemberEntity interceptorMember = elementEnvironment
.lookupLocalClassMember(interceptorClass, member.name); .lookupLocalClassMember(interceptorClass, member.memberName);
// Interceptors must override all Object methods due to calling convention // Interceptors must override all Object methods due to calling convention
// differences. // differences.
assert( assert(

View file

@ -136,7 +136,7 @@ class KClosedWorld implements BuiltWorld, interfaces.KClosedWorld {
.checkHasMember(elementMap.getMemberNode(member))) { .checkHasMember(elementMap.getMemberNode(member))) {
throw SpannableAssertionFailure( throw SpannableAssertionFailure(
member, member,
"Member $member is in the environment of its enclosing class" "Member $member is not in the environment of its enclosing class"
" ${member.enclosingClass}."); " ${member.enclosingClass}.");
} }
} }

View file

@ -12,6 +12,7 @@ import '../constants/values.dart';
import '../deferred_load/output_unit.dart' show OutputUnit; import '../deferred_load/output_unit.dart' show OutputUnit;
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/indexed.dart'; import '../elements/indexed.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../inferrer/abstract_value_domain.dart'; import '../inferrer/abstract_value_domain.dart';
import '../ir/constants.dart'; import '../ir/constants.dart';

View file

@ -246,6 +246,26 @@ class DataSinkWriter {
} }
} }
/// Writes the [map] from [Name] to [V] values to this data sink, calling [f]
/// to write each value to the data sink. If [allowNull] is `true`, [map] is
/// allowed to be `null`.
///
/// This is a convenience method to be used together with
/// [DataSourceReader.readNameMap].
void writeNameMap<V>(Map<Name, V>? map, void f(V value),
{bool allowNull = false}) {
if (map == null) {
assert(allowNull);
writeInt(0);
} else {
writeInt(map.length);
map.forEach((Name key, V value) {
writeMemberName(key);
f(value);
});
}
}
/// Writes the string [values] to this data sink. If [allowNull] is `true`, /// Writes the string [values] to this data sink. If [allowNull] is `true`,
/// [values] is allowed to be `null`. /// [values] is allowed to be `null`.
/// ///
@ -386,6 +406,13 @@ class DataSinkWriter {
writeValueOrNull(value.library, writeLibraryNode); writeValueOrNull(value.library, writeLibraryNode);
} }
/// Writes a [Name] to this data sink.
void writeMemberName(Name value) {
writeString(value.text);
writeValueOrNull(value.uri, writeUri);
writeBool(value.isSetter);
}
/// Writes a kernel library dependency node [value] to this data sink. /// Writes a kernel library dependency node [value] to this data sink.
void writeLibraryDependencyNode(ir.LibraryDependency value) { void writeLibraryDependencyNode(ir.LibraryDependency value) {
final library = value.parent as ir.Library; final library = value.parent as ir.Library;

View file

@ -378,6 +378,24 @@ class DataSourceReader {
return list; return list;
} }
/// Reads a map from [Name] values to [V] values from this data source,
/// calling [f] to read each value from the data source. If [emptyAsNull] is
/// `true`, `null` is returned instead of an empty map.
///
/// This is a convenience method to be used together with
/// [DataSinkWriter.writeNameMap].
Map<Name, V>? readNameMap<V>(V f(), {bool emptyAsNull = false}) {
int count = readInt();
if (count == 0 && emptyAsNull) return null;
Map<Name, V> map = {};
for (int i = 0; i < count; i++) {
Name key = readMemberName();
V value = f();
map[key] = value;
}
return map;
}
/// Reads a map from string values to [V] values from this data source, /// Reads a map from string values to [V] values from this data source,
/// calling [f] to read each value from the data source. If [emptyAsNull] is /// calling [f] to read each value from the data source. If [emptyAsNull] is
/// `true`, `null` is returned instead of an empty map. /// `true`, `null` is returned instead of an empty map.
@ -537,6 +555,14 @@ class DataSourceReader {
return ir.Name(text, library); return ir.Name(text, library);
} }
/// Reads a [Name] from this data source.
Name readMemberName() {
String text = readString();
Uri? uri = readValueOrNull(readUri);
bool setter = readBool();
return Name(text, uri, isSetter: setter);
}
/// Reads a kernel library dependency node from this data source. /// Reads a kernel library dependency node from this data source.
ir.LibraryDependency readLibraryDependencyNode() { ir.LibraryDependency readLibraryDependencyNode() {
ir.Library library = readLibraryNode(); ir.Library library = readLibraryNode();

View file

@ -4285,7 +4285,7 @@ class KernelSsaGraphBuilder extends ir.Visitor<void> with ir.VisitorVoidMixin {
Map<String, ir.Expression> namedArguments = {}; Map<String, ir.Expression> namedArguments = {};
int kind = _readIntLiteral(invocation.arguments.positional[4]); int kind = _readIntLiteral(invocation.arguments.positional[4]);
Name memberName = Name(name, _currentFrame.member.library); Name memberName = Name(name, _currentFrame.member.library.canonicalUri);
Selector selector; Selector selector;
switch (kind) { switch (kind) {
case invocationMirrorGetterKind: case invocationMirrorGetterKind:

View file

@ -51,7 +51,8 @@ class InvokeDynamicSpecializer {
Selector selector = instruction.selector; Selector selector = instruction.selector;
if (selector.name == name) return; if (selector.name == name) return;
instruction.selector = Selector.call( instruction.selector = Selector.call(
Name(name, commonElements.interceptorsLibrary), selector.callStructure); Name(name, commonElements.interceptorsLibrary.canonicalUri),
selector.callStructure);
} }
constant_system.Operation operation() => null; constant_system.Operation operation() => null;

View file

@ -12,6 +12,7 @@ import '../common/tasks.dart' show Measurer, CompilerTask;
import '../constants/constant_system.dart' as constant_system; import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart'; import '../constants/values.dart';
import '../elements/entities.dart'; import '../elements/entities.dart';
import '../elements/names.dart';
import '../elements/types.dart'; import '../elements/types.dart';
import '../inferrer/abstract_value_domain.dart'; import '../inferrer/abstract_value_domain.dart';
import '../inferrer/types.dart'; import '../inferrer/types.dart';
@ -1181,8 +1182,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
} }
FieldEntity _indexFieldOfEnumClass(ClassEntity enumClass) { FieldEntity _indexFieldOfEnumClass(ClassEntity enumClass) {
MemberEntity member = MemberEntity member = _closedWorld.elementEnvironment
_closedWorld.elementEnvironment.lookupClassMember(enumClass, 'index'); .lookupClassMember(enumClass, const PublicName('index'));
if (member is FieldEntity) return member; if (member is FieldEntity) return member;
throw StateError('$enumClass should have index field, found $member'); throw StateError('$enumClass should have index field, found $member');
} }

View file

@ -63,8 +63,6 @@ class Selector {
String get name => memberName.text; String get name => memberName.text;
LibraryEntity? get library => memberName.library;
static bool isOperatorName(String name) { static bool isOperatorName(String name) {
return instanceMethodOperatorNames.contains(name); return instanceMethodOperatorNames.contains(name);
} }
@ -198,22 +196,17 @@ class Selector {
factory Selector.readFromDataSource(DataSourceReader source) { factory Selector.readFromDataSource(DataSourceReader source) {
source.begin(tag); source.begin(tag);
SelectorKind kind = source.readEnum(SelectorKind.values); SelectorKind kind = source.readEnum(SelectorKind.values);
bool isSetter = source.readBool(); Name memberName = source.readMemberName();
LibraryEntity? library = source.readLibraryOrNull();
String text = source.readString();
CallStructure callStructure = CallStructure.readFromDataSource(source); CallStructure callStructure = CallStructure.readFromDataSource(source);
source.end(tag); source.end(tag);
return Selector( return Selector(kind, memberName, callStructure);
kind, Name(text, library, isSetter: isSetter), callStructure);
} }
/// Serializes this [Selector] to [sink]. /// Serializes this [Selector] to [sink].
void writeToDataSink(DataSinkWriter sink) { void writeToDataSink(DataSinkWriter sink) {
sink.begin(tag); sink.begin(tag);
sink.writeEnum(kind); sink.writeEnum(kind);
sink.writeBool(memberName.isSetter); sink.writeMemberName(memberName);
sink.writeLibraryOrNull(memberName.library);
sink.writeString(memberName.text);
callStructure.writeToDataSink(sink); callStructure.writeToDataSink(sink);
sink.end(tag); sink.end(tag);
} }
@ -244,9 +237,7 @@ class Selector {
bool appliesUnnamed(MemberEntity element) { bool appliesUnnamed(MemberEntity element) {
assert(name == element.name); assert(name == element.name);
if (memberName.isPrivate && memberName.library != element.library) { if (!memberName.matches(element.memberName)) {
// TODO(johnniwinther): Maybe this should be
// `memberName != element.memberName`.
return false; return false;
} }
if (element.isSetter) return isSetter; if (element.isSetter) return isSetter;

View file

@ -4,6 +4,8 @@
// @dart = 2.7 // @dart = 2.7
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart"; import "package:async_helper/async_helper.dart";
import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/commandline_options.dart';
@ -56,7 +58,7 @@ void main() {
var options = [Flags.omitImplicitChecks]; var options = [Flags.omitImplicitChecks];
var result = await runCompiler( var result = await runCompiler(
memorySourceFiles: {'main.dart': TEST}, options: options); memorySourceFiles: {'main.dart': TEST}, options: options);
var compiler = result.compiler; Compiler compiler = result.compiler;
var results = compiler.globalInference.resultsForTesting; var results = compiler.globalInference.resultsForTesting;
var closedWorld = results.closedWorld; var closedWorld = results.closedWorld;
var elementEnvironment = closedWorld.elementEnvironment; var elementEnvironment = closedWorld.elementEnvironment;
@ -65,13 +67,15 @@ void main() {
elementEnvironment.lookupClass(elementEnvironment.mainLibrary, "A"); elementEnvironment.lookupClass(elementEnvironment.mainLibrary, "A");
checkReturn(String name, TypeMask type) { checkReturn(String name, TypeMask type) {
MemberEntity element = elementEnvironment.lookupClassMember(classA, name); MemberEntity element =
elementEnvironment.lookupClassMember(classA, PublicName(name));
var mask = results.resultOfMember(element).returnType; var mask = results.resultOfMember(element).returnType;
Expect.isTrue(type.containsMask(mask, closedWorld)); Expect.isTrue(type.containsMask(mask, closedWorld));
} }
checkType(String name, type) { checkType(String name, type) {
MemberEntity element = elementEnvironment.lookupClassMember(classA, name); MemberEntity element =
elementEnvironment.lookupClassMember(classA, PublicName(name));
Expect.isTrue( Expect.isTrue(
type.containsMask(results.resultOfMember(element).type, closedWorld)); type.containsMask(results.resultOfMember(element).type, closedWorld));
} }

View file

@ -4,6 +4,8 @@
// @dart = 2.7 // @dart = 2.7
import 'package:compiler/src/elements/names.dart';
import '../helpers/memory_compiler.dart'; import '../helpers/memory_compiler.dart';
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
@ -60,7 +62,7 @@ main() {
Expect.isNotNull(library); Expect.isNotNull(library);
ClassEntity clss = environment.lookupClass(library, 'ListLiteralTest'); ClassEntity clss = environment.lookupClass(library, 'ListLiteralTest');
Expect.isNotNull(clss); Expect.isNotNull(clss);
var member = environment.lookupClassMember(clss, 'testMain'); var member = environment.lookupClassMember(clss, PublicName('testMain'));
Expect.isNotNull(member); Expect.isNotNull(member);
}); });
} }

View file

@ -4,6 +4,8 @@
// @dart = 2.7 // @dart = 2.7
import 'package:compiler/src/elements/names.dart';
import '../helpers/memory_compiler.dart'; import '../helpers/memory_compiler.dart';
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
@ -61,7 +63,7 @@ main() {
Expect.isNotNull(library); Expect.isNotNull(library);
ClassEntity clss = environment.lookupClass(library, 'B1'); ClassEntity clss = environment.lookupClass(library, 'B1');
Expect.isNotNull(clss); Expect.isNotNull(clss);
var member = environment.lookupClassMember(clss, 'foo'); var member = environment.lookupClassMember(clss, PublicName('foo'));
Expect.isNotNull(member); Expect.isNotNull(member);
}); });
} }

View file

@ -14,6 +14,7 @@ import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/kernel/element_map.dart'; import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart'; import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
@ -325,7 +326,8 @@ Future<CompiledData<T>> computeData<T>(String name, Uri entryPoint,
MemberEntity member; MemberEntity member;
if (id.className != null) { if (id.className != null) {
ClassEntity cls = getGlobalClass(id.className); ClassEntity cls = getGlobalClass(id.className);
member = elementEnvironment.lookupClassMember(cls, id.memberName); member = elementEnvironment.lookupClassMember(
cls, Name(id.memberName, cls.library.canonicalUri));
member ??= elementEnvironment.lookupConstructor(cls, id.memberName); member ??= elementEnvironment.lookupConstructor(cls, id.memberName);
Expect.isNotNull( Expect.isNotNull(
member, "Global member '$member' not found in class $cls."); member, "Global member '$member' not found in class $cls.");
@ -552,8 +554,8 @@ Spannable computeSpannable(
print("No class '${id.className}' in $mainUri."); print("No class '${id.className}' in $mainUri.");
return NO_LOCATION_SPANNABLE; return NO_LOCATION_SPANNABLE;
} }
MemberEntity member = elementEnvironment MemberEntity member = elementEnvironment.lookupClassMember(
.lookupClassMember(cls, memberName, setter: isSetter); cls, Name(memberName, cls.library.canonicalUri, isSetter: isSetter));
if (member == null) { if (member == null) {
ConstructorEntity constructor = ConstructorEntity constructor =
elementEnvironment.lookupConstructor(cls, memberName); elementEnvironment.lookupConstructor(cls, memberName);

View file

@ -9,6 +9,7 @@ import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/js/js.dart' as js; import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_model/js_strategy.dart'; import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/world.dart'; import 'package:compiler/src/world.dart';
@ -194,7 +195,8 @@ main(List<String> args) {
ClassEntity cls = elementEnvironment.lookupClass( ClassEntity cls = elementEnvironment.lookupClass(
elementEnvironment.mainLibrary, className); elementEnvironment.mainLibrary, className);
Expect.isNotNull(cls, "Class '$className' not found."); Expect.isNotNull(cls, "Class '$className' not found.");
method = elementEnvironment.lookupClassMember(cls, methodName); method = elementEnvironment.lookupClassMember(
cls, Name(methodName, cls.library.canonicalUri));
Expect.isNotNull(method, "Method '$methodName' not found in $cls."); Expect.isNotNull(method, "Method '$methodName' not found in $cls.");
} else { } else {
method = elementEnvironment.lookupLibraryMember( method = elementEnvironment.lookupLibraryMember(

View file

@ -6,6 +6,7 @@
import 'package:compiler/src/common/elements.dart' show JElementEnvironment; import 'package:compiler/src/common/elements.dart' show JElementEnvironment;
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/elements/types.dart'; import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/world.dart' show JClosedWorld; import 'package:compiler/src/world.dart' show JClosedWorld;
@ -45,8 +46,8 @@ MemberEntity findClassMember(
JElementEnvironment elementEnvironment = closedWorld.elementEnvironment; JElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
ClassEntity cls = findClass(closedWorld, className); ClassEntity cls = findClass(closedWorld, className);
assert(cls != null, "Class '$className' not found."); assert(cls != null, "Class '$className' not found.");
MemberEntity member = MemberEntity member = elementEnvironment.lookupClassMember(
elementEnvironment.lookupClassMember(cls, memberName, setter: isSetter); cls, Name(memberName, cls.library.canonicalUri, isSetter: isSetter));
if (member == null && !isSetter) { if (member == null && !isSetter) {
member = elementEnvironment.lookupConstructor(cls, memberName); member = elementEnvironment.lookupConstructor(cls, memberName);
} }

View file

@ -7,6 +7,7 @@
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/deferred_load/output_unit.dart' show OutputUnit; import 'package:compiler/src/deferred_load/output_unit.dart' show OutputUnit;
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/js/js.dart' as js; import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_backend/namer.dart'; import 'package:compiler/src/js_backend/namer.dart';
import 'package:compiler/src/js_emitter/model.dart'; import 'package:compiler/src/js_emitter/model.dart';
@ -29,7 +30,8 @@ MemberEntity lookupMember(JElementEnvironment elementEnvironment, String name) {
ClassEntity cls = elementEnvironment.lookupClass( ClassEntity cls = elementEnvironment.lookupClass(
elementEnvironment.mainLibrary, className); elementEnvironment.mainLibrary, className);
Expect.isNotNull(cls, "No class '$className' found in the main library."); Expect.isNotNull(cls, "No class '$className' found in the main library.");
member = elementEnvironment.lookupClassMember(cls, name); member = elementEnvironment.lookupClassMember(
cls, Name(name, cls.library.canonicalUri));
member ??= elementEnvironment.lookupConstructor(cls, name); member ??= elementEnvironment.lookupConstructor(cls, name);
Expect.isNotNull(member, "No member '$name' found in $cls"); Expect.isNotNull(member, "No member '$name' found in $cls");
} else { } else {

View file

@ -7,6 +7,7 @@
library type_test_helper; library type_test_helper;
import 'dart:async'; import 'dart:async';
import 'package:compiler/src/elements/names.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/commandline_options.dart';
@ -136,7 +137,8 @@ class TypeEnvironment {
MemberEntity _getMember(String name, [ClassEntity cls]) { MemberEntity _getMember(String name, [ClassEntity cls]) {
if (cls != null) { if (cls != null) {
return elementEnvironment.lookupLocalClassMember(cls, name); return elementEnvironment.lookupLocalClassMember(
cls, Name(name, cls.library.canonicalUri));
} else { } else {
LibraryEntity mainLibrary = elementEnvironment.mainLibrary; LibraryEntity mainLibrary = elementEnvironment.mainLibrary;
return elementEnvironment.lookupLibraryMember(mainLibrary, name); return elementEnvironment.lookupLibraryMember(mainLibrary, name);

View file

@ -7,6 +7,7 @@
library dart2js.constants.values.test; library dart2js.constants.values.test;
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart'; import 'package:compiler/src/elements/types.dart';
@ -30,8 +31,10 @@ void main() {
"""); """);
ClassEntity C = env.getClass('C'); ClassEntity C = env.getClass('C');
InterfaceType C_raw = env.elementEnvironment.getRawType(C); InterfaceType C_raw = env.elementEnvironment.getRawType(C);
FieldEntity field1 = env.elementEnvironment.lookupClassMember(C, 'field1'); FieldEntity field1 =
FieldEntity field2 = env.elementEnvironment.lookupClassMember(C, 'field2'); env.elementEnvironment.lookupClassMember(C, PublicName('field1'));
FieldEntity field2 =
env.elementEnvironment.lookupClassMember(C, PublicName('field2'));
ConstructedConstantValue value1 = new ConstructedConstantValue(C_raw, { ConstructedConstantValue value1 = new ConstructedConstantValue(C_raw, {
field1: new IntConstantValue(BigInt.zero), field1: new IntConstantValue(BigInt.zero),
field2: new IntConstantValue(BigInt.one), field2: new IntConstantValue(BigInt.one),

View file

@ -194,7 +194,7 @@ main() {}
ClassEntity cls = elementEnvironment.lookupClass( ClassEntity cls = elementEnvironment.lookupClass(
elementEnvironment.mainLibrary, className); elementEnvironment.mainLibrary, className);
Selector selector = new Selector.call( Selector selector = new Selector.call(
new Name(methodName, elementEnvironment.mainLibrary), new Name(methodName, elementEnvironment.mainLibrary.canonicalUri),
CallStructure.NO_ARGS); CallStructure.NO_ARGS);
WorldImpact impact = new WorldImpactBuilderImpl() WorldImpact impact = new WorldImpactBuilderImpl()
..registerDynamicUse( ..registerDynamicUse(

View file

@ -8,6 +8,7 @@ import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/world.dart'; import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import '../helpers/memory_compiler.dart'; import '../helpers/memory_compiler.dart';
@ -37,7 +38,8 @@ main() {
elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Class'); elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Class');
ClassEntity mixin = ClassEntity mixin =
elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Mixin'); elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Mixin');
FunctionEntity method = elementEnvironment.lookupClassMember(cls, 'method'); FunctionEntity method =
elementEnvironment.lookupClassMember(cls, PublicName('method'));
Expect.isNotNull(method); Expect.isNotNull(method);
Expect.equals(mixin, method.enclosingClass); Expect.equals(mixin, method.enclosingClass);
Expect.isFalse(method.isAbstract); Expect.isFalse(method.isAbstract);

View file

@ -6,6 +6,7 @@
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_backend/no_such_method_registry.dart'; import 'package:compiler/src/js_backend/no_such_method_registry.dart';
@ -261,7 +262,8 @@ checkTest(Compiler compiler, NoSuchMethodTest test) {
compiler.frontendStrategy.noSuchMethodRegistry; compiler.frontendStrategy.noSuchMethodRegistry;
var resolver = registry.internalResolverForTesting; var resolver = registry.internalResolverForTesting;
FunctionEntity ObjectNSM = frontendEnvironment.lookupClassMember( FunctionEntity ObjectNSM = frontendEnvironment.lookupClassMember(
compiler.frontendStrategy.commonElements.objectClass, 'noSuchMethod'); compiler.frontendStrategy.commonElements.objectClass,
Names.noSuchMethod_);
JClosedWorld backendClosedWorld = compiler.backendClosedWorldForTesting; JClosedWorld backendClosedWorld = compiler.backendClosedWorldForTesting;
ElementEnvironment backendEnvironment = backendClosedWorld.elementEnvironment; ElementEnvironment backendEnvironment = backendClosedWorld.elementEnvironment;
NoSuchMethodData data = backendClosedWorld.noSuchMethodData; NoSuchMethodData data = backendClosedWorld.noSuchMethodData;
@ -272,7 +274,7 @@ checkTest(Compiler compiler, NoSuchMethodTest test) {
frontendEnvironment.mainLibrary, info.className); frontendEnvironment.mainLibrary, info.className);
Expect.isNotNull(cls, "Class ${info.className} not found."); Expect.isNotNull(cls, "Class ${info.className} not found.");
FunctionEntity noSuchMethod = FunctionEntity noSuchMethod =
frontendEnvironment.lookupClassMember(cls, 'noSuchMethod'); frontendEnvironment.lookupClassMember(cls, Names.noSuchMethod_);
Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls."); Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls.");
if (info.superClassName == null) { if (info.superClassName == null) {
@ -282,8 +284,8 @@ checkTest(Compiler compiler, NoSuchMethodTest test) {
frontendEnvironment.mainLibrary, info.superClassName); frontendEnvironment.mainLibrary, info.superClassName);
Expect.isNotNull( Expect.isNotNull(
superclass, "Superclass ${info.superClassName} not found."); superclass, "Superclass ${info.superClassName} not found.");
FunctionEntity superNoSuchMethod = FunctionEntity superNoSuchMethod = frontendEnvironment.lookupClassMember(
frontendEnvironment.lookupClassMember(superclass, 'noSuchMethod'); superclass, Names.noSuchMethod_);
Expect.isNotNull( Expect.isNotNull(
superNoSuchMethod, "noSuchMethod not found in $superclass."); superNoSuchMethod, "noSuchMethod not found in $superclass.");
Expect.equals( Expect.equals(
@ -309,8 +311,8 @@ checkTest(Compiler compiler, NoSuchMethodTest test) {
ClassEntity frontendClass = frontendEnvironment.lookupClass( ClassEntity frontendClass = frontendEnvironment.lookupClass(
frontendEnvironment.mainLibrary, info.className); frontendEnvironment.mainLibrary, info.className);
Expect.isNotNull(frontendClass, "Class ${info.className} not found."); Expect.isNotNull(frontendClass, "Class ${info.className} not found.");
FunctionEntity frontendNoSuchMethod = FunctionEntity frontendNoSuchMethod = frontendEnvironment.lookupClassMember(
frontendEnvironment.lookupClassMember(frontendClass, 'noSuchMethod'); frontendClass, Names.noSuchMethod_);
Expect.isNotNull( Expect.isNotNull(
frontendNoSuchMethod, "noSuchMethod not found in $frontendClass."); frontendNoSuchMethod, "noSuchMethod not found in $frontendClass.");
@ -331,7 +333,7 @@ checkTest(Compiler compiler, NoSuchMethodTest test) {
backendEnvironment.mainLibrary, info.className); backendEnvironment.mainLibrary, info.className);
Expect.isNotNull(backendClass, "Class ${info.className} not found."); Expect.isNotNull(backendClass, "Class ${info.className} not found.");
FunctionEntity backendNoSuchMethod = FunctionEntity backendNoSuchMethod =
backendEnvironment.lookupClassMember(backendClass, 'noSuchMethod'); backendEnvironment.lookupClassMember(backendClass, Names.noSuchMethod_);
Expect.isNotNull( Expect.isNotNull(
backendNoSuchMethod, "noSuchMethod not found in $backendClass."); backendNoSuchMethod, "noSuchMethod not found in $backendClass.");

View file

@ -6,6 +6,7 @@
library type_substitution_test; library type_substitution_test;
import 'package:compiler/src/elements/names.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/commandline_options.dart';
@ -17,7 +18,8 @@ import '../helpers/type_test_helper.dart';
DartType getType(ElementEnvironment elementEnvironment, String name) { DartType getType(ElementEnvironment elementEnvironment, String name) {
ClassEntity cls = ClassEntity cls =
elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Class'); elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Class');
FunctionEntity element = elementEnvironment.lookupClassMember(cls, name); FunctionEntity element = elementEnvironment.lookupClassMember(
cls, Name(name, cls.library.canonicalUri));
Expect.isNotNull(element); Expect.isNotNull(element);
FunctionType type = elementEnvironment.getFunctionType(element); FunctionType type = elementEnvironment.getFunctionType(element);

View file

@ -12,6 +12,7 @@ import 'package:compiler/src/common.dart';
import 'package:compiler/src/common/elements.dart'; import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/compiler.dart'; import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart'; import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/elements/types.dart'; import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/js_backend/runtime_types_resolution.dart'; import 'package:compiler/src/js_backend/runtime_types_resolution.dart';
import 'package:compiler/src/js_model/js_world.dart'; import 'package:compiler/src/js_model/js_world.dart';
@ -288,8 +289,9 @@ abstract class IrMixin implements ComputeValueMixin {
frontendClass, backendMember.name); frontendClass, backendMember.name);
} else { } else {
return elementEnvironment.lookupClassMember( return elementEnvironment.lookupClassMember(
frontendClass, backendMember.name, frontendClass,
setter: backendMember.isSetter); Name(backendMember.name, frontendClass.library.canonicalUri,
isSetter: backendMember.isSetter));
} }
} }
return elementEnvironment.lookupLibraryMember( return elementEnvironment.lookupLibraryMember(

View file

@ -7,6 +7,7 @@
library source_map_name_test; library source_map_name_test;
import 'package:async_helper/async_helper.dart'; import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:expect/expect.dart'; import 'package:expect/expect.dart';
import 'package:compiler/src/commandline_options.dart'; import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/elements.dart' show JElementEnvironment; import 'package:compiler/src/common/elements.dart' show JElementEnvironment;
@ -101,7 +102,8 @@ main() {
ClassEntity cls = env.lookupClass(mainApp, clsName); ClassEntity cls = env.lookupClass(mainApp, clsName);
Expect.isNotNull(cls, "Class '$clsName' not found."); Expect.isNotNull(cls, "Class '$clsName' not found.");
var subname = name.substring(dotPosition + 1); var subname = name.substring(dotPosition + 1);
element = env.lookupLocalClassMember(cls, subname) ?? element = env.lookupLocalClassMember(
cls, Name(subname, cls.library.canonicalUri)) ??
env.lookupConstructor(cls, subname); env.lookupConstructor(cls, subname);
} else { } else {
element = env.lookupLibraryMember(mainApp, name); element = env.lookupLibraryMember(mainApp, name);

View file

@ -39,7 +39,7 @@ if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart
"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%DART2JS%" %EXTRA_OPTIONS% %* "%DART%" "--packages=%DART_ROOT%\.dart_tool\package_config.json" %EXTRA_VM_OPTIONS% "%DART2JS%" %EXTRA_OPTIONS% %*
endlocal endlocal

View file

@ -0,0 +1,75 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// 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 'private_names_lib2.dart';
export 'private_names_lib2.dart' show DoubleLinkedQueueEntry;
abstract class _DoubleLinkedQueueEntry<E> {
_DoubleLinkedQueueEntry<E>? _previousLink;
_DoubleLinkedQueueEntry<E>? _nextLink;
void _link(
_DoubleLinkedQueueEntry<E>? previous, _DoubleLinkedQueueEntry<E>? next) {
_nextLink = next;
_previousLink = previous;
previous?._nextLink = this;
next?._previousLink = this;
}
_DoubleLinkedQueueElement<E>? _asNonSentinelEntry();
void _prepend(E element, DoubleLinkedQueue<E>? queue) {
_DoubleLinkedQueueElement<E>(element, queue)._link(_previousLink, this);
}
}
class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E>
implements DoubleLinkedQueueEntry<E> {
DoubleLinkedQueue<E>? _queue;
E element;
_DoubleLinkedQueueElement(this.element, this._queue);
void prepend(E e) {
_prepend(e, _queue);
_queue?._elementCount++;
}
_DoubleLinkedQueueElement<E> _asNonSentinelEntry() => this;
}
class _DoubleLinkedQueueSentinel<E> extends _DoubleLinkedQueueEntry<E> {
_DoubleLinkedQueueSentinel() {
_previousLink = this;
_nextLink = this;
}
Null _asNonSentinelEntry() => null;
}
class DoubleLinkedQueue<E> /*extends Iterable<E> implements Queue<E>*/ {
final _DoubleLinkedQueueSentinel<E> _sentinel =
_DoubleLinkedQueueSentinel<E>();
int _elementCount = 0;
DoubleLinkedQueue();
factory DoubleLinkedQueue.from(Iterable<dynamic> elements) {
DoubleLinkedQueue<E> list = DoubleLinkedQueue<E>();
for (final e in elements) {
list.addLast(e as E);
}
return list;
}
void addLast(E value) {
_sentinel._prepend(value, this);
_elementCount++;
}
DoubleLinkedQueueEntry<E>? firstEntry() =>
_sentinel._nextLink!._asNonSentinelEntry();
}

View file

@ -0,0 +1,24 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// 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.
class DoubleLinkedQueueEntry<E> {
DoubleLinkedQueueEntry<E>? _previousLink;
DoubleLinkedQueueEntry<E>? _nextLink;
E element;
DoubleLinkedQueueEntry(this.element);
void _link(
DoubleLinkedQueueEntry<E>? previous, DoubleLinkedQueueEntry<E>? next) {
_nextLink = next;
_previousLink = previous;
previous?._nextLink = this;
next?._previousLink = this;
}
void prepend(E e) {
DoubleLinkedQueueEntry<E>(e)._link(_previousLink, this);
}
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// 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.
// Derived from lib/collection/queue_test which showed in error in the
// of private names in dart2js.
library queue.test;
import 'private_names_lib1.dart';
class DoubleLinkedQueueTest {
void testMain() {
testQueueElements();
}
void testQueueElements() {
DoubleLinkedQueue<int> queue1 = new DoubleLinkedQueue<int>.from([1, 2, 3]);
var firstEntry = queue1.firstEntry()!;
firstEntry.prepend(4);
}
}
void linkEntryTest() {
var entry = new DoubleLinkedQueueEntry(42);
}
main() {
new DoubleLinkedQueueTest().testMain();
linkEntryTest();
}

View file

@ -0,0 +1,75 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// 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 'private_names_lib2.dart';
export 'private_names_lib2.dart' show DoubleLinkedQueueEntry;
abstract class _DoubleLinkedQueueEntry<E> {
_DoubleLinkedQueueEntry<E>? _previousLink;
_DoubleLinkedQueueEntry<E>? _nextLink;
void _link(
_DoubleLinkedQueueEntry<E>? previous, _DoubleLinkedQueueEntry<E>? next) {
_nextLink = next;
_previousLink = previous;
previous?._nextLink = this;
next?._previousLink = this;
}
_DoubleLinkedQueueElement<E>? _asNonSentinelEntry();
void _prepend(E element, DoubleLinkedQueue<E>? queue) {
_DoubleLinkedQueueElement<E>(element, queue)._link(_previousLink, this);
}
}
class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E>
implements DoubleLinkedQueueEntry<E> {
DoubleLinkedQueue<E>? _queue;
E element;
_DoubleLinkedQueueElement(this.element, this._queue);
void prepend(E e) {
_prepend(e, _queue);
_queue?._elementCount++;
}
_DoubleLinkedQueueElement<E> _asNonSentinelEntry() => this;
}
class _DoubleLinkedQueueSentinel<E> extends _DoubleLinkedQueueEntry<E> {
_DoubleLinkedQueueSentinel() {
_previousLink = this;
_nextLink = this;
}
Null _asNonSentinelEntry() => null;
}
class DoubleLinkedQueue<E> /*extends Iterable<E> implements Queue<E>*/ {
final _DoubleLinkedQueueSentinel<E> _sentinel =
_DoubleLinkedQueueSentinel<E>();
int _elementCount = 0;
DoubleLinkedQueue();
factory DoubleLinkedQueue.from(Iterable<dynamic> elements) {
DoubleLinkedQueue<E> list = DoubleLinkedQueue<E>();
for (final e in elements) {
list.addLast(e as E);
}
return list;
}
void addLast(E value) {
_sentinel._prepend(value, this);
_elementCount++;
}
DoubleLinkedQueueEntry<E>? firstEntry() =>
_sentinel._nextLink!._asNonSentinelEntry();
}

View file

@ -0,0 +1,24 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// 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.
class DoubleLinkedQueueEntry<E> {
DoubleLinkedQueueEntry<E>? _previousLink;
DoubleLinkedQueueEntry<E>? _nextLink;
E element;
DoubleLinkedQueueEntry(this.element);
void _link(
DoubleLinkedQueueEntry<E>? previous, DoubleLinkedQueueEntry<E>? next) {
_nextLink = next;
_previousLink = previous;
previous?._nextLink = this;
next?._previousLink = this;
}
void prepend(E e) {
DoubleLinkedQueueEntry<E>(e)._link(_previousLink, this);
}
}

View file

@ -0,0 +1,33 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// 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.
// Derived from lib_2/collection/queue_test which showed in error in the
// of private names in dart2js.
// @dart = 2.9
library queue.test;
import 'private_names_lib1.dart';
class DoubleLinkedQueueTest {
void testMain() {
testQueueElements();
}
void testQueueElements() {
DoubleLinkedQueue<int> queue1 = new DoubleLinkedQueue<int>.from([1, 2, 3]);
var firstEntry = queue1.firstEntry();
firstEntry.prepend(4);
}
}
void linkEntryTest() {
var entry = new DoubleLinkedQueueEntry(42);
}
main() {
new DoubleLinkedQueueTest().testMain();
linkEntryTest();
}