| // 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. |
| |
| part of universe; |
| |
| // TODO(kasperl): This actually holds getters and setters just fine |
| // too and stricly they aren't functions. Maybe this needs a better |
| // name -- something like ElementSet seems a bit too generic. |
| class FunctionSet extends PartialTypeTree { |
| |
| FunctionSet(Compiler compiler) : super(compiler); |
| |
| FunctionSetNode newSpecializedNode(ClassElement type) |
| => new FunctionSetNode(type); |
| |
| // TODO(kasperl): Allow static members too? |
| void add(Element element) { |
| assert(element.isMember()); |
| FunctionSetNode node = findNode(element.getEnclosingClass(), true); |
| node.membersByName[element.name] = element; |
| } |
| |
| // TODO(kasperl): Allow static members too? |
| void remove(Element element) { |
| assert(element.isMember()); |
| FunctionSetNode node = findNode(element.getEnclosingClass(), false); |
| if (node != null) node.membersByName.remove(element.name); |
| } |
| |
| // TODO(kasperl): Allow static members too? |
| bool contains(Element element) { |
| assert(element.isMember()); |
| FunctionSetNode node = findNode(element.getEnclosingClass(), false); |
| return (node != null) |
| ? node.membersByName.containsKey(element.name) |
| : false; |
| } |
| |
| /** |
| * Returns all elements that may be invoked with the given [selector]. |
| */ |
| Set<Element> filterBySelector(Selector selector) { |
| // TODO(kasperl): For now, we use a different implementation for |
| // filtering if the tree contains interface subtypes. |
| return containsInterfaceSubtypes |
| ? filterAllBySelector(selector) |
| : filterHierarchyBySelector(selector); |
| } |
| |
| /** |
| * Returns whether the set has any element matching the given |
| * [selector]. |
| */ |
| bool hasAnyElementMatchingSelector(Selector selector) { |
| // TODO(kasperl): For now, we use a different implementation for |
| // filtering if the tree contains interface subtypes. |
| return containsInterfaceSubtypes |
| ? hasAnyInAll(selector) |
| : hasAnyInHierarchy(selector); |
| } |
| |
| Set<Element> filterAllBySelector(Selector selector) { |
| Set<Element> result = new Set<Element>(); |
| if (root == null) return result; |
| root.visitRecursively((FunctionSetNode node) { |
| Element member = node.membersByName[selector.name]; |
| // Since we're running through the entire tree we have to use |
| // the applies method that takes types into account. |
| if (member != null && selector.applies(member, compiler)) { |
| result.add(member); |
| } |
| return true; |
| }); |
| return result; |
| } |
| |
| Set<Element> filterHierarchyBySelector(Selector selector) { |
| Set<Element> result = new Set<Element>(); |
| if (root == null) return result; |
| visitHierarchy(selectorType(selector), (FunctionSetNode node) { |
| Element member = node.membersByName[selector.name]; |
| if (member != null && selector.appliesUntyped(member, compiler)) { |
| result.add(member); |
| } |
| return true; |
| }); |
| return result; |
| } |
| |
| bool hasAnyInAll(Selector selector) { |
| bool result = false; |
| if (root == null) return result; |
| root.visitRecursively((FunctionSetNode node) { |
| Element member = node.membersByName[selector.name]; |
| // Since we're running through the entire tree we have to use |
| // the applies method that takes types into account. |
| if (member != null && selector.applies(member, compiler)) { |
| result = true; |
| // End the traversal. |
| return false; |
| } |
| return true; |
| }); |
| return result; |
| } |
| |
| bool hasAnyInHierarchy(Selector selector) { |
| bool result = false; |
| if (root == null) return result; |
| visitHierarchy(selectorType(selector), (FunctionSetNode node) { |
| Element member = node.membersByName[selector.name]; |
| if (member != null && selector.appliesUntyped(member, compiler)) { |
| result = true; |
| // End the traversal. |
| return false; |
| } |
| return true; |
| }); |
| return result; |
| } |
| |
| void forEach(Function f) { |
| if (root == null) return; |
| root.visitRecursively((FunctionSetNode node) { |
| node.membersByName.forEach( |
| (SourceString _, Element element) => f(element)); |
| return true; |
| }); |
| } |
| } |
| |
| class FunctionSetNode extends PartialTypeTreeNode { |
| |
| final Map<SourceString, Element> membersByName; |
| |
| FunctionSetNode(ClassElement type) : super(type), |
| membersByName = new Map<SourceString, Element>(); |
| |
| } |