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

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

Issue 1346593002: Move Selector and CallStructure into parts. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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/universe/selector.dart ('k') | no next file » | 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 4530400e1cbaffc794effa09c6a3e22e636bd033..5268be3de5802c9ac6661b5efecaf035f545d677 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -25,7 +25,9 @@ import '../world.dart' show
ClassWorld,
World;
+part 'call_structure.dart';
part 'function_set.dart';
+part 'selector.dart';
part 'side_effects.dart';
class UniverseSelector {
@@ -371,546 +373,3 @@ class Universe {
}));
}
}
-
-class SelectorKind {
- final String name;
- final int hashCode;
- const SelectorKind(this.name, this.hashCode);
-
- static const SelectorKind GETTER = const SelectorKind('getter', 0);
- static const SelectorKind SETTER = const SelectorKind('setter', 1);
- static const SelectorKind CALL = const SelectorKind('call', 2);
- static const SelectorKind OPERATOR = const SelectorKind('operator', 3);
- static const SelectorKind INDEX = const SelectorKind('index', 4);
-
- String toString() => name;
-}
-
-/// 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;
-
- /// The number of named arguments of the call.
- int get namedArgumentCount => 0;
-
- /// The number of positional argument of the call.
- int get positionalArgumentCount => argumentCount;
-
- const CallStructure.unnamed(this.argumentCount);
-
- factory CallStructure(int argumentCount, [List<String> namedArguments]) {
- if (namedArguments == null || namedArguments.isEmpty) {
- return new CallStructure.unnamed(argumentCount);
- }
- return new NamedCallStructure(argumentCount, namedArguments);
- }
-
- /// `true` if this call has named arguments.
- bool get isNamed => false;
-
- /// `true` if this call has no named arguments.
- bool get isUnnamed => true;
-
- /// The names of the named arguments in call-site order.
- List<String> get namedArguments => const <String>[];
-
- /// The names of the named arguments in canonicalized order.
- List<String> getOrderedNamedArguments() => const <String>[];
-
- /// A description of the argument structure.
- String structureToString() => 'arity=$argumentCount';
-
- String toString() => 'CallStructure(${structureToString()})';
-
- Selector get callSelector {
- return new Selector(SelectorKind.CALL, Selector.CALL_NAME, this);
- }
-
- bool match(CallStructure other) {
- if (identical(this, other)) return true;
- return this.argumentCount == other.argumentCount
- && this.namedArgumentCount == other.namedArgumentCount
- && sameNames(this.namedArguments, other.namedArguments);
- }
-
- // TODO(johnniwinther): Cache hash code?
- int get hashCode {
- return Hashing.listHash(namedArguments,
- Hashing.objectHash(argumentCount, namedArguments.length));
- }
-
- bool operator ==(other) {
- if (other is! CallStructure) return false;
- return match(other);
- }
-
- bool signatureApplies(FunctionSignature parameters) {
- if (argumentCount > parameters.parameterCount) return false;
- int requiredParameterCount = parameters.requiredParameterCount;
- int optionalParameterCount = parameters.optionalParameterCount;
- if (positionalArgumentCount < requiredParameterCount) return false;
-
- if (!parameters.optionalParametersAreNamed) {
- // We have already checked that the number of arguments are
- // not greater than the number of parameters. Therefore the
- // number of positional arguments are not greater than the
- // number of parameters.
- assert(positionalArgumentCount <= parameters.parameterCount);
- return namedArguments.isEmpty;
- } else {
- if (positionalArgumentCount > requiredParameterCount) return false;
- assert(positionalArgumentCount == requiredParameterCount);
- if (namedArgumentCount > optionalParameterCount) return false;
- Set<String> nameSet = new Set<String>();
- parameters.optionalParameters.forEach((Element element) {
- nameSet.add(element.name);
- });
- for (String name in namedArguments) {
- if (!nameSet.contains(name)) return false;
- // TODO(5213): By removing from the set we are checking
- // that we are not passing the name twice. We should have this
- // check in the resolver also.
- nameSet.remove(name);
- }
- return true;
- }
- }
-
- /**
- * Returns a `List` with the evaluated arguments in the normalized order.
- *
- * [compileDefaultValue] is a function that returns a compiled constant
- * of an optional argument that is not in [compiledArguments].
- *
- * Precondition: `this.applies(element, world)`.
- *
- * Invariant: [element] must be the implementation element.
- */
- /*<T>*/ List/*<T>*/ makeArgumentsList(
- Link<Node> arguments,
- FunctionElement element,
- /*T*/ compileArgument(Node argument),
- /*T*/ compileDefaultValue(ParameterElement element)) {
- assert(invariant(element, element.isImplementation));
- List/*<T>*/ result = new List();
-
- FunctionSignature parameters = element.functionSignature;
- parameters.forEachRequiredParameter((ParameterElement element) {
- result.add(compileArgument(arguments.head));
- arguments = arguments.tail;
- });
-
- if (!parameters.optionalParametersAreNamed) {
- parameters.forEachOptionalParameter((ParameterElement element) {
- if (!arguments.isEmpty) {
- result.add(compileArgument(arguments.head));
- arguments = arguments.tail;
- } else {
- result.add(compileDefaultValue(element));
- }
- });
- } else {
- // Visit named arguments and add them into a temporary list.
- List compiledNamedArguments = [];
- for (; !arguments.isEmpty; arguments = arguments.tail) {
- NamedArgument namedArgument = arguments.head;
- compiledNamedArguments.add(compileArgument(namedArgument.expression));
- }
- // Iterate over the optional parameters of the signature, and try to
- // find them in [compiledNamedArguments]. If found, we use the
- // value in the temporary list, otherwise the default value.
- parameters.orderedOptionalParameters.forEach((ParameterElement element) {
- int foundIndex = namedArguments.indexOf(element.name);
- if (foundIndex != -1) {
- result.add(compiledNamedArguments[foundIndex]);
- } else {
- result.add(compileDefaultValue(element));
- }
- });
- }
- return result;
- }
-
- /**
- * Fills [list] with the arguments in the order expected by
- * [callee], and where [caller] is a synthesized element
- *
- * [compileArgument] is a function that returns a compiled version
- * of a parameter of [callee].
- *
- * [compileConstant] is a function that returns a compiled constant
- * of an optional argument that is not in the parameters of [callee].
- *
- * Returns [:true:] if the signature of the [caller] matches the
- * signature of the [callee], [:false:] otherwise.
- */
- static /*<T>*/ bool addForwardingElementArgumentsToList(
- ConstructorElement caller,
- List/*<T>*/ list,
- ConstructorElement callee,
- /*T*/ compileArgument(ParameterElement element),
- /*T*/ compileConstant(ParameterElement element)) {
- assert(invariant(caller, !callee.isErroneous,
- message: "Cannot compute arguments to erroneous constructor: "
- "$caller calling $callee."));
-
- FunctionSignature signature = caller.functionSignature;
- Map<Node, ParameterElement> mapping = <Node, ParameterElement>{};
-
- // TODO(ngeoffray): This is a hack that fakes up AST nodes, so
- // that we can call [addArgumentsToList].
- Link<Node> computeCallNodesFromParameters() {
- LinkBuilder<Node> builder = new LinkBuilder<Node>();
- signature.forEachRequiredParameter((ParameterElement element) {
- Node node = element.node;
- mapping[node] = element;
- builder.addLast(node);
- });
- if (signature.optionalParametersAreNamed) {
- signature.forEachOptionalParameter((ParameterElement element) {
- mapping[element.initializer] = element;
- builder.addLast(new NamedArgument(null, null, element.initializer));
- });
- } else {
- signature.forEachOptionalParameter((ParameterElement element) {
- Node node = element.node;
- mapping[node] = element;
- builder.addLast(node);
- });
- }
- return builder.toLink();
- }
-
- /*T*/ internalCompileArgument(Node node) {
- return compileArgument(mapping[node]);
- }
-
- Link<Node> nodes = computeCallNodesFromParameters();
-
- // Synthesize a structure for the call.
- // TODO(ngeoffray): Should the resolver do it instead?
- List<String> namedParameters;
- if (signature.optionalParametersAreNamed) {
- namedParameters =
- signature.optionalParameters.map((e) => e.name).toList();
- }
- CallStructure callStructure =
- new CallStructure(signature.parameterCount, namedParameters);
- if (!callStructure.signatureApplies(signature)) {
- return false;
- }
- list.addAll(callStructure.makeArgumentsList(
- nodes,
- callee,
- internalCompileArgument,
- compileConstant));
-
- return true;
- }
-
- static bool sameNames(List<String> first, List<String> second) {
- for (int i = 0; i < first.length; i++) {
- if (first[i] != second[i]) return false;
- }
- return true;
- }
-}
-
-///
-class NamedCallStructure extends CallStructure {
- final List<String> namedArguments;
- final List<String> _orderedNamedArguments = <String>[];
-
- NamedCallStructure(int argumentCount, this.namedArguments)
- : super.unnamed(argumentCount) {
- assert(namedArguments.isNotEmpty);
- }
-
- @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 (!_orderedNamedArguments.isEmpty) return _orderedNamedArguments;
-
- _orderedNamedArguments.addAll(namedArguments);
- _orderedNamedArguments.sort((String first, String second) {
- return first.compareTo(second);
- });
- return _orderedNamedArguments;
- }
-
- @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 = Names.call;
-
- 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) ||
- identical(memberName.text, '??'));
- assert(kind == SelectorKind.CALL ||
- kind == SelectorKind.GETTER ||
- kind == SelectorKind.SETTER ||
- Elements.isOperatorName(memberName.text) ||
- identical(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);
- return existing;
- }
- }
- Selector result = new Selector.internal(
- kind, name, callStructure, hashCode);
- list.add(result);
- return result;
- }
-
- factory Selector.fromElement(Element element) {
- Name name = new Name(element.name, element.library);
- if (element.isFunction) {
- if (name == INDEX_NAME) {
- return new Selector.index();
- } else if (name == INDEX_SET_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,
- new CallStructure(arity, namedArguments));
- } else {
- return new Selector.call(
- name, new CallStructure(arity, namedArguments));
- }
- } else if (element.isSetter) {
- return new Selector.setter(name);
- } else if (element.isGetter) {
- return new Selector.getter(name);
- } else if (element.isField) {
- return new Selector.getter(name);
- } else if (element.isConstructor) {
- return new Selector.callConstructor(name);
- } else {
- throw new SpannableAssertionFailure(
- element, "Can't get selector from $element");
- }
- }
-
- factory Selector.getter(Name name)
- => new Selector(SelectorKind.GETTER,
- name.getter,
- CallStructure.NO_ARGS);
-
- factory Selector.setter(Name name)
- => new Selector(SelectorKind.SETTER,
- name.setter,
- 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(Name name, CallStructure callStructure)
- => new Selector(SelectorKind.CALL, name, callStructure);
-
- 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(Name name,
- [int arity = 0,
- List<String> namedArguments])
- => new Selector(SelectorKind.CALL, name,
- 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");
-
- /**
- * 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;
- }
- 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) {
- if (Elements.isUnresolved(function)) return false;
- return callStructure.signatureApplies(function.functionSignature);
- }
-
- 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 = Hashing.mixHashCodeBits(name.hashCode, kind.hashCode);
- // Add bits from the call structure.
- return Hashing.mixHashCodeBits(hash, callStructure.hashCode);
- }
-
- String toString() {
- return 'Selector($kind, $name, ${callStructure.structureToString()})';
- }
-
- Selector toCallSelector() => new Selector.callClosureFrom(this);
-}
« no previous file with comments | « pkg/compiler/lib/src/universe/selector.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698