| package com.intellij.dupLocator.treeHash; |
| |
| import com.intellij.dupLocator.NodeSpecificHasher; |
| import com.intellij.dupLocator.util.PsiFragment; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.impl.source.tree.LeafElement; |
| |
| import java.util.List; |
| |
| /** |
| * Created by Maxim.Mossienko on 2/17/14. |
| */ |
| public class TreeHashingUtils { |
| protected static TreeHashResult hashCodeBlockForIndexing(AbstractTreeHasher treeHasher, FragmentsCollector callBack, |
| List<? extends PsiElement> statements, |
| PsiFragment upper, |
| NodeSpecificHasher hasher) { |
| final int statementsSize = statements.size(); |
| |
| if (statementsSize > 0) { |
| final PsiFragment fragment = treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1); |
| fragment.setParent(upper); |
| int cost = 0; |
| int hash = 0; |
| for (PsiElement statement : statements) { |
| final TreeHashResult res = treeHasher.hash(statement, null, hasher); |
| hash = hash* 31 + res.getHash(); |
| cost += res.getCost(); |
| } |
| |
| TreeHashResult result = new TreeHashResult(hash, cost, treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1)); |
| if (callBack != null && statementsSize > 1) callBack.add(hash, cost, fragment); |
| return result; |
| } |
| return new TreeHashResult(1, 0, treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1)); |
| } |
| static TreeHashResult computeElementHashForIndexing(AbstractTreeHasher base, |
| FragmentsCollector callBack, |
| PsiElement root, |
| PsiFragment upper, |
| NodeSpecificHasher hasher |
| ) { |
| final List<PsiElement> children = hasher.getNodeChildren(root); |
| final PsiFragment fragment = base.buildFragment(hasher, root, base.getCost(root)); |
| |
| if (upper != null) { |
| fragment.setParent(upper); |
| } |
| |
| final int size = children.size(); |
| if (size == 0 && !(root instanceof LeafElement)) { |
| // contains only whitespaces and other unmeaning children |
| return new TreeHashResult(0, hasher.getNodeCost(root), fragment); |
| } |
| |
| final int discardCost = base.getDiscardCost(root); |
| int c = hasher.getNodeCost(root); |
| int h = hasher.getNodeHash(root); |
| |
| for (int i = 0; i < size; i++) { |
| PsiElement child = children.get(i); |
| final TreeHashResult res = base.hash(child, fragment, hasher); |
| int childCost = res.getCost(); |
| c += childCost; |
| if (childCost > discardCost || !base.ignoreChildHash(child)) { |
| h += res.getHash(); |
| } |
| } |
| |
| if (base.shouldAnonymize(root, hasher)) { |
| h = 0; |
| } |
| |
| if (callBack != null) { |
| callBack.add(h, c, fragment); |
| } |
| |
| return new TreeHashResult(h, c, fragment); |
| } |
| } |