Files
sdk/lib/compiler/implementation/js_backend/function_set.dart
T
kasperl@google.com 2d772a2283 Fix issue with the partial type tree and implemented interfaces.
Treat partial type trees that have cross-links (because of implements) as too complex and use a slower, but correct way of walking them.

R=sgjesse@google.com,ngeoffray@google.com
BUG=

Review URL: https://chromiumcodereview.appspot.com//10919003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@11584 260f80e4-7a28-3924-810f-c04153c831b5
2012-08-30 08:23:24 +00:00

87 lines
2.9 KiB
Dart

// 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.
// 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);
}
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;
}
}
class FunctionSetNode extends PartialTypeTreeNode {
final Map<SourceString, Element> membersByName;
FunctionSetNode(ClassElement type) : super(type),
membersByName = new Map<SourceString, Element>();
}