Ejemplo n.º 1
0
  /**
   * We want to treat comments specially in a way to skip comment prefix on line indent calculation.
   *
   * <p>Example:
   *
   * <pre>
   *   if (true) {
   *     int i1;
   * //    int i2;
   *     int i3;
   *   }
   * </pre>
   *
   * We want to use 'int i2;' start offset as the third line indent (though it has non-white space
   * comment prefix (//) at the first column.
   *
   * <p>This method tries to parse comment prefix for the language implied by the given comment
   * type. It uses {@link #NO_COMMENT_INFO_MARKER} as an indicator that that information is
   * unavailable
   *
   * @param commentType target comment type
   * @return prefix of the comment denoted by the given type if any; {@link #NO_COMMENT_INFO_MARKER}
   *     otherwise
   */
  @NotNull
  private static String getCommentPrefix(@NotNull IElementType commentType) {
    Commenter c = LanguageCommenters.INSTANCE.forLanguage(commentType.getLanguage());
    if (!(c instanceof CodeDocumentationAwareCommenter)) {
      COMMENT_PREFIXES.put(commentType, NO_COMMENT_INFO_MARKER);
      return NO_COMMENT_INFO_MARKER;
    }
    CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter) c;

    IElementType lineCommentType = commenter.getLineCommentTokenType();
    String lineCommentPrefix = commenter.getLineCommentPrefix();
    if (lineCommentType != null) {
      COMMENT_PREFIXES.put(
          lineCommentType, lineCommentPrefix == null ? NO_COMMENT_INFO_MARKER : lineCommentPrefix);
    }

    IElementType blockCommentType = commenter.getBlockCommentTokenType();
    String blockCommentPrefix = commenter.getBlockCommentPrefix();
    if (blockCommentType != null) {
      COMMENT_PREFIXES.put(
          blockCommentType,
          blockCommentPrefix == null ? NO_COMMENT_INFO_MARKER : blockCommentPrefix);
    }

    IElementType docCommentType = commenter.getDocumentationCommentTokenType();
    String docCommentPrefix = commenter.getDocumentationCommentPrefix();
    if (docCommentType != null) {
      COMMENT_PREFIXES.put(
          docCommentType, docCommentPrefix == null ? NO_COMMENT_INFO_MARKER : docCommentPrefix);
    }

    COMMENT_PREFIXES.putIfAbsent(commentType, NO_COMMENT_INFO_MARKER);
    return COMMENT_PREFIXES.get(commentType);
  }
Ejemplo n.º 2
0
  public static boolean isCommentTextElement(final PsiElement element) {
    final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(element.getLanguage());
    if (commenter instanceof CodeDocumentationAwareCommenterEx) {
      final CodeDocumentationAwareCommenterEx commenterEx =
          (CodeDocumentationAwareCommenterEx) commenter;
      if (commenterEx.isDocumentationCommentText(element)) return true;
      if (element instanceof PsiComment && commenterEx.isDocumentationComment((PsiComment) element))
        return false;
    }

    return isComment(element);
  }
  @Override
  public Result preprocessEnter(
      @NotNull final PsiFile file,
      @NotNull final Editor editor,
      @NotNull final Ref<Integer> caretOffsetRef,
      @NotNull final Ref<Integer> caretAdvance,
      @NotNull final DataContext dataContext,
      final EditorActionHandler originalHandler) {
    int caretOffset = caretOffsetRef.get().intValue();
    PsiElement psiAtOffset = file.findElementAt(caretOffset);
    if (psiAtOffset != null && psiAtOffset.getTextOffset() < caretOffset) {
      ASTNode token = psiAtOffset.getNode();
      Document document = editor.getDocument();
      CharSequence text = document.getText();
      final Language language = psiAtOffset.getLanguage();
      final Commenter languageCommenter = LanguageCommenters.INSTANCE.forLanguage(language);
      final CodeDocumentationAwareCommenter commenter =
          languageCommenter instanceof CodeDocumentationAwareCommenter
              ? (CodeDocumentationAwareCommenter) languageCommenter
              : null;
      if (commenter != null && token.getElementType() == commenter.getLineCommentTokenType()) {
        final int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t");

        if (offset < document.getTextLength() && text.charAt(offset) != '\n') {
          String prefix = commenter.getLineCommentPrefix();
          assert prefix != null : "Line Comment type is set but Line Comment Prefix is null!";
          if (!StringUtil.startsWith(text, offset, prefix)) {
            if (text.charAt(caretOffset) != ' ' && !prefix.endsWith(" ")) {
              prefix += " ";
            }
            document.insertString(caretOffset, prefix);
            return Result.Default;
          } else {
            int afterPrefix = offset + prefix.length();
            if (afterPrefix < document.getTextLength() && text.charAt(afterPrefix) != ' ') {
              document.insertString(afterPrefix, " ");
              // caretAdvance.set(0);
            }
            caretOffsetRef.set(offset);
          }
          return Result.Default;
        }
      }
    }
    return Result.Continue;
  }
Ejemplo n.º 4
0
  private static void process(
      @NotNull final PsiFile file,
      @NotNull final Editor editor,
      @NotNull final Project project,
      int offset) {
    PsiElement elementAtOffset = file.findElementAt(offset);
    if (elementAtOffset == null) {
      return;
    }

    Language language = PsiUtilCore.getLanguageAtOffset(file, offset);
    final CodeDocumentationProvider docProvider;
    final DocumentationProvider langDocumentationProvider =
        LanguageDocumentation.INSTANCE.forLanguage(language);
    if (langDocumentationProvider instanceof CompositeDocumentationProvider) {
      docProvider =
          ((CompositeDocumentationProvider) langDocumentationProvider)
              .getFirstCodeDocumentationProvider();
    } else if (langDocumentationProvider instanceof CodeDocumentationProvider) {
      docProvider = (CodeDocumentationProvider) langDocumentationProvider;
    } else {
      docProvider = null;
    }
    if (docProvider == null) {
      return;
    }

    final Pair<PsiElement, PsiComment> pair = docProvider.parseContext(elementAtOffset);
    if (pair == null) {
      return;
    }

    Commenter c = LanguageCommenters.INSTANCE.forLanguage(language);
    if (!(c instanceof CodeDocumentationAwareCommenter)) {
      return;
    }
    final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter) c;
    final Runnable task;
    if (pair.second == null || pair.second.getTextRange().isEmpty()) {
      task =
          new Runnable() {
            @Override
            public void run() {
              generateComment(pair.first, editor, docProvider, commenter, project);
            }
          };
    } else {
      final DocCommentFixer fixer = DocCommentFixer.EXTENSION.forLanguage(language);
      if (fixer == null) {
        return;
      } else {
        task =
            new Runnable() {
              @Override
              public void run() {
                fixer.fixComment(project, editor, pair.second);
              }
            };
      }
    }
    final Runnable command =
        new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication().runWriteAction(task);
          }
        };
    CommandProcessor.getInstance().executeCommand(project, command, "Fix documentation", null);
  }