Java 类com.intellij.psi.tree.IReparseableElementType 实例源码

项目:intellij-ce-playground    文件:BlockSupportImpl.java   
/**
 * 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;
}
项目:tools-idea    文件:BlockSupportImpl.java   
@Override
@NotNull
public DiffLog reparseRange(@NotNull final PsiFile file,
                            TextRange changedPsiRange,
                            @NotNull final CharSequence newFileText,
                            @NotNull final ProgressIndicator indicator) {
  final PsiFileImpl fileImpl = (PsiFileImpl)file;
  Project project = fileImpl.getProject();
  final FileElement treeFileElement = fileImpl.getTreeElement();
  final CharTable charTable = treeFileElement.getCharTable();


  final int textLength = newFileText.length();
  int lengthShift = textLength - treeFileElement.getTextLength();

  if (treeFileElement.getElementType() instanceof ITemplateDataElementType || isTooDeep(file)) {
    // unable to perform incremental reparse for template data in JSP, or in exceptionally deep trees
    return makeFullParse(treeFileElement, newFileText, textLength, fileImpl, indicator);
  }

  final ASTNode leafAtStart = treeFileElement.findLeafElementAt(Math.max(0, changedPsiRange.getStartOffset() - 1));
  final ASTNode leafAtEnd = treeFileElement.findLeafElementAt(changedPsiRange.getEndOffset());
  ASTNode node = leafAtStart != null && leafAtEnd != null ? TreeUtil.findCommonParent(leafAtStart, leafAtEnd) : treeFileElement;
  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())) {
        final int start = textRange.getStartOffset();
        final int end = start + textRange.getLength() + lengthShift;
        assertFileLength(file, newFileText, node, elementType, start, end);

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

        if (reparseable.isParsable(newTextStr, baseLanguage, project)) {
          ASTNode chameleon = reparseable.createNode(newTextStr);
          if (chameleon != null) {
            DummyHolder holder = DummyHolderFactory.createHolder(fileImpl.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 mergeTrees(fileImpl, node, chameleon, indicator);
          }
        }
      }
    }
    node = node.getTreeParent();
  }

  return makeFullParse(node, newFileText, textLength, fileImpl, indicator);
}
项目:consulo    文件:BlockSupportImpl.java   
/**
 * Find ast node that could be reparsed incrementally
 *
 * @return Pair (target reparseable node, new replacement node)
 * or {@code null} if can't parse incrementally.
 */
@Nullable
public static Couple<ASTNode> findReparseableRoots(@Nonnull PsiFileImpl file, @Nonnull FileASTNode oldFileNode, @Nonnull TextRange changedPsiRange, @Nonnull CharSequence newFileText) {
  Project project = file.getProject();
  final FileElement fileElement = (FileElement)oldFileNode;
  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(file, 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;
}