mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 14:43:13 +00:00
[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:
parent
94d797ebee
commit
50ac2500a1
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()}';
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}.");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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}.");
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.");
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
75
tests/web/regress/private_names_lib1.dart
Normal file
75
tests/web/regress/private_names_lib1.dart
Normal 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();
|
||||||
|
}
|
24
tests/web/regress/private_names_lib2.dart
Normal file
24
tests/web/regress/private_names_lib2.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
31
tests/web/regress/private_names_test.dart
Normal file
31
tests/web/regress/private_names_test.dart
Normal 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();
|
||||||
|
}
|
75
tests/web_2/regress/private_names_lib1.dart
Normal file
75
tests/web_2/regress/private_names_lib1.dart
Normal 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();
|
||||||
|
}
|
24
tests/web_2/regress/private_names_lib2.dart
Normal file
24
tests/web_2/regress/private_names_lib2.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
33
tests/web_2/regress/private_names_test.dart
Normal file
33
tests/web_2/regress/private_names_test.dart
Normal 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();
|
||||||
|
}
|
Loading…
Reference in a new issue