Search in sources :

Example 1 with FilteringNodeIterator

use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.

the class DuplicatesMatchingVisitor method match.

@Override
public boolean match(PsiElement element1, PsiElement element2) {
    if (element1 == null || element2 == null) {
        return element1 == element2;
    }
    if (myDiscardCost > 0) {
        final int cost1 = myTreeHasher.hash(element1, null, myNodeSpecificHasher).getCost();
        final int cost2 = myTreeHasher.hash(element2, null, myNodeSpecificHasher).getCost();
        if (cost1 < myDiscardCost || cost2 < myDiscardCost) {
            return true;
        }
    }
    final DuplicatesProfileBase duplicatesProfile = myNodeSpecificHasher.getDuplicatesProfile();
    final PsiElementRole role1 = duplicatesProfile.getRole(element1);
    final PsiElementRole role2 = duplicatesProfile.getRole(element2);
    final Set<PsiElementRole> skippedRoles = EnumSet.noneOf(PsiElementRole.class);
    final ExternalizableDuplocatorState duplocatorState = duplicatesProfile.getDuplocatorState(duplicatesProfile.getLanguage(element1));
    for (PsiElementRole role : PsiElementRole.values()) {
        if (!duplocatorState.distinguishRole(role)) {
            skippedRoles.add(role);
        }
    }
    if (role1 == role2 && skippedRoles.contains(role1)) {
        return true;
    }
    final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element1);
    EquivalenceDescriptor descriptor1 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element1) : null;
    EquivalenceDescriptor descriptor2 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element2) : null;
    PsiElement newElement1 = DuplocatorUtil.skipNodeIfNeccessary(element1, descriptor1, myNodeFilter);
    PsiElement newElement2 = DuplocatorUtil.skipNodeIfNeccessary(element2, descriptor2, myNodeFilter);
    if (newElement1 != element1 || newElement2 != element2) {
        return match(newElement1, newElement2);
    }
    if (!element1.getClass().equals(element2.getClass())) {
        return false;
    }
    if (descriptor1 != null && descriptor2 != null) {
        return DuplocatorUtil.match(descriptor1, descriptor2, this, skippedRoles, duplicatesProfile);
    }
    if (element1 instanceof LeafElement) {
        IElementType elementType1 = ((LeafElement) element1).getElementType();
        IElementType elementType2 = ((LeafElement) element2).getElementType();
        if (!duplocatorState.distinguishLiterals() && duplicatesProfile.getLiterals().contains(elementType1) && duplicatesProfile.getLiterals().contains(elementType2)) {
            return true;
        }
        return element1.getText().equals(element2.getText());
    }
    if (element1.getFirstChild() == null && element1.getTextLength() == 0) {
        return element2.getFirstChild() == null && element2.getTextLength() == 0;
    }
    return matchSequentially(new FilteringNodeIterator(new SiblingNodeIterator(element1.getFirstChild()), getNodeFilter()), new FilteringNodeIterator(new SiblingNodeIterator(element2.getFirstChild()), getNodeFilter()));
}
Also used : IElementType(com.intellij.psi.tree.IElementType) EquivalenceDescriptorProvider(com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider) SiblingNodeIterator(com.intellij.dupLocator.iterators.SiblingNodeIterator) FilteringNodeIterator(com.intellij.dupLocator.iterators.FilteringNodeIterator) EquivalenceDescriptor(com.intellij.dupLocator.equivalence.EquivalenceDescriptor) PsiElement(com.intellij.psi.PsiElement) LeafElement(com.intellij.psi.impl.source.tree.LeafElement)

Example 2 with FilteringNodeIterator

use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.

the class AbstractMatchingVisitor method matchSonsInAnyOrder.

public final boolean matchSonsInAnyOrder(PsiElement element1, PsiElement element2) {
    if (element1 == null && isLeftLooseMatching()) {
        return true;
    }
    if (element2 == null && isRightLooseMatching()) {
        return true;
    }
    if (element1 == null || element2 == null) {
        return element1 == element2;
    }
    PsiElement e = element1.getFirstChild();
    PsiElement e2 = element2.getFirstChild();
    return (e == null && isLeftLooseMatching()) || (e2 == null && isRightLooseMatching()) || matchInAnyOrder(new FilteringNodeIterator(new SiblingNodeIterator(e), getNodeFilter()), new FilteringNodeIterator(new SiblingNodeIterator(e2), getNodeFilter()));
}
Also used : SiblingNodeIterator(com.intellij.dupLocator.iterators.SiblingNodeIterator) FilteringNodeIterator(com.intellij.dupLocator.iterators.FilteringNodeIterator) PsiElement(com.intellij.psi.PsiElement)

Example 3 with FilteringNodeIterator

use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.

the class NodeSpecificHasherBase method getNodeChildren.

@Override
public List<PsiElement> getNodeChildren(PsiElement node) {
    final List<PsiElement> result = new ArrayList<>();
    final FilteringNodeIterator it = new FilteringNodeIterator(new SiblingNodeIterator(node.getFirstChild()), myNodeFilter);
    while (it.hasNext()) {
        result.add(it.current());
        it.advance();
    }
    return result;
}
Also used : SiblingNodeIterator(com.intellij.dupLocator.iterators.SiblingNodeIterator) FilteringNodeIterator(com.intellij.dupLocator.iterators.FilteringNodeIterator) ArrayList(java.util.ArrayList) PsiElement(com.intellij.psi.PsiElement)

Example 4 with FilteringNodeIterator

use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.

the class DuplocatorUtil method getOnlyChild.

public static PsiElement getOnlyChild(PsiElement element, @NotNull NodeFilter filter) {
    FilteringNodeIterator it = new FilteringNodeIterator(new SiblingNodeIterator(element.getFirstChild()), filter);
    PsiElement child = it.current();
    if (child != null) {
        it.advance();
        if (!it.hasNext()) {
            return child;
        }
    }
    return element;
}
Also used : SiblingNodeIterator(com.intellij.dupLocator.iterators.SiblingNodeIterator) FilteringNodeIterator(com.intellij.dupLocator.iterators.FilteringNodeIterator) PsiElement(com.intellij.psi.PsiElement)

Example 5 with FilteringNodeIterator

use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.

the class SubstitutionHandler method doMatchSequentially.

protected boolean doMatchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
    final int previousMatchedOccurs = matchedOccurs;
    FilteringNodeIterator fNodes2 = new FilteringNodeIterator(nodes2, VARS_DELIM_FILTER);
    try {
        MatchingHandler handler = context.getPattern().getHandler(nodes.current());
        matchedOccurs = 0;
        boolean flag = false;
        while (fNodes2.hasNext() && matchedOccurs < minOccurs) {
            if (handler.match(nodes.current(), nodes2.current(), context)) {
                ++matchedOccurs;
            } else {
                break;
            }
            fNodes2.advance();
            flag = true;
        }
        if (matchedOccurs != minOccurs) {
            // failed even for min occurs
            removeLastResults(matchedOccurs, context);
            fNodes2.rewind(matchedOccurs);
            return false;
        }
        if (greedy) {
            while (fNodes2.hasNext() && matchedOccurs < maxOccurs) {
                if (handler.match(nodes.current(), nodes2.current(), context)) {
                    ++matchedOccurs;
                } else {
                    // no more matches could take!
                    break;
                }
                fNodes2.advance();
                flag = true;
            }
            if (flag) {
                fNodes2.rewind();
                nodes2.advance();
            }
            nodes.advance();
            if (nodes.hasNext()) {
                final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
                while (matchedOccurs >= minOccurs) {
                    if (nextHandler.matchSequentially(nodes, nodes2, context)) {
                        totalMatchedOccurs = matchedOccurs;
                        // match found
                        return true;
                    }
                    if (matchedOccurs > 0) {
                        nodes2.rewind();
                        removeLastResults(1, context);
                    }
                    --matchedOccurs;
                }
                if (matchedOccurs > 0) {
                    removeLastResults(matchedOccurs, context);
                }
                nodes.rewind();
                return false;
            } else {
                // match found
                if (handler.isMatchSequentiallySucceeded(nodes2)) {
                    return checkSameOccurrencesConstraint();
                }
                removeLastResults(matchedOccurs, context);
                return false;
            }
        } else {
            nodes.advance();
            if (flag) {
                fNodes2.rewind();
                nodes2.advance();
            }
            if (nodes.hasNext()) {
                final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
                flag = false;
                while (nodes2.hasNext() && matchedOccurs <= maxOccurs) {
                    if (nextHandler.matchSequentially(nodes, nodes2, context)) {
                        return checkSameOccurrencesConstraint();
                    }
                    if (flag) {
                        nodes2.rewind();
                        fNodes2.advance();
                    }
                    if (handler.match(nodes.current(), nodes2.current(), context)) {
                        matchedOccurs++;
                    } else {
                        nodes.rewind();
                        removeLastResults(matchedOccurs, context);
                        return false;
                    }
                    nodes2.advance();
                    flag = true;
                }
                nodes.rewind();
                removeLastResults(matchedOccurs, context);
                return false;
            } else {
                return checkSameOccurrencesConstraint();
            }
        }
    } finally {
        matchedOccurs = previousMatchedOccurs;
    }
}
Also used : FilteringNodeIterator(com.intellij.dupLocator.iterators.FilteringNodeIterator)

Aggregations

FilteringNodeIterator (com.intellij.dupLocator.iterators.FilteringNodeIterator)5 SiblingNodeIterator (com.intellij.dupLocator.iterators.SiblingNodeIterator)4 PsiElement (com.intellij.psi.PsiElement)4 EquivalenceDescriptor (com.intellij.dupLocator.equivalence.EquivalenceDescriptor)1 EquivalenceDescriptorProvider (com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider)1 LeafElement (com.intellij.psi.impl.source.tree.LeafElement)1 IElementType (com.intellij.psi.tree.IElementType)1 ArrayList (java.util.ArrayList)1