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

Unified Diff: sdk/lib/_internal/compiler/implementation/universe/universe.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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
Index: sdk/lib/_internal/compiler/implementation/universe/universe.dart
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
deleted file mode 100644
index e5e3915d8518b57786f3721788cf218bfb612466..0000000000000000000000000000000000000000
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ /dev/null
@@ -1,805 +0,0 @@
-// Copyright (c) 2012, 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.
-
-library universe;
-
-import '../elements/elements.dart';
-import '../dart2jslib.dart';
-import '../dart_types.dart';
-import '../types/types.dart';
-import '../tree/tree.dart';
-import '../util/util.dart';
-
-part 'function_set.dart';
-part 'side_effects.dart';
-
-class Universe {
- /// The set of all directly instantiated classes, that is, classes with a
- /// generative constructor that has been called directly and not only through
- /// a super-call.
- ///
- /// Invariant: Elements are declaration elements.
- // TODO(johnniwinther): [_directlyInstantiatedClasses] and
- // [_instantiatedTypes] sets should be merged.
- final Set<ClassElement> _directlyInstantiatedClasses =
- new Set<ClassElement>();
-
- /// The set of all directly instantiated types, that is, the types of the
- /// directly instantiated classes.
- ///
- /// See [_directlyInstantiatedClasses].
- final Set<DartType> _instantiatedTypes = new Set<DartType>();
-
- /// The set of all instantiated classes, either directly, as superclasses or
- /// as supertypes.
- ///
- /// Invariant: Elements are declaration elements.
- final Set<ClassElement> _allInstantiatedClasses = new Set<ClassElement>();
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Elements are declaration elements.
- */
- final Set<FunctionElement> staticFunctionsNeedingGetter =
- new Set<FunctionElement>();
- final Set<FunctionElement> methodsNeedingSuperGetter =
- new Set<FunctionElement>();
- final Map<String, Set<Selector>> invokedNames =
- new Map<String, Set<Selector>>();
- final Map<String, Set<Selector>> invokedGetters =
- new Map<String, Set<Selector>>();
- final Map<String, Set<Selector>> invokedSetters =
- new Map<String, Set<Selector>>();
-
- /**
- * Fields accessed. Currently only the codegen knows this
- * information. The resolver is too conservative when seeing a
- * getter and only registers an invoked getter.
- */
- final Set<Element> fieldGetters = new Set<Element>();
-
- /**
- * Fields set. See comment in [fieldGetters].
- */
- final Set<Element> fieldSetters = new Set<Element>();
- final Set<DartType> isChecks = new Set<DartType>();
-
- /**
- * Set of (live) [:call:] methods whose signatures reference type variables.
- *
- * A live [:call:] method is one whose enclosing class has been instantiated.
- */
- final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>();
-
- /**
- * Set of (live) local functions (closures) whose signatures reference type
- * variables.
- *
- * A live function is one whose enclosing member function has been enqueued.
- */
- final Set<Element> closuresWithFreeTypeVariables = new Set<Element>();
-
- /**
- * Set of all closures in the program. Used by the mirror tracking system
- * to find all live closure instances.
- */
- final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
-
- /**
- * Set of methods in instantiated classes that are potentially
- * closurized.
- */
- final Set<Element> closurizedMembers = new Set<Element>();
-
- bool usingFactoryWithTypeArguments = false;
-
- /// All directly instantiated classes, that is, classes with a generative
- /// constructor that has been called directly and not only through a
- /// super-call.
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<ClassElement> get directlyInstantiatedClasses {
- return _directlyInstantiatedClasses;
- }
-
- /// All instantiated classes, either directly, as superclasses or as
- /// supertypes.
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<ClassElement> get allInstantiatedClasses {
- return _allInstantiatedClasses;
- }
-
- /// All directly instantiated types, that is, the types of the directly
- /// instantiated classes.
- ///
- /// See [directlyInstantiatedClasses].
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
-
- /// Returns `true` if [cls] is considered to be instantiated, either directly,
- /// through subclasses or throught subtypes.
- // TODO(johnniwinther): Improve semantic precision.
- bool isInstantiated(ClassElement cls) {
- return _allInstantiatedClasses.contains(cls);
- }
-
- /// Register [type] as (directly) instantiated.
- ///
- /// If [byMirrors] is `true`, the instantiation is through mirrors.
- // TODO(johnniwinther): Fully enforce the separation between exact, through
- // subclass and through subtype instantiated types/classes.
- // TODO(johnniwinther): Support unknown type arguments for generic types.
- void registerTypeInstantiation(InterfaceType type,
- {bool byMirrors: false}) {
- _instantiatedTypes.add(type);
- ClassElement cls = type.element;
- if (!cls.isAbstract
- // We can't use the closed-world assumption with native abstract
- // classes; a native abstract class may have non-abstract subclasses
- // not declared to the program. Instances of these classes are
- // indistinguishable from the abstract class.
- || cls.isNative
- // Likewise, if this registration comes from the mirror system,
- // all bets are off.
- // TODO(herhut): Track classes required by mirrors seperately.
- || byMirrors) {
- _directlyInstantiatedClasses.add(cls);
- }
-
- // TODO(johnniwinther): Replace this by separate more specific mappings.
- if (!_allInstantiatedClasses.add(cls)) return;
- cls.allSupertypes.forEach((InterfaceType supertype) {
- _allInstantiatedClasses.add(supertype.element);
- });
- }
-
- bool hasMatchingSelector(Set<Selector> selectors,
- Element member,
- World world) {
- if (selectors == null) return false;
- for (Selector selector in selectors) {
- if (selector.appliesUnnamed(member, world)) return true;
- }
- return false;
- }
-
- bool hasInvocation(Element member, World world) {
- return hasMatchingSelector(invokedNames[member.name], member, world);
- }
-
- bool hasInvokedGetter(Element member, World world) {
- return hasMatchingSelector(invokedGetters[member.name], member, world);
- }
-
- bool hasInvokedSetter(Element member, World world) {
- return hasMatchingSelector(invokedSetters[member.name], member, world);
- }
-
- DartType registerIsCheck(DartType type, Compiler compiler) {
- type = type.unalias(compiler);
- // Even in checked mode, type annotations for return type and argument
- // types do not imply type checks, so there should never be a check
- // against the type variable of a typedef.
- isChecks.add(type);
- return type;
- }
-
- void forgetElement(Element element, Compiler compiler) {
- allClosures.remove(element);
- slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
- closurizedMembers.remove(element);
- fieldSetters.remove(element);
- fieldGetters.remove(element);
- _directlyInstantiatedClasses.remove(element);
- _allInstantiatedClasses.remove(element);
- if (element is ClassElement) {
- assert(invariant(
- element, element.thisType.isRaw,
- message: 'Generic classes not supported (${element.thisType}).'));
- _instantiatedTypes
- ..remove(element.rawType)
- ..remove(element.thisType);
- }
- }
-
- // TODO(ahe): Replace this method with something that is O(1), for example,
- // by using a map.
- List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
- // Return new list to guard against concurrent modifications.
- return new List<LocalFunctionElement>.from(
- allClosures.where((LocalFunctionElement closure) {
- return closure.executableContext == element;
- }));
- }
-}
-
-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;
-}
-
-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.
- 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;
-
- 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);
- }
-
- 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;
- }
-
- 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 {
- throw new SpannableAssertionFailure(
- element, "Can't get selector from $element");
- }
- }
-
- 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);
-
- factory Selector.unaryOperator(String name)
- => new Selector(SelectorKind.OPERATOR,
- Elements.constructOperatorName(name, true),
- null, 0);
-
- factory Selector.binaryOperator(String name)
- => new Selector(SelectorKind.OPERATOR,
- Elements.constructOperatorName(name, false),
- null, 1);
-
- factory Selector.index()
- => new Selector(SelectorKind.INDEX,
- Elements.constructOperatorName(INDEX_NAME, false),
- null, 1);
-
- factory Selector.indexSet()
- => new Selector(SelectorKind.INDEX,
- Elements.constructOperatorName(INDEX_SET_NAME, false),
- null, 2);
-
- 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);
-
- 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(LibraryElement library)
- => new Selector(SelectorKind.CALL, "", library, 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;
- }
-
- 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 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 (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 signatureApplies(FunctionElement function) {
- FunctionSignature parameters = function.functionSignature;
- 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;
- }
- }
-
- 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);
- }
-
- /**
- * Fills [list] with the arguments in the normalized order.
- *
- * [compileArgument] is a function that returns a compiled version
- * of an argument located in [arguments].
- *
- * [compileDefaultValue] is a function that returns a compiled constant
- * of an optional argument that is not in [arguments].
- *
- * Returns [:true:] if the selector and the [element] match; [:false:]
- * otherwise.
- *
- * Invariant: [element] must be the implementation element.
- */
- /*<T>*/ bool addArgumentsToList(
- Link<Node> arguments,
- List/*<T>*/ list,
- FunctionElement element,
- /*T*/ compileArgument(Node argument),
- /*T*/ compileDefaultValue(ParameterElement element),
- World world) {
- assert(invariant(element, element.isImplementation));
- if (!this.applies(element, world)) return false;
-
- FunctionSignature parameters = element.functionSignature;
- parameters.forEachRequiredParameter((ParameterElement element) {
- list.add(compileArgument(arguments.head));
- arguments = arguments.tail;
- });
-
- if (!parameters.optionalParametersAreNamed) {
- parameters.forEachOptionalParameter((ParameterElement element) {
- if (!arguments.isEmpty) {
- list.add(compileArgument(arguments.head));
- arguments = arguments.tail;
- } else {
- list.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) {
- list.add(compiledNamedArguments[foundIndex]);
- } else {
- list.add(compileDefaultValue(element));
- }
- });
- }
- return true;
- }
-
- /**
- * 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 bool addForwardingElementArgumentsToList(
- FunctionElement caller,
- List list,
- FunctionElement callee,
- compileArgument(Element element),
- compileConstant(Element element),
- World world) {
-
- FunctionSignature signature = caller.functionSignature;
- Map mapping = new Map();
-
- // TODO(ngeoffray): This is a hack that fakes up AST nodes, so
- // that we can call [addArgumentsToList].
- Link computeCallNodesFromParameters() {
- LinkBuilder builder = new LinkBuilder();
- 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();
- }
-
- internalCompileArgument(Node node) {
- return compileArgument(mapping[node]);
- }
-
- Link<Node> nodes = computeCallNodesFromParameters();
-
- // Synthesize a selector for the call.
- // TODO(ngeoffray): Should the resolver do it instead?
- List<String> namedParameters;
- if (signature.optionalParametersAreNamed) {
- namedParameters =
- signature.optionalParameters.mapToList((e) => e.name);
- }
- Selector selector = new Selector.call(callee.name,
- caller.library,
- signature.parameterCount,
- namedParameters);
-
- return selector.addArgumentsToList(nodes,
- list,
- callee,
- internalCompileArgument,
- compileConstant,
- world);
- }
-
- 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;
- }
-
- 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);
- }
-
- 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;
- }
-
- // 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;
- }
-
- List<String> getOrderedNamedArguments() {
- if (namedArguments.isEmpty) return namedArguments;
- if (!_orderedNamedArguments.isEmpty) return _orderedNamedArguments;
-
- _orderedNamedArguments.addAll(namedArguments);
- _orderedNamedArguments.sort((String first, String second) {
- return first.compareTo(second);
- });
- 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]);
- }
- return "[$result]";
- }
- return '';
- }
-
- 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)';
- }
-
- Selector extendIfReachesAll(Compiler compiler) {
- return new TypedSelector(
- compiler.typesTask.dynamicType, this, compiler.world);
- }
-
- Selector toCallSelector() => new Selector.callClosureFrom(this);
-}
-
-class TypedSelector extends Selector {
- final Selector asUntyped;
- final TypeMask mask;
-
- TypedSelector.internal(this.mask, Selector selector, int hashCode)
- : asUntyped = selector,
- super.internal(selector.kind,
- selector.name,
- selector.library,
- selector.argumentCount,
- selector.namedArguments,
- selector._orderedNamedArguments,
- hashCode) {
- assert(mask != null);
- assert(asUntyped.mask == null);
- }
-
- static Map<Selector, Map<TypeMask, TypedSelector>> canonicalizedValues =
- new Map<Selector, Map<TypeMask, TypedSelector>>();
-
- factory TypedSelector(TypeMask mask, Selector selector, World world) {
- // TODO(johnniwinther): Allow more TypeSelector kinds during resoluton.
- assert(world.isClosed || mask.isExact);
- if (selector.mask == mask) return selector;
- Selector untyped = selector.asUntyped;
- Map<TypeMask, TypedSelector> map = canonicalizedValues.putIfAbsent(untyped,
- () => new Map<TypeMask, TypedSelector>());
- TypedSelector result = map[mask];
- if (result == null) {
- int hashCode = Selector.mixHashCodeBits(untyped.hashCode, mask.hashCode);
- result = map[mask] = new TypedSelector.internal(mask, untyped, hashCode);
- }
- return result;
- }
-
- factory TypedSelector.exact(
- ClassElement base, Selector selector, World world)
- => new TypedSelector(new TypeMask.exact(base, world), selector,
- world);
-
- factory TypedSelector.subclass(
- ClassElement base, Selector selector, World world)
- => new TypedSelector(new TypeMask.subclass(base, world),
- selector, world);
-
- factory TypedSelector.subtype(
- ClassElement base, Selector selector, World world)
- => new TypedSelector(new TypeMask.subtype(base, world),
- selector, world);
-
- bool appliesUnnamed(Element element, World world) {
- assert(sameNameHack(element, world));
- // [TypedSelector] are only used after resolution.
- if (!element.isClassMember) return false;
-
- // A closure can be called through any typed selector:
- // class A {
- // get foo => () => 42;
- // bar() => foo(); // The call to 'foo' is a typed selector.
- // }
- if (element.enclosingClass.isClosure) {
- return appliesUntyped(element, world);
- }
-
- if (!mask.canHit(element, this, world)) return false;
- return appliesUntyped(element, world);
- }
-
- Selector extendIfReachesAll(Compiler compiler) {
- bool canReachAll = compiler.enabledInvokeOn
- && mask.needsNoSuchMethodHandling(this, compiler.world);
- return canReachAll
- ? new TypedSelector(
- compiler.typesTask.dynamicType, this, compiler.world)
- : this;
- }
-}

Powered by Google App Engine
This is Rietveld 408576698