/** * 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 void initState(IElementType root, PsiBuilder builder, ErrorState state) { PsiFile file = builder.getUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY); state.completionState = file == null ? null : file.getUserData(COMPLETION_STATE_KEY); Language language = file == null ? root.getLanguage() : file.getLanguage(); state.caseSensitive = language.isCaseSensitive(); ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language); if (parserDefinition != null) { state.commentTokens = parserDefinition.getCommentTokens(); state.whitespaceTokens = parserDefinition.getWhitespaceTokens(); } PairedBraceMatcher matcher = LanguageBraceMatching.INSTANCE.forLanguage(language); state.braces = matcher == null ? null : matcher.getPairs(); if (state.braces != null && state.braces.length == 0) state.braces = null; }
public static boolean isCommentToken( @NotNull IElementType tokenType, @NotNull LanguageVersion languageVersion) { final Language language = tokenType.getLanguage(); if (language != languageVersion.getLanguage()) { return false; } boolean inComments = false; final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language); if (parserDefinition != null) { final TokenSet commentTokens = parserDefinition.getCommentTokens(languageVersion); if (commentTokens.contains(tokenType)) { inComments = true; } } return inComments; }
@NotNull @Override public PsiElement createDummyHolder( @NotNull final String text, @NotNull final IElementType type, @Nullable final PsiElement context) { final DummyHolder result = DummyHolderFactory.createHolder(myManager, context); final FileElement holder = result.getTreeElement(); final Language language = type.getLanguage(); final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language); assert parserDefinition != null : "No parser definition for language " + language; final Project project = myManager.getProject(); final Lexer lexer = parserDefinition.createLexer(project); final PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, holder, lexer, language, text); final ASTNode node = parserDefinition.createParser(project).parse(type, builder); holder.rawAddChildren((TreeElement) node); final PsiElement psi = node.getPsi(); assert psi != null : text; return psi; }
public PsiBuilder createBuilder(final Lexer lexer, final Language lang, final CharSequence seq) { ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang); return new PsiBuilderImpl( lexer, parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), seq); }
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(); } }
@SuppressWarnings("ConstantConditions") private static PsiBuilderImpl createBuilder(CharSequence text) { ParserDefinition parserDefinition = new ParserDefinition() { @NotNull @Override public Lexer createLexer(Project project) { return new MyTestLexer(); } @Override public PsiParser createParser(Project project) { return null; } @Override public IFileElementType getFileNodeType() { return null; } @NotNull @Override public TokenSet getWhitespaceTokens() { return WHITESPACE_SET; } @NotNull @Override public TokenSet getCommentTokens() { return COMMENT_SET; } @NotNull @Override public TokenSet getStringLiteralElements() { return null; } @NotNull @Override public PsiElement createElement(ASTNode node) { return null; } @Override public PsiFile createFile(FileViewProvider viewProvider) { return null; } @Override public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { return null; } }; return new PsiBuilderImpl( getProject(), null, parserDefinition, parserDefinition.createLexer(getProject()), null, text, null, null); }