Example #1
0
 /** Clear the JTree. */
 private void clearTree() {
   // expand.clear();
   TreeUtil.removeAllChildren(getRootNode());
   initRootNode();
   getTreeModel().setRoot(getRootNode());
   // getTreeModel().reload();
 }
  public static void replaceLastWhiteSpace(
      final ASTNode astNode, final String whiteSpace, final TextRange textRange) {
    ASTNode lastWS = TreeUtil.findLastLeaf(astNode);
    if (lastWS == null) {
      return;
    }
    if (lastWS.getElementType() != TokenType.WHITE_SPACE) {
      lastWS = null;
    }
    if (lastWS != null && !lastWS.getTextRange().equals(textRange)) {
      return;
    }
    if (whiteSpace.isEmpty() && lastWS == null) {
      return;
    }
    if (lastWS != null && whiteSpace.isEmpty()) {
      lastWS.getTreeParent().removeRange(lastWS, null);
      return;
    }

    LeafElement whiteSpaceElement = ASTFactory.whitespace(whiteSpace);

    if (lastWS == null) {
      astNode.addChild(whiteSpaceElement, null);
    } else {
      ASTNode treeParent = lastWS.getTreeParent();
      treeParent.replaceChild(lastWS, whiteSpaceElement);
    }
  }
Example #3
0
  @Override
  public void adoptElement(SceneElement elem) {
    if (!(elem instanceof NenyaImageSceneElement
        || elem instanceof NenyaTileSceneElement
        || elem instanceof NenyaComponentSceneElement)) {
      enableEditor(false);
      return;
    }

    DefaultComboBoxModel dcm = (DefaultComboBoxModel) itemList.getModel();

    // Important: Work on a copy, not on the original. Otherwise we mess up the undomanager
    sceneElement = elem.copy();

    if ((sceneElement instanceof NenyaImageSceneElement) && !locked) {
      dcm.removeAllElements();
      String[] tmp = ((NenyaImageSceneElement) sceneElement).getPath();
      dcm.addElement(tmp[tmp.length - 1]);
    }
    if ((sceneElement instanceof NenyaTileSceneElement) && !locked) {
      dcm.removeAllElements();
      dcm.addElement(((NenyaTileSceneElement) sceneElement).getTileName());
    }
    if ((sceneElement instanceof NenyaComponentSceneElement) && !locked) {
      dcm.removeAllElements();
      NenyaComponentItem[] ni = ((NenyaComponentSceneElement) sceneElement).getComponents();
      for (NenyaComponentItem element : ni) {
        dcm.addElement(element);
      }
    }

    try {
      ClassedItem[] cols = null;
      if (elem instanceof NenyaTileSceneElement)
        cols = ((NenyaTileSceneElement) elem).getColorList();
      if (elem instanceof NenyaImageSceneElement)
        cols = ((NenyaImageSceneElement) elem).getColorList();
      if (elem instanceof NenyaComponentSceneElement) {
        NenyaComponentItem nci = (NenyaComponentItem) dcm.getSelectedItem();
        cols = nci.getColorList();
      }
      Vector<TreePath> collect = new Vector<TreePath>();
      TreeNode root = (TreeNode) colors.getModel().getRoot();
      for (ClassedItem col : cols) {
        String[] tmp = {root.toString(), col.getClassName(), col.getItemName()};
        collect.add(TreeUtil.findPath(root, tmp));
      }
      TreePath[] path = collect.toArray(new TreePath[0]);
      colors.getSelectionModel().setSelectionPaths(path);
    } catch (Exception e) {
      // Either the tree is filtered away or the selected item is not colorized.
    }

    enableEditor(true);
    itemList.setEnabled(elem instanceof NenyaComponentSceneElement);
  }
 public static <T> void diffTrees(
     @NotNull final ASTNode oldRoot,
     @NotNull final DiffTreeChangeBuilder<ASTNode, T> builder,
     @NotNull final ShallowNodeComparator<ASTNode, T> comparator,
     @NotNull final FlyweightCapableTreeStructure<T> newTreeStructure,
     @NotNull ProgressIndicator indicator) {
   TreeUtil.ensureParsedRecursivelyCheckingProgress(oldRoot, indicator);
   DiffTree.diff(
       createInterruptibleASTStructure(oldRoot, indicator), newTreeStructure, comparator, builder);
 }
Example #5
0
  public StubTree calcStubTree() {
    FileElement fileElement = calcTreeElement();
    synchronized (myStubFromTreeLock) {
      SoftReference<StubTree> ref = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE);
      StubTree tree = SoftReference.dereference(ref);

      if (tree == null) {
        ApplicationManager.getApplication().assertReadAccessAllowed();
        IElementType contentElementType = getContentElementType();
        if (!(contentElementType instanceof IStubFileElementType)) {
          VirtualFile vFile = getVirtualFile();
          String message =
              "ContentElementType: "
                  + contentElementType
                  + "; file: "
                  + this
                  + "\n\t"
                  + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = "
                  + Boolean.TRUE.equals(getUserData(BUILDING_STUB))
                  + "\n\t"
                  + "getTreeElement() = "
                  + getTreeElement()
                  + "\n\t"
                  + "vFile instanceof VirtualFileWithId = "
                  + (vFile instanceof VirtualFileWithId)
                  + "\n\t"
                  + "StubUpdatingIndex.canHaveStub(vFile) = "
                  + StubTreeLoader.getInstance().canHaveStub(vFile);
          rebuildStub();
          throw new AssertionError(message);
        }

        StubElement currentStubTree =
            ((IStubFileElementType) contentElementType).getBuilder().buildStubTree(this);
        if (currentStubTree == null) {
          throw new AssertionError(
              "Stub tree wasn't built for " + contentElementType + "; file: " + this);
        }

        tree = new StubTree((PsiFileStub) currentStubTree);
        tree.setDebugInfo("created in calcStubTree");
        try {
          TreeUtil.bindStubsToTree(this, tree);
        } catch (TreeUtil.StubBindingException e) {
          rebuildStub();
          throw new RuntimeException("Stub and PSI element type mismatch in " + getName(), e);
        }

        fileElement.putUserData(STUB_TREE_IN_PARSED_TREE, new SoftReference<StubTree>(tree));
      }

      return tree;
    }
  }
Example #6
0
 /** Refresh the expansion (recursive function) */
 public void expandRefresh(TreeTableNode moved) {
   if (moved instanceof TaskNode) {
     Task movedTask = (Task) moved.getUserObject();
     if (movedTask.getExpand()) {
       getTreeTable().getTree().expandPath(TreeUtil.createPath(moved));
     }
     for (int i = 0; i < moved.getChildCount(); i++) {
       expandRefresh(moved.getChildAt(i));
     }
   }
 }
Example #7
0
 public void treeExpanded(TreeExpansionEvent event) {
   TreePath treePath = event.getPath();
   if (treePath != null) {
     TreeUINode targetNode = (TreeUINode) treePath.getLastPathComponent();
     if (!targetNode.isChildrenLoaded()) {
       String targetPathText = TreeUtil.makePathText(treePath);
       String absPathText = PathUtil.makeChildPath(_tree.getRelativeRoot(), targetPathText);
       expandNode(targetNode, absPathText);
     }
   }
 }
  @Override
  public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
    boolean needToAddNewline = false;
    if (first == last && first.getElementType() == DOC_TAG) {
      if (anchor == null) {
        anchor = getLastChildNode(); // this is a '*/'
        final ASTNode prevBeforeWS =
            TreeUtil.skipElementsBack(anchor.getTreePrev(), ElementType.JAVA_WHITESPACE_BIT_SET);
        if (prevBeforeWS != null) {
          anchor = prevBeforeWS;
          before = Boolean.FALSE;
        } else {
          before = Boolean.TRUE;
        }
        needToAddNewline = true;
      }
      if (anchor.getElementType() != DOC_TAG) {
        final CharTable charTable = SharedImplUtil.findCharTableByTree(this);
        final TreeElement newLine =
            Factory.createSingleLeafElement(DOC_COMMENT_DATA, "\n", 0, 1, charTable, getManager());
        final TreeElement leadingAsterisk =
            Factory.createSingleLeafElement(
                DOC_COMMENT_LEADING_ASTERISKS, "*", 0, 1, charTable, getManager());
        final TreeElement commentData =
            Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", 0, 1, charTable, getManager());
        final TreeElement indentWS =
            Factory.createSingleLeafElement(DOC_COMMENT_DATA, " ", 0, 1, charTable, getManager());
        newLine.getTreeParent().addChild(indentWS);
        newLine.getTreeParent().addChild(leadingAsterisk);
        newLine.getTreeParent().addChild(commentData);
        super.addInternal(newLine, commentData, anchor, Boolean.FALSE);

        anchor = commentData;
        before = Boolean.FALSE;
      } else {
        needToAddNewline = true;
      }
    }
    if (before) anchor.getTreeParent().addChildren(first, last.getTreeNext(), anchor);
    else anchor.getTreeParent().addChildren(first, last.getTreeNext(), anchor.getTreeNext());

    if (needToAddNewline) {
      if (first.getTreePrev() != null && first.getTreePrev().getElementType() == DOC_TAG) {
        addNewLineToTag((CompositeElement) first.getTreePrev(), getProject());
      }
      if (first.getTreeNext() != null && first.getTreeNext().getElementType() == DOC_TAG) {
        addNewLineToTag((CompositeElement) first, getProject());
      } else {
        removeEndingAsterisksFromTag((CompositeElement) first);
      }
    }
    return first;
  }
  private void insertOuters(TreeElement root, Lexer lexer, final CharTable table) {
    TreePatcher patcher = TREE_PATCHER.forLanguage(root.getPsi().getLanguage());

    int treeOffset = 0;
    LeafElement leaf = TreeUtil.findFirstLeaf(root);
    while (lexer.getTokenType() != null) {
      IElementType tt = lexer.getTokenType();
      if (tt != myTemplateElementType) {
        while (leaf != null && treeOffset < lexer.getTokenStart()) {
          treeOffset += leaf.getTextLength();
          if (treeOffset > lexer.getTokenStart()) {
            leaf =
                patcher.split(
                    leaf, leaf.getTextLength() - (treeOffset - lexer.getTokenStart()), table);
            treeOffset = lexer.getTokenStart();
          }
          leaf = (LeafElement) TreeUtil.nextLeaf(leaf);
        }

        if (leaf == null) break;

        final OuterLanguageElementImpl newLeaf =
            createOuterLanguageElement(lexer, table, myOuterElementType);
        patcher.insert(leaf.getTreeParent(), leaf, newLeaf);
        leaf.getTreeParent().subtreeChanged();
        leaf = newLeaf;
      }
      lexer.advance();
    }

    if (lexer.getTokenType() != null) {
      assert lexer.getTokenType() != myTemplateElementType;
      final OuterLanguageElementImpl newLeaf =
          createOuterLanguageElement(lexer, table, myOuterElementType);
      ((CompositeElement) root).rawAddChildren(newLeaf);
      ((CompositeElement) root).subtreeChanged();
    }
  }
  private void ensureParsed() {
    if (!ourParsingAllowed) {
      LOG.error("Parsing not allowed!!!");
    }
    CharSequence text = myText();
    if (text == null) return;

    if (TreeUtil.getFileElement(this) == null) {
      LOG.error("Chameleons must not be parsed till they're in file tree: " + this);
    }

    ApplicationManager.getApplication().assertReadAccessAllowed();

    DebugUtil.startPsiModification("lazy-parsing");
    try {
      ILazyParseableElementType type = (ILazyParseableElementType) getElementType();
      ASTNode parsedNode = type.parseContents(this);

      if (parsedNode == null && text.length() > 0) {
        CharSequence diagText = ApplicationManager.getApplication().isInternal() ? text : "";
        LOG.error(
            "No parse for a non-empty string: "
                + diagText
                + "; type="
                + LogUtil.objectAndClass(type));
      }

      synchronized (lock) {
        if (myText == null) return;
        if (rawFirstChild() != null) {
          LOG.error("Reentrant parsing?");
        }

        myText = null;

        if (parsedNode == null) return;
        super.rawAddChildrenWithoutNotifications((TreeElement) parsedNode);
      }
    } finally {
      DebugUtil.finishPsiModification();
    }

    if (!Boolean.TRUE.equals(ourSuppressEagerPsiCreation.get())) {
      // create PSI all at once, to reduce contention of PsiLock in CompositeElement.getPsi()
      // create PSI outside the 'lock' since this method grabs PSI_LOCK and deadlock is possible
      // when someone else locks in the other order.
      createAllChildrenPsiIfNecessary();
    }
  }
  @Override
  public ASTNode parseContents(ASTNode chameleon) {
    final CharTable table = SharedImplUtil.findCharTableByTree(chameleon);
    final FileElement treeElement =
        new DummyHolder(((TreeElement) chameleon).getManager(), null, table).getTreeElement();
    final PsiFile file = (PsiFile) TreeUtil.getFileElement((TreeElement) chameleon).getPsi();
    PsiFile originalFile = file.getOriginalFile();

    final TemplateLanguageFileViewProvider viewProvider =
        (TemplateLanguageFileViewProvider) originalFile.getViewProvider();

    final Language language = getTemplateFileLanguage(viewProvider);
    final CharSequence chars = chameleon.getChars();

    final PsiFile templateFile = createTemplateFile(file, language, chars, viewProvider);

    final TreeElement parsed = ((PsiFileImpl) templateFile).calcTreeElement();
    Lexer langLexer =
        LanguageParserDefinitions.INSTANCE.forLanguage(language).createLexer(file.getProject());
    final Lexer lexer =
        new MergingLexerAdapter(
            new TemplateBlackAndWhiteLexer(
                createBaseLexer(viewProvider),
                langLexer,
                myTemplateElementType,
                myOuterElementType),
            TokenSet.create(myTemplateElementType, myOuterElementType));
    lexer.start(chars);
    insertOuters(parsed, lexer, table);

    if (parsed != null) {
      final TreeElement element = parsed.getFirstChildNode();
      if (element != null) {
        ((CompositeElement) parsed).rawRemoveAllChildren();
        treeElement.rawAddChildren(element);
      }
    }

    treeElement.subtreeChanged();
    TreeElement childNode = treeElement.getFirstChildNode();

    DebugUtil.checkTreeStructure(parsed);
    DebugUtil.checkTreeStructure(treeElement);
    DebugUtil.checkTreeStructure(chameleon);
    DebugUtil.checkTreeStructure(file.getNode());
    DebugUtil.checkTreeStructure(originalFile.getNode());

    return childNode;
  }
Example #12
0
 @Override
 public void applyPreservingExpansionState(Task rootTask, Predicate<Task> callable) {
   MutableTreeTableNode rootNode = getNode(rootTask);
   List<MutableTreeTableNode> subtree = TreeUtil.collectSubtree(rootNode);
   Collections.reverse(subtree);
   LinkedHashMap<Task, Boolean> states = Maps.newLinkedHashMap();
   for (MutableTreeTableNode node : subtree) {
     Task t = (Task) node.getUserObject();
     states.put(t, t.getExpand());
   }
   callable.apply(rootTask);
   for (Map.Entry<Task, Boolean> state : states.entrySet()) {
     setExpanded(state.getKey(), state.getValue());
   }
 }
 private static void removeEndingAsterisksFromTag(CompositeElement tag) {
   ASTNode current = tag.getLastChildNode();
   while (current != null && current.getElementType() == DOC_COMMENT_DATA) {
     current = current.getTreePrev();
   }
   if (current != null && current.getElementType() == DOC_COMMENT_LEADING_ASTERISKS) {
     final ASTNode prevWhiteSpace =
         TreeUtil.skipElementsBack(current.getTreePrev(), ElementType.JAVA_WHITESPACE_BIT_SET);
     ASTNode toBeDeleted = prevWhiteSpace.getTreeNext();
     while (toBeDeleted != null) {
       ASTNode next = toBeDeleted.getTreeNext();
       tag.deleteChildInternal(toBeDeleted);
       toBeDeleted = next;
     }
   }
 }
  public ASTNode findChildByRole(int role) {
    LOG.assertTrue(ChildRole.isUnique(role));
    switch (role) {
      default:
        return null;

      case ChildRole.PACKAGE_KEYWORD:
        return findChildByType(JavaTokenType.PACKAGE_KEYWORD);

      case ChildRole.PACKAGE_REFERENCE:
        return findChildByType(JavaElementType.JAVA_CODE_REFERENCE);

      case ChildRole.CLOSING_SEMICOLON:
        return TreeUtil.findChildBackward(this, JavaTokenType.SEMICOLON);

      case ChildRole.MODIFIER_LIST:
        return findChildByType(JavaElementType.MODIFIER_LIST);
    }
  }
  @Nullable
  public static ASTNode getPreviousNonWhitespaceLeaf(@Nullable ASTNode node) {
    if (node == null) return null;
    ASTNode treePrev = node.getTreePrev();
    if (treePrev != null) {
      ASTNode candidate = TreeUtil.getLastChild(treePrev);
      if (candidate != null && !isWhitespaceOrEmpty(candidate)) {
        return candidate;
      } else {
        return getPreviousNonWhitespaceLeaf(candidate);
      }
    }
    final ASTNode treeParent = node.getTreeParent();

    if (treeParent == null || treeParent.getTreeParent() == null) {
      return null;
    } else {
      return getPreviousNonWhitespaceLeaf(treeParent);
    }
  }
Example #16
0
 private void onTaskSelectionChanged(List<Task> tasks) {
   isOnTaskSelectionEventProcessing = true;
   List<TreePath> paths = new ArrayList<TreePath>();
   for (Task t : tasks) {
     if (t == null) {
       GPLogger.getLogger(getClass())
           .log(
               Level.SEVERE,
               "Found null task in the selection. Full selection=" + tasks,
               new NullPointerException());
       continue;
     }
     MutableTreeTableNode treeNode = getNode(t);
     assert treeNode != null : "Failed to find tree node for task=" + t;
     paths.add(TreeUtil.createPath(treeNode));
   }
   getTreeTable()
       .getTreeSelectionModel()
       .setSelectionPaths(paths.toArray(new TreePath[paths.size()]));
   isOnTaskSelectionEventProcessing = false;
 }
  public TreeElement process(TreeElement element, boolean addImports, boolean uncompleteCode) {
    IElementType elementType = element.getElementType();
    if (elementType == JavaElementType.JAVA_CODE_REFERENCE
        || elementType == JavaElementType.REFERENCE_EXPRESSION) {
      final IElementType parentElementType = element.getTreeParent().getElementType();
      if (elementType == JavaElementType.JAVA_CODE_REFERENCE
          || parentElementType == JavaElementType.REFERENCE_EXPRESSION
          || parentElementType == JavaElementType.METHOD_REF_EXPRESSION
          || uncompleteCode) {
        final PsiJavaCodeReferenceElement ref =
            (PsiJavaCodeReferenceElement) SourceTreeToPsiMap.treeElementToPsi(element);
        final PsiReferenceParameterList parameterList = ref.getParameterList();
        if (parameterList != null) {
          final PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements();
          for (PsiTypeElement typeParameter : typeParameters) {
            process(
                (TreeElement) SourceTreeToPsiMap.psiElementToTree(typeParameter),
                addImports,
                uncompleteCode);
          }
        }

        boolean rightKind = true;
        if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
          int kind = ((PsiJavaCodeReferenceElementImpl) element).getKind();
          rightKind =
              kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND
                  || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND;
        }

        if (rightKind) {
          boolean isInsideDocComment =
              TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
          boolean isShort = !((SourceJavaCodeReference) element).isQualified();
          if (!makeFQ(isInsideDocComment)) {
            if (isShort) return element; // short name already, no need to change
          }
          PsiElement refElement;
          if (!uncompleteCode) {
            refElement = ref.resolve();
          } else {
            PsiResolveHelper helper =
                JavaPsiFacade.getInstance(element.getManager().getProject()).getResolveHelper();
            refElement =
                helper.resolveReferencedClass(
                    ((SourceJavaCodeReference) element).getClassNameText(),
                    SourceTreeToPsiMap.treeElementToPsi(element));
          }
          if (refElement instanceof PsiClass) {
            if (makeFQ(isInsideDocComment)) {
              String qName = ((PsiClass) refElement).getQualifiedName();
              if (qName == null) return element;
              PsiImportHolder file =
                  (PsiImportHolder)
                      SourceTreeToPsiMap.treeElementToPsi(element).getContainingFile();
              if (file instanceof PsiJavaFile
                  && ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) {
                if (isShort) return element;
                return (TreeElement)
                    makeShortReference(
                        (CompositeElement) element, (PsiClass) refElement, addImports);
              }
              if (file instanceof PsiJavaFile) {
                String thisPackageName = ((PsiJavaFile) file).getPackageName();
                if (ImportHelper.hasPackage(qName, thisPackageName)) {
                  if (!isShort) {
                    return (TreeElement)
                        makeShortReference(
                            (CompositeElement) element, (PsiClass) refElement, addImports);
                  }
                }
              }
              return (TreeElement) replaceReferenceWithFQ(element, (PsiClass) refElement);
            } else {
              int oldLength = element.getTextLength();
              TreeElement treeElement =
                  (TreeElement)
                      makeShortReference(
                          (CompositeElement) element, (PsiClass) refElement, addImports);
              if (treeElement.getTextLength() == oldLength
                  && ((PsiClass) refElement).getContainingClass() != null) {
                PsiElement qualifier = ref.getQualifier();
                if (qualifier instanceof PsiJavaCodeReferenceElement
                    && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) {
                  process((TreeElement) qualifier.getNode(), addImports, uncompleteCode);
                }
              }
              return treeElement;
            }
          }
        }
      }
    }

    for (TreeElement child = element.getFirstChildNode();
        child != null;
        child = child.getTreeNext()) {
      child = process(child, addImports, uncompleteCode);
    }

    return element;
  }
Example #18
0
 public static void main(String[] args) {
   TreeNode node = TreeUtil.createTree(15);
   inOrderTraversal(node);
   System.out.println();
   inOrder(node);
 }
  /**
   * This method searches ast node that could be reparsed incrementally and returns pair of target
   * reparseable node and new replacement node. Returns null if there is no any chance to make
   * incremental parsing.
   */
  @Nullable
  public Couple<ASTNode> findReparseableRoots(
      @NotNull PsiFileImpl file,
      @NotNull TextRange changedPsiRange,
      @NotNull CharSequence newFileText) {
    Project project = file.getProject();
    final FileElement fileElement = file.getTreeElement();
    final CharTable charTable = fileElement.getCharTable();
    int lengthShift = newFileText.length() - fileElement.getTextLength();

    if (fileElement.getElementType() instanceof ITemplateDataElementType || isTooDeep(file)) {
      // unable to perform incremental reparse for template data in JSP, or in exceptionally deep
      // trees
      return null;
    }

    final ASTNode leafAtStart =
        fileElement.findLeafElementAt(Math.max(0, changedPsiRange.getStartOffset() - 1));
    final ASTNode leafAtEnd =
        fileElement.findLeafElementAt(
            Math.min(changedPsiRange.getEndOffset(), fileElement.getTextLength() - 1));
    ASTNode node =
        leafAtStart != null && leafAtEnd != null
            ? TreeUtil.findCommonParent(leafAtStart, leafAtEnd)
            : fileElement;
    Language baseLanguage = file.getViewProvider().getBaseLanguage();

    while (node != null && !(node instanceof FileElement)) {
      IElementType elementType = node.getElementType();
      if (elementType instanceof IReparseableElementType) {
        final TextRange textRange = node.getTextRange();
        final IReparseableElementType reparseable = (IReparseableElementType) elementType;

        if (baseLanguage.isKindOf(reparseable.getLanguage())
            && textRange.getLength() + lengthShift > 0) {
          final int start = textRange.getStartOffset();
          final int end = start + textRange.getLength() + lengthShift;
          if (end > newFileText.length()) {
            reportInconsistentLength(file, newFileText, node, start, end);
            break;
          }

          CharSequence newTextStr = newFileText.subSequence(start, end);

          if (reparseable.isParsable(node.getTreeParent(), newTextStr, baseLanguage, project)) {
            ASTNode chameleon = reparseable.createNode(newTextStr);
            if (chameleon != null) {
              DummyHolder holder =
                  DummyHolderFactory.createHolder(
                      file.getManager(), null, node.getPsi(), charTable);
              holder.getTreeElement().rawAddChildren((TreeElement) chameleon);

              if (holder.getTextLength() != newTextStr.length()) {
                String details =
                    ApplicationManager.getApplication().isInternal()
                        ? "text=" + newTextStr + "; treeText=" + holder.getText() + ";"
                        : "";
                LOG.error("Inconsistent reparse: " + details + " type=" + elementType);
              }

              return Couple.of(node, chameleon);
            }
          }
        }
      }
      node = node.getTreeParent();
    }
    return null;
  }
Example #20
0
  @Override
  public ASTNode process(
      @NotNull ASTNode element,
      boolean addImports,
      boolean incompleteCode,
      boolean useFqInJavadoc,
      boolean useFqInCode) {
    IElementType elementType = element.getElementType();
    if ((elementType == JavaElementType.JAVA_CODE_REFERENCE
            || elementType == JavaElementType.REFERENCE_EXPRESSION)
        && !isAnnotated(element)) {
      IElementType parentType = element.getTreeParent().getElementType();
      if (elementType == JavaElementType.JAVA_CODE_REFERENCE
          || incompleteCode
          || parentType == JavaElementType.REFERENCE_EXPRESSION
          || parentType == JavaElementType.METHOD_REF_EXPRESSION) {
        PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) element.getPsi();

        PsiReferenceParameterList parameterList = ref.getParameterList();
        if (parameterList != null) {
          PsiTypeElement[] typeParameters = parameterList.getTypeParameterElements();
          for (PsiTypeElement typeParameter : typeParameters) {
            process(
                typeParameter.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
          }
        }

        boolean rightKind = true;
        if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
          PsiJavaCodeReferenceElementImpl impl = (PsiJavaCodeReferenceElementImpl) element;
          int kind = impl.getKind(impl.getContainingFile());
          rightKind =
              kind == PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND
                  || kind == PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND;
        }

        if (rightKind) {
          // annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations())
          // so they should be processed first
          List<PsiAnnotation> annotations =
              PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class);
          for (PsiAnnotation annotation : annotations) {
            process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
          }

          boolean isInsideDocComment =
              TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
          boolean isShort = !ref.isQualified();
          if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) {
            if (isShort) return element; // short name already, no need to change
          }

          PsiElement refElement;
          if (!incompleteCode) {
            refElement = ref.resolve();
          } else {
            PsiResolveHelper helper =
                JavaPsiFacade.getInstance(ref.getManager().getProject()).getResolveHelper();
            final SourceJavaCodeReference reference = (SourceJavaCodeReference) element;
            refElement = helper.resolveReferencedClass(reference.getClassNameText(), ref);
          }

          if (refElement instanceof PsiClass) {
            PsiClass psiClass = (PsiClass) refElement;
            if (isInsideDocComment ? useFqInJavadoc : useFqInCode) {
              String qName = psiClass.getQualifiedName();
              if (qName == null) return element;

              PsiFile file = ref.getContainingFile();
              if (file instanceof PsiJavaFile) {
                if (ImportHelper.isImplicitlyImported(qName, (PsiJavaFile) file)) {
                  if (isShort) return element;
                  return makeShortReference((CompositeElement) element, psiClass, addImports);
                }

                String thisPackageName = ((PsiJavaFile) file).getPackageName();
                if (ImportHelper.hasPackage(qName, thisPackageName)) {
                  if (!isShort) {
                    return makeShortReference((CompositeElement) element, psiClass, addImports);
                  }
                }
              }

              return replaceReferenceWithFQ(element, psiClass);
            } else {
              int oldLength = element.getTextLength();
              ASTNode treeElement =
                  makeShortReference((CompositeElement) element, psiClass, addImports);
              if (treeElement.getTextLength() == oldLength
                  && psiClass.getContainingClass() != null) {
                PsiElement qualifier = ref.getQualifier();
                if (qualifier instanceof PsiJavaCodeReferenceElement
                    && ((PsiJavaCodeReferenceElement) qualifier).resolve() instanceof PsiClass) {
                  process(
                      qualifier.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
                }
              }
              return treeElement;
            }
          }
        }
      }
    }

    for (ASTNode child = element.getFirstChildNode(); child != null; child = child.getTreeNext()) {
      //noinspection AssignmentToForLoopParameter
      child = process(child, addImports, incompleteCode, useFqInJavadoc, useFqInCode);
    }

    return element;
  }
  private static void createActionsMap(
      final List<ASTNode> astNodes,
      final FileViewProvider provider,
      final TreeSet<PostprocessFormattingTask> rangesToProcess) {
    final Set<ASTNode> nodesToProcess = new HashSet<ASTNode>(astNodes);
    final Document document = provider.getDocument();
    for (final ASTNode node : astNodes) {
      nodesToProcess.remove(node);
      final FileElement fileElement = TreeUtil.getFileElement((TreeElement) node);
      if (fileElement == null || ((PsiFile) fileElement.getPsi()).getViewProvider() != provider)
        continue;
      final boolean isGenerated = CodeEditUtil.isNodeGenerated(node);

      ((TreeElement) node)
          .acceptTree(
              new RecursiveTreeElementVisitor() {
                boolean inGeneratedContext = !isGenerated;

                protected boolean visitNode(TreeElement element) {
                  if (nodesToProcess.contains(element)) return false;
                  if (CodeEditUtil.isPostponedFormattingDisabled(element)) return false;

                  final boolean currentNodeGenerated = CodeEditUtil.isNodeGenerated(element);
                  CodeEditUtil.setNodeGenerated(element, false);
                  if (currentNodeGenerated && !inGeneratedContext) {
                    rangesToProcess.add(
                        new ReformatTask(document.createRangeMarker(element.getTextRange())));
                    inGeneratedContext = true;
                  }
                  if (!currentNodeGenerated && inGeneratedContext) {
                    if (element.getElementType() == TokenType.WHITE_SPACE) return false;
                    final int oldIndent = CodeEditUtil.getOldIndentation(element);
                    LOG.assertTrue(
                        oldIndent >= 0,
                        "for not generated items old indentation must be defined: element "
                            + element);
                    rangesToProcess.add(
                        new ReindentTask(
                            document.createRangeMarker(element.getTextRange()), oldIndent));
                    inGeneratedContext = false;
                  }
                  return true;
                }

                @Override
                public void visitComposite(CompositeElement composite) {
                  boolean oldGeneratedContext = inGeneratedContext;
                  super.visitComposite(composite);
                  inGeneratedContext = oldGeneratedContext;
                }

                @Override
                public void visitLeaf(LeafElement leaf) {
                  boolean oldGeneratedContext = inGeneratedContext;
                  super.visitLeaf(leaf);
                  inGeneratedContext = oldGeneratedContext;
                }
              });

      CodeEditUtil.enablePostponedFormattingInTree(node);
    }
  }
Example #22
0
 /** @return an ArrayList with all tasks. */
 List<MutableTreeTableNode> getAllTasks() {
   return TreeUtil.collectSubtree(getRootNode());
 }
  private static void createActionsMap(
      @NotNull List<ASTNode> astNodes,
      @NotNull FileViewProvider provider,
      @NotNull final TreeSet<PostprocessFormattingTask> rangesToProcess) {
    final Set<ASTNode> nodesToProcess = new HashSet<ASTNode>(astNodes);
    final Document document = provider.getDocument();
    if (document == null) {
      return;
    }
    for (final ASTNode node : astNodes) {
      nodesToProcess.remove(node);
      final FileElement fileElement = TreeUtil.getFileElement((TreeElement) node);
      if (fileElement == null || ((PsiFile) fileElement.getPsi()).getViewProvider() != provider)
        continue;
      final boolean isGenerated = CodeEditUtil.isNodeGenerated(node);

      ((TreeElement) node)
          .acceptTree(
              new RecursiveTreeElementVisitor() {
                boolean inGeneratedContext = !isGenerated;

                @Override
                protected boolean visitNode(TreeElement element) {
                  if (nodesToProcess.contains(element)) return false;

                  final boolean currentNodeGenerated = CodeEditUtil.isNodeGenerated(element);
                  CodeEditUtil.setNodeGenerated(element, false);
                  if (currentNodeGenerated && !inGeneratedContext) {
                    rangesToProcess.add(
                        new ReformatTask(document.createRangeMarker(element.getTextRange())));
                    inGeneratedContext = true;
                  }
                  if (!currentNodeGenerated && inGeneratedContext) {
                    if (element.getElementType() == TokenType.WHITE_SPACE) return false;
                    final int oldIndent = CodeEditUtil.getOldIndentation(element);
                    CodeEditUtil.setOldIndentation(element, -1);
                    LOG.assertTrue(
                        oldIndent >= 0,
                        "for not generated items old indentation must be defined: element "
                            + element);
                    for (TextRange indentRange : getEnabledRanges(element.getPsi())) {
                      rangesToProcess.add(
                          new ReindentTask(document.createRangeMarker(indentRange), oldIndent));
                    }
                    inGeneratedContext = false;
                  }
                  return true;
                }

                private Iterable<TextRange> getEnabledRanges(@NotNull PsiElement element) {
                  List<TextRange> disabledRanges = new ArrayList<TextRange>();
                  for (DisabledIndentRangesProvider rangesProvider :
                      DisabledIndentRangesProvider.EP_NAME.getExtensions()) {
                    Collection<TextRange> providedDisabledRanges =
                        rangesProvider.getDisabledIndentRanges(element);
                    if (providedDisabledRanges != null) {
                      disabledRanges.addAll(providedDisabledRanges);
                    }
                  }
                  return TextRangeUtil.excludeRanges(element.getTextRange(), disabledRanges);
                }

                @Override
                public void visitComposite(CompositeElement composite) {
                  boolean oldGeneratedContext = inGeneratedContext;
                  super.visitComposite(composite);
                  inGeneratedContext = oldGeneratedContext;
                }

                @Override
                public void visitLeaf(LeafElement leaf) {
                  boolean oldGeneratedContext = inGeneratedContext;
                  super.visitLeaf(leaf);
                  inGeneratedContext = oldGeneratedContext;
                }
              });
    }
  }