TreeHashResult (@NotNull PsiElement root, PsiFragment upper, NodeSpecificHasher hasher) { if (myForIndexing) { return TreeHashingUtils.computeElementHashForIndexing(this, myCallBack, root, upper, hasher); } final List<PsiElement> children = hasher.getNodeChildren(root); final int size = children.size(); final int[] childHashes = new int[size]; final int[] childCosts = new int[size]; final PsiFragment fragment = buildFragment(hasher, root, getCost(root)); if (upper != null) { fragment.setParent(upper); } if (size == 0 && !(root instanceof LeafElement)) { // contains only whitespaces and other unmeaning children return new TreeHashResult(0, hasher.getNodeCost(root), fragment); } for (int i = 0; i < size; i++) { final TreeHashResult res = this.hash(children.get(i), fragment, hasher); childHashes[i] = res.getHash(); childCosts[i] = res.getCost(); } final int c = hasher.getNodeCost(root) + AbstractTreeHasher.vector(childCosts); final int h1 = hasher.getNodeHash(root); final int discardCost = getDiscardCost(root); for (int i = 0; i < size; i++) { if (childCosts[i] <= discardCost && ignoreChildHash(children.get(i))) { childHashes[i] = 0; } } int h = h1 + AbstractTreeHasher.vector(childHashes); if (shouldBeAnonymized(root, (NodeSpecificHasherBase)hasher)) { h = 0; } if (myCallBack != null) { myCallBack.add(h, c, fragment); } return new TreeHashResult(h, c, fragment); }