示例#1
0
 /**
  * Tries to calculate given line's indent column assuming that there might be a comment at the
  * given indent offset (see {@link #getCommentPrefix(IElementType)}).
  *
  * @param line target line
  * @param indentOffset start indent offset to use for the given line
  * @param lineEndOffset given line's end offset
  * @param fallbackColumn column to return if it's not possible to apply comment-specific indent
  *     calculation rules
  * @return given line's indent column to use
  */
 private int calcIndent(int line, int indentOffset, int lineEndOffset, int fallbackColumn) {
   final HighlighterIterator it = myEditor.getHighlighter().createIterator(indentOffset);
   IElementType tokenType = it.getTokenType();
   Language language = tokenType.getLanguage();
   TokenSet comments = myComments.get(language);
   if (comments == null) {
     ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
     if (definition != null) {
       comments = definition.getCommentTokens();
     }
     if (comments == null) {
       return fallbackColumn;
     } else {
       myComments.put(language, comments);
     }
   }
   if (comments.contains(tokenType) && indentOffset == it.getStart()) {
     String prefix = COMMENT_PREFIXES.get(tokenType);
     if (prefix == null) {
       prefix = getCommentPrefix(tokenType);
     }
     if (!NO_COMMENT_INFO_MARKER.equals(prefix)) {
       final int indentInsideCommentOffset =
           CharArrayUtil.shiftForward(
               myChars, indentOffset + prefix.length(), lineEndOffset, " \t");
       if (indentInsideCommentOffset < lineEndOffset) {
         int indent = myEditor.calcColumnNumber(indentInsideCommentOffset, line);
         indentAfterUncomment.put(line, indent - prefix.length());
         return indent;
       }
     }
   }
   return fallbackColumn;
 }
  private static boolean isCommentComplete(
      PsiComment comment, CodeDocumentationAwareCommenter commenter, Editor editor) {
    for (CommentCompleteHandler handler :
        Extensions.getExtensions(CommentCompleteHandler.EP_NAME)) {
      if (handler.isApplicable(comment, commenter)) {
        return handler.isCommentComplete(comment, commenter, editor);
      }
    }

    String commentText = comment.getText();
    final boolean docComment = isDocComment(comment, commenter);
    final String expectedCommentEnd =
        docComment ? commenter.getDocumentationCommentSuffix() : commenter.getBlockCommentSuffix();
    if (!commentText.endsWith(expectedCommentEnd)) return false;

    final PsiFile containingFile = comment.getContainingFile();
    final Language language = containingFile.getLanguage();
    ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
    if (parserDefinition == null) {
      return true;
    }
    Lexer lexer = parserDefinition.createLexer(containingFile.getProject());
    final String commentPrefix =
        docComment ? commenter.getDocumentationCommentPrefix() : commenter.getBlockCommentPrefix();
    lexer.start(
        commentText, commentPrefix == null ? 0 : commentPrefix.length(), commentText.length());
    QuoteHandler fileTypeHandler = TypedHandler.getQuoteHandler(containingFile, editor);
    JavaLikeQuoteHandler javaLikeQuoteHandler =
        fileTypeHandler instanceof JavaLikeQuoteHandler
            ? (JavaLikeQuoteHandler) fileTypeHandler
            : null;

    while (true) {
      IElementType tokenType = lexer.getTokenType();
      if (tokenType == null) {
        return false;
      }

      if (javaLikeQuoteHandler != null
          && javaLikeQuoteHandler.getStringTokenTypes() != null
          && javaLikeQuoteHandler.getStringTokenTypes().contains(tokenType)) {
        String text = commentText.substring(lexer.getTokenStart(), lexer.getTokenEnd());
        int endOffset = comment.getTextRange().getEndOffset();

        if (text.endsWith(expectedCommentEnd)
            && endOffset < containingFile.getTextLength()
            && containingFile.getText().charAt(endOffset) == '\n') {
          return true;
        }
      }
      if (tokenType == commenter.getDocumentationCommentTokenType()
          || tokenType == commenter.getBlockCommentTokenType()) {
        return false;
      }
      if (tokenType == commenter.getLineCommentTokenType()
          && lexer.getTokenText().contains(commentPrefix)) {
        return false;
      }
      if (lexer.getTokenEnd() == commentText.length()) {
        if (tokenType == commenter.getLineCommentTokenType()) {
          String prefix = commenter.getLineCommentPrefix();
          lexer.start(
              commentText,
              lexer.getTokenStart() + (prefix == null ? 0 : prefix.length()),
              commentText.length());
          lexer.advance();
          continue;
        } else if (isInvalidPsi(comment)) {
          return false;
        }
        return true;
      }
      lexer.advance();
    }
  }