use of com.intellij.dupLocator.equivalence.SingleChildDescriptor 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);
}
use of com.intellij.dupLocator.equivalence.SingleChildDescriptor 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;
}
use of com.intellij.dupLocator.equivalence.SingleChildDescriptor 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;
}
Aggregations