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

Unified Diff: pkg/compiler/lib/src/universe/universe.dart

Issue 1062913003: Extract CallStructure from Selector. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix expentancy in unittest Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart ('k') | pkg/compiler/lib/src/use_unused_api.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/universe/universe.dart
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index 3deffcba75cd27966bafcbcc8b0126afc809a713..590bb543a0a1ac000c3c177768eaf2fd8113b257 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -228,230 +228,78 @@ class SelectorKind {
String toString() => name;
}
-class Selector {
- final SelectorKind kind;
- final String name;
- final LibraryElement library; // Library is null for non-private selectors.
-
- // The numbers of arguments of the selector. Includes named arguments.
+/// The structure of the arguments at a call-site.
+// TODO(johnniwinther): Should these be cached?
+// TODO(johnniwinther): Should isGetter/isSetter be part of the call structure
+// instead of the selector?
+class CallStructure {
+ static const CallStructure NO_ARGS = const CallStructure.unnamed(0);
+ static const CallStructure ONE_ARG = const CallStructure.unnamed(1);
+ static const CallStructure TWO_ARGS = const CallStructure.unnamed(2);
+
+ /// The numbers of arguments of the call. Includes named arguments.
final int argumentCount;
- final List<String> namedArguments;
- final List<String> _orderedNamedArguments;
- final int hashCode;
- static const String INDEX_NAME ="[]";
- static const String INDEX_SET_NAME = "[]=";
- static const String CALL_NAME = Compiler.CALL_OPERATOR_NAME;
+ /// The number of named arguments of the call.
+ int get namedArgumentCount => 0;
- Selector.internal(this.kind,
- this.name,
- this.library,
- this.argumentCount,
- this.namedArguments,
- this._orderedNamedArguments,
- this.hashCode) {
- assert(kind == SelectorKind.INDEX
- || (name != INDEX_NAME && name != INDEX_SET_NAME));
- assert(kind == SelectorKind.OPERATOR
- || kind == SelectorKind.INDEX
- || !Elements.isOperatorName(name));
- assert(kind == SelectorKind.CALL
- || kind == SelectorKind.GETTER
- || kind == SelectorKind.SETTER
- || Elements.isOperatorName(name));
- assert(!isPrivateName(name) || library != null);
- }
+ /// The number of positional argument of the call.
+ int get positionalArgumentCount => argumentCount;
- static Map<int, List<Selector>> canonicalizedValues =
- new Map<int, List<Selector>>();
-
- factory Selector(SelectorKind kind,
- String name,
- LibraryElement library,
- int argumentCount,
- [List<String> namedArguments]) {
- if (!isPrivateName(name)) library = null;
- if (namedArguments == null) namedArguments = const <String>[];
- int hashCode = computeHashCode(
- kind, name, library, argumentCount, namedArguments);
- List<Selector> list = canonicalizedValues.putIfAbsent(hashCode,
- () => <Selector>[]);
- for (int i = 0; i < list.length; i++) {
- Selector existing = list[i];
- if (existing.match(kind, name, library, argumentCount, namedArguments)) {
- assert(existing.hashCode == hashCode);
- assert(existing.mask == null);
- return existing;
- }
- }
- List<String> orderedNamedArguments = namedArguments.isEmpty
- ? const <String>[]
- : <String>[];
- Selector result = new Selector.internal(
- kind, name, library, argumentCount,
- namedArguments, orderedNamedArguments,
- hashCode);
- list.add(result);
- return result;
- }
+ const CallStructure.unnamed(this.argumentCount);
- factory Selector.fromElement(Element element) {
- String name = element.name;
- if (element.isFunction) {
- if (name == '[]') {
- return new Selector.index();
- } else if (name == '[]=') {
- return new Selector.indexSet();
- }
- FunctionSignature signature =
- element.asFunctionElement().functionSignature;
- int arity = signature.parameterCount;
- List<String> namedArguments = null;
- if (signature.optionalParametersAreNamed) {
- namedArguments =
- signature.orderedOptionalParameters.map((e) => e.name).toList();
- }
- if (element.isOperator) {
- // Operators cannot have named arguments, however, that doesn't prevent
- // a user from declaring such an operator.
- return new Selector(
- SelectorKind.OPERATOR, name, null, arity, namedArguments);
- } else {
- return new Selector.call(
- name, element.library, arity, namedArguments);
- }
- } else if (element.isSetter) {
- return new Selector.setter(name, element.library);
- } else if (element.isGetter) {
- return new Selector.getter(name, element.library);
- } else if (element.isField) {
- return new Selector.getter(name, element.library);
- } else if (element.isConstructor) {
- return new Selector.callConstructor(name, element.library);
- } else {
- throw new SpannableAssertionFailure(
- element, "Can't get selector from $element");
+ factory CallStructure(int argumentCount, [List<String> namedArguments]) {
+ if (namedArguments == null || namedArguments.isEmpty) {
+ return new CallStructure.unnamed(argumentCount);
}
+ return new NamedCallStructure(argumentCount, namedArguments);
}
- factory Selector.getter(String name, LibraryElement library)
- => new Selector(SelectorKind.GETTER, name, library, 0);
-
- factory Selector.getterFrom(Selector selector)
- => new Selector(SelectorKind.GETTER, selector.name, selector.library, 0);
-
- factory Selector.setter(String name, LibraryElement library)
- => new Selector(SelectorKind.SETTER, name, library, 1);
+ /// `true` if this call has named arguments.
+ bool get isNamed => false;
- factory Selector.unaryOperator(String name)
- => new Selector(SelectorKind.OPERATOR,
- Elements.constructOperatorName(name, true),
- null, 0);
+ /// `true` if this call has no named arguments.
+ bool get isUnnamed => true;
- factory Selector.binaryOperator(String name)
- => new Selector(SelectorKind.OPERATOR,
- Elements.constructOperatorName(name, false),
- null, 1);
+ /// The names of the named arguments in call-site order.
+ List<String> get namedArguments => const <String>[];
- factory Selector.index()
- => new Selector(SelectorKind.INDEX,
- Elements.constructOperatorName(INDEX_NAME, false),
- null, 1);
+ /// The names of the named arguments in canonicalized order.
+ List<String> getOrderedNamedArguments() => const <String>[];
- factory Selector.indexSet()
- => new Selector(SelectorKind.INDEX,
- Elements.constructOperatorName(INDEX_SET_NAME, false),
- null, 2);
+ /// A description of the argument structure.
+ String structureToString() => 'arity=$argumentCount';
- factory Selector.call(String name,
- LibraryElement library,
- int arity,
- [List<String> namedArguments])
- => new Selector(SelectorKind.CALL, name, library, arity, namedArguments);
-
- factory Selector.callClosure(int arity, [List<String> namedArguments])
- => new Selector(SelectorKind.CALL, CALL_NAME, null,
- arity, namedArguments);
+ String toString() => 'CallStructure(${structureToString()})';
- factory Selector.callClosureFrom(Selector selector)
- => new Selector(SelectorKind.CALL, CALL_NAME, null,
- selector.argumentCount, selector.namedArguments);
-
- factory Selector.callConstructor(String name, LibraryElement library,
- [int arity = 0,
- List<String> namedArguments])
- => new Selector(SelectorKind.CALL, name, library,
- arity, namedArguments);
-
- factory Selector.callDefaultConstructor()
- => new Selector(SelectorKind.CALL, "", null, 0);
-
- bool get isGetter => identical(kind, SelectorKind.GETTER);
- bool get isSetter => identical(kind, SelectorKind.SETTER);
- bool get isCall => identical(kind, SelectorKind.CALL);
- bool get isClosureCall {
- String callName = Compiler.CALL_OPERATOR_NAME;
- return isCall && name == callName;
+ Selector get callSelector {
+ return new Selector(SelectorKind.CALL, Selector.CALL_NAME, this);
}
- bool get isIndex => identical(kind, SelectorKind.INDEX) && argumentCount == 1;
- bool get isIndexSet => identical(kind, SelectorKind.INDEX) && argumentCount == 2;
-
- bool get isOperator => identical(kind, SelectorKind.OPERATOR);
- bool get isUnaryOperator => isOperator && argumentCount == 0;
-
- /** Check whether this is a call to 'assert'. */
- bool get isAssert => isCall && identical(name, "assert");
-
- int get namedArgumentCount => namedArguments.length;
- int get positionalArgumentCount => argumentCount - namedArgumentCount;
-
- bool get hasExactMask => false;
- TypeMask get mask => null;
- Selector get asUntyped => this;
-
- /**
- * The member name for invocation mirrors created from this selector.
- */
- String get invocationMirrorMemberName =>
- isSetter ? '$name=' : name;
-
- int get invocationMirrorKind {
- const int METHOD = 0;
- const int GETTER = 1;
- const int SETTER = 2;
- int kind = METHOD;
- if (isGetter) {
- kind = GETTER;
- } else if (isSetter) {
- kind = SETTER;
- }
- return kind;
+ bool match(CallStructure other) {
+ if (identical(this, other)) return true;
+ return this.argumentCount == other.argumentCount
+ && this.namedArgumentCount == other.namedArgumentCount
+ && sameNames(this.namedArguments, other.namedArguments);
}
- bool appliesUnnamed(Element element, World world) {
- assert(sameNameHack(element, world));
- return appliesUntyped(element, world);
+ // TODO(johnniwinther): Cache hash code?
+ int get hashCode {
+ int named = namedArguments.length;
+ int hash = mixHashCodeBits(argumentCount, named);
+ for (int i = 0; i < named; i++) {
+ hash = mixHashCodeBits(hash, namedArguments[i].hashCode);
+ }
+ return hash;
}
- bool appliesUntyped(Element element, World world) {
- assert(sameNameHack(element, world));
- if (Elements.isUnresolved(element)) return false;
- if (isPrivateName(name) && library != element.library) return false;
- if (world.isForeign(element)) return true;
- if (element.isSetter) return isSetter;
- if (element.isGetter) return isGetter || isCall;
- if (element.isField) {
- return isSetter
- ? !element.isFinal && !element.isConst
- : isGetter || isCall;
- }
- if (isGetter) return true;
- if (isSetter) return false;
- return signatureApplies(element);
+ bool operator ==(other) {
+ if (other is! CallStructure) return false;
+ return match(other);
}
bool signatureApplies(FunctionElement function) {
+ if (Elements.isUnresolved(function)) return false;
FunctionSignature parameters = function.functionSignature;
if (argumentCount > parameters.parameterCount) return false;
int requiredParameterCount = parameters.requiredParameterCount;
@@ -484,18 +332,6 @@ class Selector {
}
}
- bool sameNameHack(Element element, World world) {
- // TODO(ngeoffray): Remove workaround checks.
- return element.isConstructor ||
- name == element.name ||
- name == 'assert' && world.isAssertMethod(element);
- }
-
- bool applies(Element element, World world) {
- if (!sameNameHack(element, world)) return false;
- return appliesUnnamed(element, world);
- }
-
/**
* Returns a `List` with the evaluated arguments in the normalized order.
*
@@ -564,21 +400,20 @@ class Selector {
* Returns [:true:] if the signature of the [caller] matches the
* signature of the [callee], [:false:] otherwise.
*/
- static bool addForwardingElementArgumentsToList(
- FunctionElement caller,
- List list,
- FunctionElement callee,
- compileArgument(Element element),
- compileConstant(Element element),
- World world) {
+ static /*<T>*/ bool addForwardingElementArgumentsToList(
+ ConstructorElement caller,
+ List/*<T>*/ list,
+ ConstructorElement callee,
+ /*T*/ compileArgument(ParameterElement element),
+ /*T*/ compileConstant(ParameterElement element)) {
FunctionSignature signature = caller.functionSignature;
- Map mapping = new Map();
+ Map<Node, ParameterElement> mapping = <Node, ParameterElement>{};
// TODO(ngeoffray): This is a hack that fakes up AST nodes, so
// that we can call [addArgumentsToList].
- Link computeCallNodesFromParameters() {
- LinkBuilder builder = new LinkBuilder();
+ Link<Node> computeCallNodesFromParameters() {
+ LinkBuilder<Node> builder = new LinkBuilder<Node>();
signature.forEachRequiredParameter((ParameterElement element) {
Node node = element.node;
mapping[node] = element;
@@ -599,29 +434,28 @@ class Selector {
return builder.toLink();
}
- internalCompileArgument(Node node) {
+ /*T*/ internalCompileArgument(Node node) {
return compileArgument(mapping[node]);
}
Link<Node> nodes = computeCallNodesFromParameters();
- // Synthesize a selector for the call.
+ // Synthesize a structure for the call.
// TODO(ngeoffray): Should the resolver do it instead?
List<String> namedParameters;
if (signature.optionalParametersAreNamed) {
- namedParameters =
- signature.optionalParameters.mapToList((e) => e.name);
+ namedParameters = signature.optionalParameters.mapToList((e) => e.name);
}
- Selector selector = new Selector.call(callee.name,
- caller.library,
- signature.parameterCount,
- namedParameters);
-
- if (!selector.applies(callee, world)) return false;
- list.addAll(selector.makeArgumentsList(nodes,
- callee,
- internalCompileArgument,
- compileConstant));
+ CallStructure callStructure =
+ new CallStructure(signature.parameterCount, namedParameters);
+ if (!callStructure.signatureApplies(callee)) {
+ return false;
+ }
+ list.addAll(callStructure.makeArgumentsList(
+ nodes,
+ callee,
+ internalCompileArgument,
+ compileConstant));
return true;
}
@@ -632,59 +466,32 @@ class Selector {
}
return true;
}
+}
- bool match(SelectorKind kind,
- String name,
- LibraryElement library,
- int argumentCount,
- List<String> namedArguments) {
- return this.kind == kind
- && this.name == name
- && identical(this.library, library)
- && this.argumentCount == argumentCount
- && this.namedArguments.length == namedArguments.length
- && sameNames(this.namedArguments, namedArguments);
- }
+///
+class NamedCallStructure extends CallStructure {
+ final List<String> namedArguments;
+ final List<String> _orderedNamedArguments = <String>[];
- static int computeHashCode(SelectorKind kind,
- String name,
- LibraryElement library,
- int argumentCount,
- List<String> namedArguments) {
- // Add bits from name and kind.
- int hash = mixHashCodeBits(name.hashCode, kind.hashCode);
- // Add bits from the library.
- if (library != null) hash = mixHashCodeBits(hash, library.hashCode);
- // Add bits from the unnamed arguments.
- hash = mixHashCodeBits(hash, argumentCount);
- // Add bits from the named arguments.
- int named = namedArguments.length;
- hash = mixHashCodeBits(hash, named);
- for (int i = 0; i < named; i++) {
- hash = mixHashCodeBits(hash, namedArguments[i].hashCode);
- }
- return hash;
+ NamedCallStructure(int argumentCount, this.namedArguments)
+ : super.unnamed(argumentCount) {
+ assert(namedArguments.isNotEmpty);
}
- // TODO(kasperl): Move this out so it becomes useful in other places too?
- static int mixHashCodeBits(int existing, int value) {
- // Spread the bits of value. Try to stay in the 30-bit range to
- // avoid overflowing into a more expensive integer representation.
- int h = value & 0x1fffffff;
- h += ((h & 0x3fff) << 15) ^ 0x1fffcd7d;
- h ^= (h >> 10);
- h += ((h & 0x3ffffff) << 3);
- h ^= (h >> 6);
- h += ((h & 0x7ffffff) << 2) + ((h & 0x7fff) << 14);
- h ^= (h >> 16);
- // Combine the two hash values.
- int high = existing >> 15;
- int low = existing & 0x7fff;
- return ((high * 13) ^ (low * 997) ^ h) & SMI_MASK;
- }
+ @override
+ bool get isNamed => true;
+
+ @override
+ bool get isUnnamed => false;
+ @override
+ int get namedArgumentCount => namedArguments.length;
+
+ @override
+ int get positionalArgumentCount => argumentCount - namedArgumentCount;
+
+ @override
List<String> getOrderedNamedArguments() {
- if (namedArguments.isEmpty) return namedArguments;
if (!_orderedNamedArguments.isEmpty) return _orderedNamedArguments;
_orderedNamedArguments.addAll(namedArguments);
@@ -694,25 +501,273 @@ class Selector {
return _orderedNamedArguments;
}
- String namedArgumentsToString() {
- if (namedArgumentCount > 0) {
- StringBuffer result = new StringBuffer();
- for (int i = 0; i < namedArgumentCount; i++) {
- if (i != 0) result.write(', ');
- result.write(namedArguments[i]);
+ @override
+ String structureToString() {
+ return 'arity=$argumentCount, named=[${namedArguments.join(', ')}]';
+ }
+}
+
+class Selector {
+ final SelectorKind kind;
+ final Name memberName;
+ final CallStructure callStructure;
+
+ final int hashCode;
+
+ int get argumentCount => callStructure.argumentCount;
+ int get namedArgumentCount => callStructure.namedArgumentCount;
+ int get positionalArgumentCount => callStructure.positionalArgumentCount;
+ List<String> get namedArguments => callStructure.namedArguments;
+
+ String get name => memberName.text;
+
+ LibraryElement get library => memberName.library;
+
+ static const Name INDEX_NAME = const PublicName("[]");
+ static const Name INDEX_SET_NAME = const PublicName("[]=");
+ static const Name CALL_NAME = const PublicName(Compiler.CALL_OPERATOR_NAME);
+
+ Selector.internal(this.kind,
+ this.memberName,
+ this.callStructure,
+ this.hashCode) {
+ assert(kind == SelectorKind.INDEX ||
+ (memberName != INDEX_NAME && memberName != INDEX_SET_NAME));
+ assert(kind == SelectorKind.OPERATOR ||
+ kind == SelectorKind.INDEX ||
+ !Elements.isOperatorName(memberName.text));
+ assert(kind == SelectorKind.CALL ||
+ kind == SelectorKind.GETTER ||
+ kind == SelectorKind.SETTER ||
+ Elements.isOperatorName(memberName.text));
+ }
+
+ // TODO(johnniwinther): Extract caching.
+ static Map<int, List<Selector>> canonicalizedValues =
+ new Map<int, List<Selector>>();
+
+ factory Selector(SelectorKind kind,
+ Name name,
+ CallStructure callStructure) {
+ // TODO(johnniwinther): Maybe use equality instead of implicit hashing.
+ int hashCode = computeHashCode(kind, name, callStructure);
+ List<Selector> list = canonicalizedValues.putIfAbsent(hashCode,
+ () => <Selector>[]);
+ for (int i = 0; i < list.length; i++) {
+ Selector existing = list[i];
+ if (existing.match(kind, name, callStructure)) {
+ assert(existing.hashCode == hashCode);
+ assert(existing.mask == null);
+ return existing;
+ }
+ }
+ Selector result = new Selector.internal(
+ kind, name, callStructure, hashCode);
+ list.add(result);
+ return result;
+ }
+
+ factory Selector.fromElement(Element element) {
+ String name = element.name;
+ if (element.isFunction) {
+ if (name == '[]') {
+ return new Selector.index();
+ } else if (name == '[]=') {
+ return new Selector.indexSet();
+ }
+ FunctionSignature signature =
+ element.asFunctionElement().functionSignature;
+ int arity = signature.parameterCount;
+ List<String> namedArguments = null;
+ if (signature.optionalParametersAreNamed) {
+ namedArguments =
+ signature.orderedOptionalParameters.map((e) => e.name).toList();
}
- return "[$result]";
+ if (element.isOperator) {
+ // Operators cannot have named arguments, however, that doesn't prevent
+ // a user from declaring such an operator.
+ return new Selector(
+ SelectorKind.OPERATOR,
+ new PublicName(name),
+ new CallStructure(arity, namedArguments));
+ } else {
+ return new Selector.call(
+ name, element.library, arity, namedArguments);
+ }
+ } else if (element.isSetter) {
+ return new Selector.setter(name, element.library);
+ } else if (element.isGetter) {
+ return new Selector.getter(name, element.library);
+ } else if (element.isField) {
+ return new Selector.getter(name, element.library);
+ } else if (element.isConstructor) {
+ return new Selector.callConstructor(name, element.library);
+ } else {
+ throw new SpannableAssertionFailure(
+ element, "Can't get selector from $element");
+ }
+ }
+
+ factory Selector.getter(String name, LibraryElement library)
+ => new Selector(SelectorKind.GETTER,
+ new Name(name, library),
+ CallStructure.NO_ARGS);
+
+ factory Selector.getterFrom(Selector selector)
+ => new Selector(SelectorKind.GETTER,
+ selector.memberName,
+ CallStructure.NO_ARGS);
+
+ factory Selector.setter(String name, LibraryElement library)
+ => new Selector(SelectorKind.SETTER,
+ new Name(name, library, isSetter: true),
+ CallStructure.ONE_ARG);
+
+ factory Selector.unaryOperator(String name) => new Selector(
+ SelectorKind.OPERATOR,
+ new PublicName(Elements.constructOperatorName(name, true)),
+ CallStructure.NO_ARGS);
+
+ factory Selector.binaryOperator(String name) => new Selector(
+ SelectorKind.OPERATOR,
+ new PublicName(Elements.constructOperatorName(name, false)),
+ CallStructure.ONE_ARG);
+
+ factory Selector.index()
+ => new Selector(SelectorKind.INDEX, INDEX_NAME,
+ CallStructure.ONE_ARG);
+
+ factory Selector.indexSet()
+ => new Selector(SelectorKind.INDEX, INDEX_SET_NAME,
+ CallStructure.TWO_ARGS);
+
+ factory Selector.call(String name,
+ LibraryElement library,
+ int arity,
+ [List<String> namedArguments])
+ => new Selector(SelectorKind.CALL,
+ new Name(name, library),
+ new CallStructure(arity, namedArguments));
+
+ factory Selector.callClosure(int arity, [List<String> namedArguments])
+ => new Selector(SelectorKind.CALL, CALL_NAME,
+ new CallStructure(arity, namedArguments));
+
+ factory Selector.callClosureFrom(Selector selector)
+ => new Selector(SelectorKind.CALL, CALL_NAME, selector.callStructure);
+
+ factory Selector.callConstructor(String name, LibraryElement library,
+ [int arity = 0,
+ List<String> namedArguments])
+ => new Selector(SelectorKind.CALL, new Name(name, library),
+ new CallStructure(arity, namedArguments));
+
+ factory Selector.callDefaultConstructor()
+ => new Selector(
+ SelectorKind.CALL,
+ const PublicName(''),
+ CallStructure.NO_ARGS);
+
+ bool get isGetter => kind == SelectorKind.GETTER;
+ bool get isSetter => kind == SelectorKind.SETTER;
+ bool get isCall => kind == SelectorKind.CALL;
+ bool get isClosureCall => isCall && memberName == CALL_NAME;
+
+ bool get isIndex => kind == SelectorKind.INDEX && argumentCount == 1;
+ bool get isIndexSet => kind == SelectorKind.INDEX && argumentCount == 2;
+
+ bool get isOperator => kind == SelectorKind.OPERATOR;
+ bool get isUnaryOperator => isOperator && argumentCount == 0;
+
+ /** Check whether this is a call to 'assert'. */
+ bool get isAssert => isCall && identical(name, "assert");
+
+ bool get hasExactMask => false;
+ TypeMask get mask => null;
+ Selector get asUntyped => this;
+
+ /**
+ * The member name for invocation mirrors created from this selector.
+ */
+ String get invocationMirrorMemberName =>
+ isSetter ? '$name=' : name;
+
+ int get invocationMirrorKind {
+ const int METHOD = 0;
+ const int GETTER = 1;
+ const int SETTER = 2;
+ int kind = METHOD;
+ if (isGetter) {
+ kind = GETTER;
+ } else if (isSetter) {
+ kind = SETTER;
+ }
+ return kind;
+ }
+
+ bool appliesUnnamed(Element element, World world) {
+ assert(sameNameHack(element, world));
+ return appliesUntyped(element, world);
+ }
+
+ bool appliesUntyped(Element element, World world) {
+ assert(sameNameHack(element, world));
+ if (Elements.isUnresolved(element)) return false;
+ if (memberName.isPrivate && memberName.library != element.library) {
+ // TODO(johnniwinther): Maybe this should be
+ // `memberName != element.memberName`.
+ return false;
}
- return '';
+ if (world.isForeign(element)) return true;
+ if (element.isSetter) return isSetter;
+ if (element.isGetter) return isGetter || isCall;
+ if (element.isField) {
+ return isSetter
+ ? !element.isFinal && !element.isConst
+ : isGetter || isCall;
+ }
+ if (isGetter) return true;
+ if (isSetter) return false;
+ return signatureApplies(element);
+ }
+
+ bool signatureApplies(FunctionElement function) {
+ return callStructure.signatureApplies(function);
+ }
+
+ bool sameNameHack(Element element, World world) {
+ // TODO(ngeoffray): Remove workaround checks.
+ return element.isConstructor ||
+ name == element.name ||
+ name == 'assert' && world.isAssertMethod(element);
+ }
+
+ bool applies(Element element, World world) {
+ if (!sameNameHack(element, world)) return false;
+ return appliesUnnamed(element, world);
+ }
+
+ bool match(SelectorKind kind,
+ Name memberName,
+ CallStructure callStructure) {
+ return this.kind == kind
+ && this.memberName == memberName
+ && this.callStructure.match(callStructure);
+ }
+
+ static int computeHashCode(SelectorKind kind,
+ Name name,
+ CallStructure callStructure) {
+ // Add bits from name and kind.
+ int hash = mixHashCodeBits(name.hashCode, kind.hashCode);
+ // Add bits from the call structure.
+ return mixHashCodeBits(hash, callStructure.hashCode);
}
String toString() {
- String named = '';
String type = '';
- if (namedArgumentCount > 0) named = ', named=${namedArgumentsToString()}';
if (mask != null) type = ', mask=$mask';
- return 'Selector($kind, $name, '
- 'arity=$argumentCount$named$type)';
+ return 'Selector($kind, $name, ${callStructure.structureToString()}$type)';
}
Selector extendIfReachesAll(Compiler compiler) {
@@ -730,11 +785,8 @@ class TypedSelector extends Selector {
TypedSelector.internal(this.mask, Selector selector, int hashCode)
: asUntyped = selector,
super.internal(selector.kind,
- selector.name,
- selector.library,
- selector.argumentCount,
- selector.namedArguments,
- selector._orderedNamedArguments,
+ selector.memberName,
+ selector.callStructure,
hashCode) {
assert(mask != null);
assert(asUntyped.mask == null);
@@ -758,7 +810,7 @@ class TypedSelector extends Selector {
.putIfAbsent(untyped, () => new Map<TypeMask, TypedSelector>());
TypedSelector result = map[mask];
if (result == null) {
- int hashCode = Selector.mixHashCodeBits(untyped.hashCode, mask.hashCode);
+ int hashCode = mixHashCodeBits(untyped.hashCode, mask.hashCode);
result = map[mask] = new TypedSelector.internal(mask, untyped, hashCode);
}
return result;
« no previous file with comments | « pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart ('k') | pkg/compiler/lib/src/use_unused_api.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698