| Index: pkg/compiler/lib/src/universe/call_structure.dart
|
| diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
|
| index 4530400e1cbaffc794effa09c6a3e22e636bd033..12e4fd895b3de2c407a2a5da0610908e6d863ea3 100644
|
| --- a/pkg/compiler/lib/src/universe/call_structure.dart
|
| +++ b/pkg/compiler/lib/src/universe/call_structure.dart
|
| @@ -1,390 +1,8 @@
|
| -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| +// Copyright (c) 2015, 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 'dart:collection';
|
| -
|
| -import '../common/names.dart' show
|
| - Identifiers,
|
| - Names,
|
| - Selectors;
|
| -import '../compiler.dart' show
|
| - Compiler;
|
| -import '../diagnostics/invariant.dart' show
|
| - invariant;
|
| -import '../diagnostics/spannable.dart' show
|
| - SpannableAssertionFailure;
|
| -import '../elements/elements.dart';
|
| -import '../dart_types.dart';
|
| -import '../tree/tree.dart';
|
| -import '../types/types.dart';
|
| -import '../util/util.dart';
|
| -import '../world.dart' show
|
| - ClassWorld,
|
| - World;
|
| -
|
| -part 'function_set.dart';
|
| -part 'side_effects.dart';
|
| -
|
| -class UniverseSelector {
|
| - final Selector selector;
|
| - final ReceiverMask mask;
|
| -
|
| - UniverseSelector(this.selector, this.mask);
|
| -
|
| - bool appliesUnnamed(Element element, ClassWorld world) {
|
| - return selector.appliesUnnamed(element, world) &&
|
| - (mask == null || mask.canHit(element, selector, world));
|
| - }
|
| -
|
| - String toString() => '$selector,$mask';
|
| -}
|
| -
|
| -/// A potential receiver for a dynamic call site.
|
| -abstract class ReceiverMask {
|
| - /// Returns whether [element] is a potential target when being
|
| - /// invoked on this receiver mask. [selector] is used to ensure library
|
| - /// privacy is taken into account.
|
| - bool canHit(Element element, Selector selector, ClassWorld classWorld);
|
| -}
|
| -
|
| -/// A set of potential receivers for the dynamic call sites of the same
|
| -/// selector.
|
| -///
|
| -/// For instance for these calls
|
| -///
|
| -/// new A().foo(a, b);
|
| -/// new B().foo(0, 42);
|
| -///
|
| -/// the receiver mask set for dynamic calls to 'foo' with to positional
|
| -/// arguments will contain receiver masks abstracting `new A()` and `new B()`.
|
| -abstract class ReceiverMaskSet {
|
| - /// Returns `true` if [selector] applies to any of the potential receivers
|
| - /// in this set given the closed [world].
|
| - bool applies(Element element, Selector selector, ClassWorld world);
|
| -
|
| - /// Returns `true` if any potential receivers in this set given the closed
|
| - /// [world] have no implementation matching [selector].
|
| - ///
|
| - /// For instance for this code snippet
|
| - ///
|
| - /// class A {}
|
| - /// class B { foo() {} }
|
| - /// m(b) => (b ? new A() : new B()).foo();
|
| - ///
|
| - /// the potential receiver `new A()` have no implementation of `foo` and thus
|
| - /// needs to handle the call though its `noSuchMethod` handler.
|
| - bool needsNoSuchMethodHandling(Selector selector, ClassWorld world);
|
| -}
|
| -
|
| -/// A mutable [ReceiverMaskSet] used in [Universe].
|
| -abstract class UniverseReceiverMaskSet extends ReceiverMaskSet {
|
| - /// Adds [mask] to this set of potential receivers. Return `true` if the
|
| - /// set expanded due to the new mask.
|
| - bool addReceiverMask(ReceiverMask mask);
|
| -}
|
| -
|
| -/// Strategy for computing potential receivers of dynamic call sites.
|
| -abstract class ReceiverMaskStrategy {
|
| - /// Create a [UniverseReceiverMaskSet] to represent the potential receiver for
|
| - /// a dynamic call site with [selector].
|
| - UniverseReceiverMaskSet createReceiverMaskSet(Selector selector);
|
| -}
|
| -
|
| -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>();
|
| -
|
| - /// The set of all referenced static fields.
|
| - ///
|
| - /// Invariant: Elements are declaration elements.
|
| - final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
|
| -
|
| - /**
|
| - * 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, Map<Selector, ReceiverMaskSet>> _invokedNames =
|
| - <String, Map<Selector, ReceiverMaskSet>>{};
|
| - final Map<String, Map<Selector, ReceiverMaskSet>> _invokedGetters =
|
| - <String, Map<Selector, ReceiverMaskSet>>{};
|
| - final Map<String, Map<Selector, ReceiverMaskSet>> _invokedSetters =
|
| - <String, Map<Selector, ReceiverMaskSet>>{};
|
| -
|
| - /**
|
| - * 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>();
|
| -
|
| - final ReceiverMaskStrategy receiverMaskStrategy;
|
| -
|
| - Universe(this.receiverMaskStrategy);
|
| -
|
| - /// 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 through subtypes. The latter case only contains
|
| - /// spurious information from instatiations through factory constructors and
|
| - /// mixins.
|
| - // 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(Map<Selector, ReceiverMaskSet> selectors,
|
| - Element member,
|
| - World world) {
|
| - if (selectors == null) return false;
|
| - for (Selector selector in selectors.keys) {
|
| - if (selector.appliesUnnamed(member, world)) {
|
| - ReceiverMaskSet masks = selectors[selector];
|
| - if (masks.applies(member, selector, 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);
|
| - }
|
| -
|
| - bool registerInvocation(UniverseSelector selector) {
|
| - return _registerNewSelector(selector, _invokedNames);
|
| - }
|
| -
|
| - bool registerInvokedGetter(UniverseSelector selector) {
|
| - return _registerNewSelector(selector, _invokedGetters);
|
| - }
|
| -
|
| - bool registerInvokedSetter(UniverseSelector selector) {
|
| - return _registerNewSelector(selector, _invokedSetters);
|
| - }
|
| -
|
| - bool _registerNewSelector(
|
| - UniverseSelector universeSelector,
|
| - Map<String, Map<Selector, ReceiverMaskSet>> selectorMap) {
|
| - Selector selector = universeSelector.selector;
|
| - String name = selector.name;
|
| - ReceiverMask mask = universeSelector.mask;
|
| - Map<Selector, ReceiverMaskSet> selectors = selectorMap.putIfAbsent(
|
| - name, () => new Maplet<Selector, ReceiverMaskSet>());
|
| - UniverseReceiverMaskSet masks = selectors.putIfAbsent(
|
| - selector, () => receiverMaskStrategy.createReceiverMaskSet(selector));
|
| - return masks.addReceiverMask(mask);
|
| - }
|
| -
|
| - Map<Selector, ReceiverMaskSet> _asUnmodifiable(
|
| - Map<Selector, ReceiverMaskSet> map) {
|
| - if (map == null) return null;
|
| - return new UnmodifiableMapView(map);
|
| - }
|
| -
|
| - Map<Selector, ReceiverMaskSet> invocationsByName(String name) {
|
| - return _asUnmodifiable(_invokedNames[name]);
|
| - }
|
| -
|
| - Map<Selector, ReceiverMaskSet> getterInvocationsByName(String name) {
|
| - return _asUnmodifiable(_invokedGetters[name]);
|
| - }
|
| -
|
| - Map<Selector, ReceiverMaskSet> setterInvocationsByName(String name) {
|
| - return _asUnmodifiable(_invokedSetters[name]);
|
| - }
|
| -
|
| - void forEachInvokedName(
|
| - f(String name, Map<Selector, ReceiverMaskSet> selectors)) {
|
| - _invokedNames.forEach(f);
|
| - }
|
| -
|
| - void forEachInvokedGetter(
|
| - f(String name, Map<Selector, ReceiverMaskSet> selectors)) {
|
| - _invokedGetters.forEach(f);
|
| - }
|
| -
|
| - void forEachInvokedSetter(
|
| - f(String name, Map<Selector, ReceiverMaskSet> selectors)) {
|
| - _invokedSetters.forEach(f);
|
| - }
|
| -
|
| - 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 registerStaticFieldUse(FieldElement staticField) {
|
| - assert(Elements.isStaticOrTopLevel(staticField) && staticField.isField);
|
| - assert(staticField.isDeclaration);
|
| -
|
| - allReferencedStaticFields.add(staticField);
|
| - }
|
| -
|
| - 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;
|
| -}
|
| +part of universe;
|
|
|
| /// The structure of the arguments at a call-site.
|
| // TODO(johnniwinther): Should these be cached?
|
| @@ -662,255 +280,3 @@ class NamedCallStructure extends CallStructure {
|
| 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);
|
| -}
|
|
|