/** * @param instanceFrame instance frame * @return iterable over instance members of the frame, including those nested in namespaces */ public static Iterable<? extends INamedElement> instanceMembers( final IInstanceFrame instanceFrame) { final List<INamedElement> members = new ArrayList<>(); // Iterate over the member functions of the frame, including those nested in namespaces. final Deque<INamedElement> queue = new LinkedList<>(); queue.addLast(instanceFrame); while (!queue.isEmpty()) { final INamedElement cur = queue.getFirst(); queue.removeFirst(); final INamedElementContainer contCur = (INamedElementContainer) cur; for (final INamedElement member : contCur.members()) if (Ast.membership(member) == (contCur == instanceFrame ? ScopeMembership.InstanceMember : ScopeMembership.StaticMember)) { members.add(member); if (member instanceof INamedElementContainer) { // Tail-recursively treat this nested namespace. queue.addLast(member); } } } return members; }
/** * @param path path to first element * @param pathTo path to second element * @return environment in which the generic parameters in the path to the first element are bound * to those in the path to the second element, or null type on error */ public static ResolvedName mapGenericParameters( final Deque<? extends INamedElement> path, final Deque<? extends INamedElement> pathTo) { // Construct an environment in which the current function's generic parameters // are bound to those of the eventual override. final Deque<List<? extends ResolvedName>> tableau = new LinkedList<>(ResolvedName.fromNamedElement(path.getLast()).tableau()); final Iterator<? extends INamedElement> pathIt = path.descendingIterator(); while (pathIt.hasNext()) { pathIt.next(); tableau.removeLast(); } CachedIterator<? extends INamedElement> itPathTo = null; CachedIterator<? extends IGenericParameter> itGPTo = null; boolean end = false; { // Initialise iterators into direct override's generic parameters. boolean foundValid = false; itPathTo = Iterators.cached(pathTo.iterator()); while (!foundValid && itPathTo.hasItem()) { itGPTo = Iterators.cached(itPathTo.item().genericParameters().iterator()); while (!foundValid && itGPTo.hasItem()) { foundValid = true; if (!foundValid) itGPTo.next(); } if (!foundValid) itPathTo.next(); } if (!foundValid) end = true; } for (final INamedElement elt : path) { final List<ResolvedName> row = new ArrayList<>(); for (@SuppressWarnings("unused") final IGenericParameter genericParameter : elt.genericParameters()) { if (end) return null; row.add(ResolvedName.fromNamedElement(itGPTo.item())); { // Increment iterators into direct override's generic parameters. boolean init = true; boolean foundValid = false; if (!init) itPathTo = Iterators.cached(pathTo.iterator()); while (!foundValid && itPathTo.hasItem()) { if (!init) itGPTo = Iterators.cached(itPathTo.item().genericParameters().iterator()); while (!foundValid && itGPTo.hasItem()) { if (!init) foundValid = true; init = false; if (!foundValid) itGPTo.next(); } if (!foundValid) itPathTo.next(); } if (!foundValid) end = true; } } tableau.add(row); } if (!end) return null; return ResolvedName.newNameReference(path.getLast(), tableau); }