Search in sources :

Example 1 with MultiChildDescriptor

use of com.intellij.dupLocator.equivalence.MultiChildDescriptor in project intellij-community by JetBrains.

the class TreeHasherBase method computeHash.

private TreeHashResult computeHash(PsiElement element, PsiFragment parent, EquivalenceDescriptor descriptor, NodeSpecificHasher hasher) {
    final NodeSpecificHasherBase ssrHasher = (NodeSpecificHasherBase) hasher;
    final PsiElement element2 = DuplocatorUtil.skipNodeIfNeccessary(element, descriptor, ssrHasher.getNodeFilter());
    final boolean canSkip = element2 != element;
    final PsiFragment fragment = buildFragment(hasher, element, 0);
    if (parent != null) {
        fragment.setParent(parent);
    }
    int hash = canSkip ? 0 : hasher.getNodeHash(element);
    int cost = hasher.getNodeCost(element);
    for (SingleChildDescriptor childDescriptor : descriptor.getSingleChildDescriptors()) {
        final Couple<Integer> childHashResult = computeHash(childDescriptor, fragment, hasher);
        hash = hash * 31 + childHashResult.first;
        cost += childHashResult.second;
    }
    for (MultiChildDescriptor childDescriptor : descriptor.getMultiChildDescriptors()) {
        final Couple<Integer> childHashResult = computeHash(childDescriptor, fragment, hasher);
        hash = hash * 31 + childHashResult.first;
        cost += childHashResult.second;
    }
    for (Object constant : descriptor.getConstants()) {
        final int constantHash = constant != null ? constant.hashCode() : 0;
        hash = hash * 31 + constantHash;
    }
    for (PsiElement[] codeBlock : descriptor.getCodeBlocks()) {
        final List<PsiElement> filteredBlock = filter(codeBlock, ssrHasher);
        final TreeHashResult childHashResult = hashCodeBlock(filteredBlock, fragment, hasher);
        hash = hash * 31 + childHashResult.getHash();
        cost += childHashResult.getCost();
    }
    if (myCallback != null) {
        myCallback.add(hash, cost, fragment);
    }
    return new TreeHashResult(hash, cost, fragment);
}
Also used : PsiFragment(com.intellij.dupLocator.util.PsiFragment) MultiChildDescriptor(com.intellij.dupLocator.equivalence.MultiChildDescriptor) SingleChildDescriptor(com.intellij.dupLocator.equivalence.SingleChildDescriptor) PsiElement(com.intellij.psi.PsiElement)

Example 2 with MultiChildDescriptor

use of com.intellij.dupLocator.equivalence.MultiChildDescriptor in project intellij-community by JetBrains.

the class DuplocatorUtil method getOnlyChildFromDescriptor.

@Nullable
private static PsiElement getOnlyChildFromDescriptor(EquivalenceDescriptor equivalenceDescriptor, NodeFilter filter) {
    if (!equivalenceDescriptor.getConstants().isEmpty()) {
        return null;
    }
    final List<SingleChildDescriptor> singleChildren = equivalenceDescriptor.getSingleChildDescriptors();
    final List<MultiChildDescriptor> multiChildren = equivalenceDescriptor.getMultiChildDescriptors();
    final List<PsiElement[]> codeBlocks = equivalenceDescriptor.getCodeBlocks();
    if (singleChildren.size() + multiChildren.size() + codeBlocks.size() != 1) {
        return null;
    }
    if (!singleChildren.isEmpty()) {
        final SingleChildDescriptor descriptor = singleChildren.get(0);
        final PsiElement child = descriptor.getElement();
        if (child != null) {
            final SingleChildDescriptor.MyType type = descriptor.getType();
            if (type == SingleChildDescriptor.MyType.DEFAULT) {
                return child;
            } else if (type == SingleChildDescriptor.MyType.CHILDREN || type == SingleChildDescriptor.MyType.CHILDREN_IN_ANY_ORDER) {
                return getOnlyChild(child, filter);
            }
        }
    } else if (!multiChildren.isEmpty()) {
        final MultiChildDescriptor descriptor = multiChildren.get(0);
        final PsiElement[] children = descriptor.getElements();
        if (children != null && children.length == 1 && descriptor.getType() != MultiChildDescriptor.MyType.OPTIONALLY) {
            return children[0];
        }
    } else if (!codeBlocks.isEmpty()) {
        final PsiElement[] codeBlock = codeBlocks.get(0);
        if (codeBlock != null && codeBlock.length == 1) {
            return codeBlock[0];
        }
    }
    return null;
}
Also used : MultiChildDescriptor(com.intellij.dupLocator.equivalence.MultiChildDescriptor) SingleChildDescriptor(com.intellij.dupLocator.equivalence.SingleChildDescriptor) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with MultiChildDescriptor

use of com.intellij.dupLocator.equivalence.MultiChildDescriptor in project intellij-community by JetBrains.

the class DuplocatorUtil method match.

public static boolean match(@NotNull EquivalenceDescriptor descriptor1, @NotNull EquivalenceDescriptor descriptor2, @NotNull AbstractMatchingVisitor g, @NotNull Set<PsiElementRole> skippedRoles, @Nullable DuplicatesProfile profile) {
    if (descriptor1.getSingleChildDescriptors().size() != descriptor2.getSingleChildDescriptors().size()) {
        return false;
    }
    if (descriptor1.getMultiChildDescriptors().size() != descriptor2.getMultiChildDescriptors().size()) {
        return false;
    }
    if (descriptor1.getCodeBlocks().size() != descriptor2.getCodeBlocks().size()) {
        return false;
    }
    if (descriptor1.getConstants().size() != descriptor2.getConstants().size()) {
        return false;
    }
    for (int i = 0, n = descriptor1.getConstants().size(); i < n; i++) {
        Object childDescriptor1 = descriptor1.getConstants().get(i);
        Object childDescriptor2 = descriptor2.getConstants().get(i);
        if (!Comparing.equal(childDescriptor1, childDescriptor2)) {
            return false;
        }
    }
    for (int i = 0, n = descriptor1.getSingleChildDescriptors().size(); i < n; i++) {
        SingleChildDescriptor childDescriptor1 = descriptor1.getSingleChildDescriptors().get(i);
        SingleChildDescriptor childDescriptor2 = descriptor2.getSingleChildDescriptors().get(i);
        if (!match(childDescriptor1, childDescriptor2, g, skippedRoles, profile)) {
            return false;
        }
    }
    for (int i = 0, n = descriptor1.getMultiChildDescriptors().size(); i < n; i++) {
        MultiChildDescriptor childDescriptor1 = descriptor1.getMultiChildDescriptors().get(i);
        MultiChildDescriptor childDescriptor2 = descriptor2.getMultiChildDescriptors().get(i);
        if (!match(childDescriptor1, childDescriptor2, g)) {
            return false;
        }
    }
    for (int i = 0, n = descriptor1.getCodeBlocks().size(); i < n; i++) {
        final PsiElement[] codeBlock1 = descriptor1.getCodeBlocks().get(i);
        final PsiElement[] codeBlock2 = descriptor2.getCodeBlocks().get(i);
        if (!g.matchSequentially(codeBlock1, codeBlock2)) {
            return false;
        }
    }
    return true;
}
Also used : MultiChildDescriptor(com.intellij.dupLocator.equivalence.MultiChildDescriptor) SingleChildDescriptor(com.intellij.dupLocator.equivalence.SingleChildDescriptor) PsiElement(com.intellij.psi.PsiElement)

Aggregations

MultiChildDescriptor (com.intellij.dupLocator.equivalence.MultiChildDescriptor)3 SingleChildDescriptor (com.intellij.dupLocator.equivalence.SingleChildDescriptor)3 PsiElement (com.intellij.psi.PsiElement)3 PsiFragment (com.intellij.dupLocator.util.PsiFragment)1 Nullable (org.jetbrains.annotations.Nullable)1