Beispiel #1
0
  private static void createValueRootNode(
      NullAnalysisResult result,
      SliceRootNode oldRoot,
      final Map<SliceNode, NullAnalysisResult> map,
      SliceRootNode root,
      SliceNode oldRootStart,
      String nodeName,
      final int group) {
    Collection<PsiElement> groupedByValue = result.groupedByValue[group];
    if (groupedByValue.isEmpty()) {
      return;
    }
    SliceLeafValueClassNode valueRoot =
        new SliceLeafValueClassNode(root.getProject(), root, nodeName);
    root.myCachedChildren.add(valueRoot);

    Set<PsiElement> uniqueValues =
        new THashSet<PsiElement>(groupedByValue, SliceLeafAnalyzer.LEAF_ELEMENT_EQUALITY);
    for (final PsiElement expression : uniqueValues) {
      SliceNode newRoot =
          SliceLeafAnalyzer.filterTree(
              oldRootStart,
              new NullableFunction<SliceNode, SliceNode>() {
                @Override
                public SliceNode fun(SliceNode oldNode) {
                  if (oldNode.getDuplicate() != null) {
                    return null;
                  }

                  for (PsiElement nullSuspect : group(oldNode, map, group)) {
                    if (PsiEquivalenceUtil.areElementsEquivalent(nullSuspect, expression)) {
                      return oldNode.copy();
                    }
                  }
                  return null;
                }
              },
              new PairProcessor<SliceNode, List<SliceNode>>() {
                @Override
                public boolean process(SliceNode node, List<SliceNode> children) {
                  if (!children.isEmpty()) return true;
                  PsiElement element = node.getValue().getElement();
                  if (element == null) return false;
                  return PsiEquivalenceUtil.areElementsEquivalent(
                      element, expression); // leaf can be there only if it's filtering expression
                }
              });
      valueRoot.myCachedChildren.add(
          new SliceLeafValueRootNode(
              root.getProject(),
              expression,
              valueRoot,
              Collections.singletonList(newRoot),
              oldRoot.getValue().params));
    }
  }
Beispiel #2
0
  private static void groupByNullness(
      NullAnalysisResult result,
      SliceRootNode oldRoot,
      final Map<SliceNode, NullAnalysisResult> map) {
    SliceRootNode root = createNewTree(result, oldRoot, map);

    SliceUsage rootUsage = oldRoot.myCachedChildren.get(0).getValue();
    SliceManager.getInstance(root.getProject())
        .createToolWindow(
            true,
            root,
            true,
            SliceManager.getElementDescription(
                null, rootUsage.getElement(), " Grouped by Nullness"));
  }
Beispiel #3
0
  public static SliceRootNode createNewTree(
      NullAnalysisResult result,
      SliceRootNode oldRoot,
      final Map<SliceNode, NullAnalysisResult> map) {
    SliceRootNode root = oldRoot.copy();
    assert oldRoot.myCachedChildren.size() == 1;
    SliceNode oldRootStart = oldRoot.myCachedChildren.get(0);
    root.setChanged();
    root.targetEqualUsages.clear();
    root.myCachedChildren = new ArrayList<SliceNode>();

    createValueRootNode(
        result, oldRoot, map, root, oldRootStart, "Null Values", NullAnalysisResult.NULLS);
    createValueRootNode(
        result, oldRoot, map, root, oldRootStart, "NotNull Values", NullAnalysisResult.NOT_NULLS);
    createValueRootNode(
        result, oldRoot, map, root, oldRootStart, "Other Values", NullAnalysisResult.UNKNOWNS);

    return root;
  }
  public void testGroupByValuesCorrectLeaves() throws Exception {
    SliceTreeStructure treeStructure = configureTree("DuplicateLeaves");
    SliceRootNode root = (SliceRootNode) treeStructure.getRootElement();
    Map<SliceNode, Collection<PsiElement>> map = SliceLeafAnalyzer.createMap();
    Collection<PsiElement> leaves = SliceLeafAnalyzer.calcLeafExpressions(root, treeStructure, map);
    assertNotNull(leaves);
    assertEquals(1, leaves.size());
    PsiElement leaf = leaves.iterator().next();
    assertTrue(leaf instanceof PsiLiteralExpression);
    assertEquals("\"oo\"", leaf.getText());

    SliceRootNode newRoot = SliceLeafAnalyzer.createTreeGroupedByValues(leaves, root, map);
    Collection<? extends AbstractTreeNode> children = newRoot.getChildren();
    assertEquals(1, children.size());
    SliceNode child = (SliceNode) children.iterator().next();
    assertTrue(child instanceof SliceLeafValueRootNode);

    children = child.getChildren();
    assertEquals(1, children.size());
    child = (SliceNode) children.iterator().next();
    assertTrue(child.getValue().getElement() instanceof PsiField);

    children = child.getChildren();
    assertEquals(1, children.size());
    child = (SliceNode) children.iterator().next();
    assertTrue(child.getValue().getElement() instanceof PsiReferenceExpression);

    children = child.getChildren();
    assertEquals(1, children.size());
    child = (SliceNode) children.iterator().next();
    assertTrue(child.getValue().getElement() instanceof PsiReferenceExpression);

    children = child.getChildren();
    assertEquals(1, children.size());
    child = (SliceNode) children.iterator().next();
    assertTrue(child.getValue().getElement() instanceof PsiLiteralExpression);
    assertEquals(child.getValue().getElement(), leaf);
  }
  private static boolean processValuesFlownTo(
      @NotNull final PsiExpression argument,
      PsiElement scope,
      @NotNull final Processor<PsiExpression> processor) {
    SliceAnalysisParams params = new SliceAnalysisParams();
    params.dataFlowToThis = true;
    params.scope = new AnalysisScope(new LocalSearchScope(scope), argument.getProject());

    SliceRootNode rootNode =
        new SliceRootNode(
            scope.getProject(), new DuplicateMap(), SliceManager.createRootUsage(argument, params));

    Collection<? extends AbstractTreeNode> children =
        rootNode.getChildren().iterator().next().getChildren();
    for (AbstractTreeNode child : children) {
      SliceUsage usage = (SliceUsage) child.getValue();
      PsiElement element = usage.getElement();
      if (element instanceof PsiExpression && !processor.process((PsiExpression) element))
        return false;
    }

    return !children.isEmpty();
  }
Beispiel #6
0
  public static void startAnalyzeNullness(
      final AbstractTreeStructure treeStructure, final Runnable finish) {
    final SliceRootNode root = (SliceRootNode) treeStructure.getRootElement();
    final Ref<NullAnalysisResult> leafExpressions = Ref.create(null);
    final Map<SliceNode, NullAnalysisResult> map = createMap();

    ProgressManager.getInstance()
        .run(
            new Task.Backgroundable(
                root.getProject(),
                "Expanding all nodes... (may very well take the whole day)",
                true) {
              @Override
              public void run(@NotNull final ProgressIndicator indicator) {
                NullAnalysisResult l = calcNullableLeaves(root, treeStructure, map);
                leafExpressions.set(l);
              }

              @Override
              public void onCancel() {
                finish.run();
              }

              @Override
              public void onSuccess() {
                try {
                  NullAnalysisResult leaves = leafExpressions.get();
                  if (leaves == null) return; // cancelled

                  groupByNullness(leaves, root, map);
                } finally {
                  finish.run();
                }
              }
            });
  }