572 return getSymbols(sf, NON_RECURSIVE).iterator().hasNext(); |
567 return getSymbols(sf, NON_RECURSIVE).iterator().hasNext(); |
573 } |
568 } |
574 |
569 |
575 public Iterable<Symbol> getSymbols(final Filter<Symbol> sf, |
570 public Iterable<Symbol> getSymbols(final Filter<Symbol> sf, |
576 final LookupKind lookupKind) { |
571 final LookupKind lookupKind) { |
577 return new Iterable<Symbol>() { |
572 return () -> new Iterator<Symbol>() { |
578 public Iterator<Symbol> iterator() { |
573 private ScopeImpl currScope = ScopeImpl.this; |
579 return new Iterator<Symbol>() { |
574 private Entry currEntry = elems; |
580 private ScopeImpl currScope = ScopeImpl.this; |
575 private int seenRemoveCount = currScope.removeCount; |
581 private Scope.Entry currEntry = elems; |
576 { |
582 private int seenRemoveCount = currScope.removeCount; |
577 update(); |
583 { |
578 } |
584 update(); |
579 |
|
580 public boolean hasNext() { |
|
581 if (seenRemoveCount != currScope.removeCount && |
|
582 currEntry != null && |
|
583 !currEntry.scope.includes(currEntry.sym)) { |
|
584 doNext(); //skip entry that is no longer in the Scope |
|
585 seenRemoveCount = currScope.removeCount; |
|
586 } |
|
587 return currEntry != null; |
|
588 } |
|
589 |
|
590 public Symbol next() { |
|
591 if (!hasNext()) { |
|
592 throw new NoSuchElementException(); |
|
593 } |
|
594 |
|
595 return doNext(); |
|
596 } |
|
597 private Symbol doNext() { |
|
598 Symbol sym = (currEntry == null ? null : currEntry.sym); |
|
599 if (currEntry != null) { |
|
600 currEntry = currEntry.sibling; |
|
601 } |
|
602 update(); |
|
603 return sym; |
|
604 } |
|
605 |
|
606 private void update() { |
|
607 skipToNextMatchingEntry(); |
|
608 if (lookupKind == RECURSIVE) { |
|
609 while (currEntry == null && currScope.next != null) { |
|
610 currScope = currScope.next; |
|
611 currEntry = currScope.elems; |
|
612 seenRemoveCount = currScope.removeCount; |
|
613 skipToNextMatchingEntry(); |
585 } |
614 } |
586 |
615 } |
587 public boolean hasNext() { |
616 } |
588 if (seenRemoveCount != currScope.removeCount && |
617 |
589 currEntry != null && |
618 void skipToNextMatchingEntry() { |
590 !currEntry.scope.includes(currEntry.sym)) { |
619 while (currEntry != null && sf != null && !sf.accepts(currEntry.sym)) { |
591 doNext(); //skip entry that is no longer in the Scope |
620 currEntry = currEntry.sibling; |
592 seenRemoveCount = currScope.removeCount; |
621 } |
593 } |
|
594 return currEntry != null; |
|
595 } |
|
596 |
|
597 public Symbol next() { |
|
598 if (!hasNext()) { |
|
599 throw new NoSuchElementException(); |
|
600 } |
|
601 |
|
602 return doNext(); |
|
603 } |
|
604 private Symbol doNext() { |
|
605 Symbol sym = (currEntry == null ? null : currEntry.sym); |
|
606 if (currEntry != null) { |
|
607 currEntry = currEntry.sibling; |
|
608 } |
|
609 update(); |
|
610 return sym; |
|
611 } |
|
612 |
|
613 public void remove() { |
|
614 throw new UnsupportedOperationException(); |
|
615 } |
|
616 |
|
617 private void update() { |
|
618 skipToNextMatchingEntry(); |
|
619 if (lookupKind == RECURSIVE) { |
|
620 while (currEntry == null && currScope.next != null) { |
|
621 currScope = currScope.next; |
|
622 currEntry = currScope.elems; |
|
623 seenRemoveCount = currScope.removeCount; |
|
624 skipToNextMatchingEntry(); |
|
625 } |
|
626 } |
|
627 } |
|
628 |
|
629 void skipToNextMatchingEntry() { |
|
630 while (currEntry != null && sf != null && !sf.accepts(currEntry.sym)) { |
|
631 currEntry = currEntry.sibling; |
|
632 } |
|
633 } |
|
634 }; |
|
635 } |
622 } |
636 }; |
623 }; |
637 } |
624 } |
638 |
625 |
639 public Iterable<Symbol> getSymbolsByName(final Name name, |
626 public Iterable<Symbol> getSymbolsByName(final Name name, |
640 final Filter<Symbol> sf, |
627 final Filter<Symbol> sf, |
641 final LookupKind lookupKind) { |
628 final LookupKind lookupKind) { |
642 return new Iterable<Symbol>() { |
629 return () -> new Iterator<Symbol>() { |
643 public Iterator<Symbol> iterator() { |
630 Entry currentEntry = lookup(name, sf); |
644 return new Iterator<Symbol>() { |
631 int seenRemoveCount = currentEntry.scope != null ? |
645 Scope.Entry currentEntry = lookup(name, sf); |
632 currentEntry.scope.removeCount : -1; |
646 int seenRemoveCount = currentEntry.scope != null ? |
633 |
647 currentEntry.scope.removeCount : -1; |
634 public boolean hasNext() { |
648 |
635 if (currentEntry.scope != null && |
649 public boolean hasNext() { |
636 seenRemoveCount != currentEntry.scope.removeCount && |
650 if (currentEntry.scope != null && |
637 !currentEntry.scope.includes(currentEntry.sym)) { |
651 seenRemoveCount != currentEntry.scope.removeCount && |
638 doNext(); //skip entry that is no longer in the Scope |
652 !currentEntry.scope.includes(currentEntry.sym)) { |
639 } |
653 doNext(); //skip entry that is no longer in the Scope |
640 return currentEntry.scope != null && |
654 } |
641 (lookupKind == RECURSIVE || |
655 return currentEntry.scope != null && |
642 currentEntry.scope == ScopeImpl.this); |
656 (lookupKind == RECURSIVE || |
643 } |
657 currentEntry.scope == ScopeImpl.this); |
644 public Symbol next() { |
658 } |
645 if (!hasNext()) { |
659 public Symbol next() { |
646 throw new NoSuchElementException(); |
660 if (!hasNext()) { |
647 } |
661 throw new NoSuchElementException(); |
648 return doNext(); |
662 } |
649 } |
663 return doNext(); |
650 private Symbol doNext() { |
664 } |
651 Entry prevEntry = currentEntry; |
665 private Symbol doNext() { |
652 currentEntry = currentEntry.next(sf); |
666 Scope.Entry prevEntry = currentEntry; |
653 return prevEntry.sym; |
667 currentEntry = currentEntry.next(sf); |
654 } |
668 return prevEntry.sym; |
655 public void remove() { |
669 } |
656 throw new UnsupportedOperationException(); |
670 public void remove() { |
657 } |
671 throw new UnsupportedOperationException(); |
658 }; |
672 } |
|
673 }; |
|
674 } |
|
675 }; |
|
676 } |
659 } |
677 |
660 |
678 public Scope getOrigin(Symbol s) { |
661 public Scope getOrigin(Symbol s) { |
679 for (Scope.Entry e = lookup(s.name); e.scope != null ; e = e.next()) { |
662 for (Scope.Entry e = lookup(s.name); e.scope != null ; e = e.next()) { |
680 if (e.sym == s) { |
663 if (e.sym == s) { |