com.puppycrawl.tools.checkstyle.utils.ParserUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checkstyle Show documentation
Show all versions of checkstyle Show documentation
Checkstyle is a development tool to help programmers write Java code
that adheres to a coding standard
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2021 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.utils;
import java.util.AbstractMap;
import java.util.Map;
import org.antlr.v4.runtime.CommonToken;
import com.puppycrawl.tools.checkstyle.DetailAstImpl;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
/**
* Contains utility methods for parser to use while creating ast.
*/
public final class ParserUtil {
/** Symbols with which javadoc starts. */
private static final String JAVADOC_START = "/**";
/** Symbols with which multiple comment starts. */
private static final String BLOCK_MULTIPLE_COMMENT_BEGIN = "/*";
/** Symbols with which multiple comment ends. */
private static final String BLOCK_MULTIPLE_COMMENT_END = "*/";
/** Stop instances being created. **/
private ParserUtil() {
}
/**
* Create block comment from string content.
*
* @param content comment content.
* @return DetailAST block comment
*/
public static DetailAST createBlockCommentNode(String content) {
final DetailAstImpl blockCommentBegin = new DetailAstImpl();
blockCommentBegin.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
blockCommentBegin.setText(BLOCK_MULTIPLE_COMMENT_BEGIN);
blockCommentBegin.setLineNo(0);
blockCommentBegin.setColumnNo(-JAVADOC_START.length());
final DetailAstImpl commentContent = new DetailAstImpl();
commentContent.setType(TokenTypes.COMMENT_CONTENT);
commentContent.setText("*" + content);
commentContent.setLineNo(0);
// javadoc should starts at 0 column, so COMMENT_CONTENT node
// that contains javadoc identifier has -1 column
commentContent.setColumnNo(-1);
final DetailAstImpl blockCommentEnd = new DetailAstImpl();
blockCommentEnd.setType(TokenTypes.BLOCK_COMMENT_END);
blockCommentEnd.setText(BLOCK_MULTIPLE_COMMENT_END);
blockCommentBegin.setFirstChild(commentContent);
commentContent.setNextSibling(blockCommentEnd);
return blockCommentBegin;
}
/**
* Create block comment from token.
*
* @param token Token object.
* @return DetailAST with BLOCK_COMMENT type.
*/
public static DetailAST createBlockCommentNode(CommonToken token) {
final DetailAstImpl blockComment = new DetailAstImpl();
blockComment.initialize(TokenTypes.BLOCK_COMMENT_BEGIN, BLOCK_MULTIPLE_COMMENT_BEGIN);
blockComment.setColumnNo(token.getCharPositionInLine());
blockComment.setLineNo(token.getLine());
final DetailAstImpl blockCommentContent = new DetailAstImpl();
blockCommentContent.setType(TokenTypes.COMMENT_CONTENT);
// Add length of '/*'
blockCommentContent.setColumnNo(token.getCharPositionInLine() + 2);
blockCommentContent.setLineNo(token.getLine());
blockCommentContent.setText(token.getText());
final DetailAstImpl blockCommentClose = new DetailAstImpl();
blockCommentClose.initialize(TokenTypes.BLOCK_COMMENT_END, BLOCK_MULTIPLE_COMMENT_END);
final Map.Entry linesColumns = countLinesColumns(
token.getText(), token.getLine(), token.getCharPositionInLine() + 1);
blockCommentClose.setLineNo(linesColumns.getKey());
blockCommentClose.setColumnNo(linesColumns.getValue());
blockComment.addChild(blockCommentContent);
blockComment.addChild(blockCommentClose);
return blockComment;
}
/**
* Count lines and columns (in last line) in text.
*
* @param text String.
* @param initialLinesCnt initial value of lines counter.
* @param initialColumnsCnt initial value of columns counter.
* @return entry(pair), key is line counter, value is column counter.
*/
private static Map.Entry countLinesColumns(
String text, int initialLinesCnt, int initialColumnsCnt) {
int lines = initialLinesCnt;
int columns = initialColumnsCnt;
boolean foundCr = false;
for (char c : text.toCharArray()) {
if (c == '\n') {
foundCr = false;
lines++;
columns = 0;
}
else {
if (foundCr) {
foundCr = false;
lines++;
columns = 0;
}
if (c == '\r') {
foundCr = true;
}
columns++;
}
}
if (foundCr) {
lines++;
columns = 0;
}
return new AbstractMap.SimpleEntry<>(lines, columns);
}
}