@NotNull public static NullAnalysisResult calcNullableLeaves( @NotNull final SliceNode root, @NotNull AbstractTreeStructure treeStructure, final Map<SliceNode, NullAnalysisResult> map) { final SliceLeafAnalyzer.SliceNodeGuide guide = new SliceLeafAnalyzer.SliceNodeGuide(treeStructure); WalkingState<SliceNode> walkingState = new WalkingState<SliceNode>(guide) { @Override public void visit(@NotNull SliceNode element) { element.calculateDupNode(); node(element, map).clear(); SliceNode duplicate = element.getDuplicate(); if (duplicate != null) { node(element, map).add(node(duplicate, map)); } else { SliceUsage sliceUsage = element.getValue(); final PsiElement value = sliceUsage.getElement(); Nullness nullness = ApplicationManager.getApplication() .runReadAction( new Computable<Nullness>() { @Override public Nullness compute() { return checkNullness(value); } }); if (nullness == Nullness.NULLABLE) { group(element, map, NullAnalysisResult.NULLS).add(value); } else if (nullness == Nullness.NOT_NULL) { group(element, map, NullAnalysisResult.NOT_NULLS).add(value); } else { Collection<? extends AbstractTreeNode> children = element.getChildren(); if (children.isEmpty()) { group(element, map, NullAnalysisResult.UNKNOWNS).add(value); } super.visit(element); } } } @Override public void elementFinished(@NotNull SliceNode element) { SliceNode parent = guide.getParent(element); if (parent != null) { node(parent, map).add(node(element, map)); } } }; walkingState.visit(root); return node(root, map); }
@NotNull public static Collection<PsiElement> calcLeafExpressions( @NotNull final SliceNode root, @NotNull AbstractTreeStructure treeStructure, @NotNull final Map<SliceNode, Collection<PsiElement>> map) { final SliceNodeGuide guide = new SliceNodeGuide(treeStructure); WalkingState<SliceNode> walkingState = new WalkingState<SliceNode>(guide) { @Override public void visit(@NotNull SliceNode element) { element.calculateDupNode(); node(element, map).clear(); SliceNode duplicate = element.getDuplicate(); if (duplicate != null) { node(element, map).addAll(node(duplicate, map)); } else { final SliceUsage sliceUsage = element.getValue(); Collection<? extends AbstractTreeNode> children = element.getChildren(); if (children.isEmpty()) { PsiElement value = ApplicationManager.getApplication() .runReadAction( new Computable<PsiElement>() { @Override public PsiElement compute() { return sliceUsage.indexNesting == 0 ? sliceUsage.getElement() : null; } }); if (value != null) { node(element, map).addAll(ContainerUtil.singleton(value, LEAF_ELEMENT_EQUALITY)); } } super.visit(element); } } @Override public void elementFinished(@NotNull SliceNode element) { SliceNode parent = guide.getParent(element); if (parent != null) { node(parent, map).addAll(node(element, map)); } } }; walkingState.visit(root); return node(root, map); }