Issue #49. Added support of single-line and block comments

This commit is contained in:
Baratali Izmailov 2014-07-12 23:56:38 +04:00 committed by Roman Ivanov
parent 59aa66c3cc
commit a24df47caf
16 changed files with 1310 additions and 122 deletions

View File

@ -499,6 +499,14 @@
</goals>
</execution>
</executions>
<configuration>
<configLocation>checkstyle_checks.xml</configLocation>
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
<suppressionsLocation>suppressions.xml</suppressionsLocation>
<headerLocation>java.header</headerLocation>
<propertyExpansion>checkstyle.importcontrol.file=import-control.xml</propertyExpansion>
<enableFilesSummary>false</enableFilesSummary>
</configuration>
</plugin>
<plugin>

View File

@ -21,15 +21,19 @@ package com.puppycrawl.tools.checkstyle;
import java.io.File;
import java.io.Reader;
import java.io.StringReader;
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import antlr.CommonHiddenStreamToken;
import antlr.RecognitionException;
import antlr.Token;
import antlr.TokenStreamException;
import antlr.TokenStreamHiddenTokenFilter;
import antlr.TokenStreamRecognitionException;
@ -61,16 +65,42 @@ import com.puppycrawl.tools.checkstyle.grammars.GeneratedJavaRecognizer;
public final class TreeWalker
extends AbstractFileSetCheck
{
/**
* State of AST.
* Indicates whether tree contains certain nodes.
*/
private static enum AstState {
/**
* Ordinary tree.
*/
ORDINARY,
/**
* AST contains comment nodes.
*/
WITH_COMMENTS
}
/** default distance between tab stops */
private static final int DEFAULT_TAB_WIDTH = 8;
/** maps from token name to checks */
private final Multimap<String, Check> mTokenToChecks =
/** maps from token name to ordinary checks */
private final Multimap<String, Check> mTokenToOrdinaryChecks =
HashMultimap.create();
/** all the registered checks */
private final Set<Check> mAllChecks = Sets.newHashSet();
/** maps from token name to comment checks */
private final Multimap<String, Check> mTokenToCommentChecks =
HashMultimap.create();
/** registered ordinary checks, that don't use comment nodes */
private final Set<Check> mOrdinaryChecks = Sets.newHashSet();
/** registered comment checks */
private final Set<Check> mCommentChecks = Sets.newHashSet();
/** the distance between tab stops */
private int mTabWidth = DEFAULT_TAB_WIDTH;
/** cache file **/
private PropertyCacheFile mCache = new PropertyCacheFile(null, null);
@ -83,11 +113,6 @@ public final class TreeWalker
/** a factory for creating submodules (i.e. the Checks) */
private ModuleFactory mModuleFactory;
/** controls whether we should use recursive or iterative
* algorithm for tree processing.
*/
private final boolean mRecursive;
/** logger for debug purpose */
private static final Log LOG =
LogFactory.getLog("com.puppycrawl.tools.checkstyle.TreeWalker");
@ -98,18 +123,6 @@ public final class TreeWalker
public TreeWalker()
{
setFileExtensions(new String[]{"java"});
// Tree walker can use two possible algorithms for
// tree processing (iterative and recursive.
// Recursive is default for now.
final String recursive =
System.getProperty("checkstyle.use.recursive.algorithm", "false");
mRecursive = "true".equals(recursive);
if (mRecursive) {
LOG.debug("TreeWalker uses recursive algorithm");
}
else {
LOG.debug("TreeWalker uses iterative algorithm");
}
}
/** @param aTabWidth the distance between tab stops */
@ -188,7 +201,14 @@ public final class TreeWalker
final FileText text = FileText.fromLines(aFile, aLines);
final FileContents contents = new FileContents(text);
final DetailAST rootAST = TreeWalker.parse(contents);
walk(rootAST, contents);
getMessageCollector().reset();
walk(rootAST, contents, AstState.ORDINARY);
final DetailAST astWithComments = appendHiddenCommentNodes(rootAST);
walk(astWithComments, contents, AstState.WITH_COMMENTS);
}
catch (final RecognitionException re) {
Utils.getExceptionLogger()
@ -243,6 +263,7 @@ public final class TreeWalker
this.getClass(), null));
}
catch (final Throwable err) {
err.printStackTrace();
Utils.getExceptionLogger().debug("Throwable occured.", err);
getMessageCollector().add(
new LocalizedMessage(
@ -295,7 +316,12 @@ public final class TreeWalker
for (int element : tokens) {
registerCheck(element, aCheck);
}
mAllChecks.add(aCheck);
if (aCheck.isCommentNodesRequired()) {
mCommentChecks.add(aCheck);
}
else {
mOrdinaryChecks.add(aCheck);
}
}
/**
@ -315,106 +341,126 @@ public final class TreeWalker
*/
private void registerCheck(String aToken, Check aCheck)
{
mTokenToChecks.put(aToken, aCheck);
if (aCheck.isCommentNodesRequired()) {
mTokenToCommentChecks.put(aToken, aCheck);
}
else if (TokenTypes.isCommentType(aToken)) {
LOG.warn("Check '"
+ aCheck.getClass().getName()
+ "' waits for comment type token ('"
+ aToken
+ "') and should override 'isCommentNodesRequred()'"
+ " method to return 'true'");
}
else {
mTokenToOrdinaryChecks.put(aToken, aCheck);
}
}
/**
* Initiates the walk of an AST.
* @param aAST the root AST
* @param aContents the contents of the file the AST was generated from
* @param aContents the contents of the file the AST was generated from.
* @param aAstState state of AST.
*/
private void walk(DetailAST aAST, FileContents aContents)
private void walk(DetailAST aAST, FileContents aContents
, AstState aAstState)
{
getMessageCollector().reset();
notifyBegin(aAST, aContents);
notifyBegin(aAST, aContents, aAstState);
// empty files are not flagged by javac, will yield aAST == null
if (aAST != null) {
if (useRecursiveAlgorithm()) {
processRec(aAST);
}
else {
processIter(aAST);
}
processIter(aAST, aAstState);
}
notifyEnd(aAST);
notifyEnd(aAST, aAstState);
}
/**
* Notify interested checks that about to begin walking a tree.
* @param aRootAST the root of the tree
* @param aContents the contents of the file the AST was generated from
* Notify checks that we are about to begin walking a tree.
* @param aRootAST the root of the tree.
* @param aContents the contents of the file the AST was generated from.
* @param aAstState state of AST.
*/
private void notifyBegin(DetailAST aRootAST, FileContents aContents)
private void notifyBegin(DetailAST aRootAST, FileContents aContents
, AstState aAstState)
{
for (Check ch : mAllChecks) {
Set<Check> checks;
if (aAstState == AstState.WITH_COMMENTS) {
checks = mCommentChecks;
}
else {
checks = mOrdinaryChecks;
}
for (Check ch : checks) {
ch.setFileContents(aContents);
ch.beginTree(aRootAST);
}
}
/**
* Notify checks that finished walking a tree.
* @param aRootAST the root of the tree
* Notify checks that we have finished walking a tree.
* @param aRootAST the root of the tree.
* @param aAstState state of AST.
*/
private void notifyEnd(DetailAST aRootAST)
private void notifyEnd(DetailAST aRootAST, AstState aAstState)
{
for (Check ch : mAllChecks) {
Set<Check> checks;
if (aAstState == AstState.WITH_COMMENTS) {
checks = mCommentChecks;
}
else {
checks = mOrdinaryChecks;
}
for (Check ch : checks) {
ch.finishTree(aRootAST);
}
}
/**
* Recursively processes a node calling interested checks at each node.
* Uses recursive algorithm.
* @param aAST the node to start from
* Notify checks that visiting a node.
* @param aAST the node to notify for.
* @param aAstState state of AST.
*/
private void processRec(DetailAST aAST)
private void notifyVisit(DetailAST aAST, AstState aAstState)
{
if (aAST == null) {
return;
Collection<Check> visitors;
final String tokenType = TokenTypes.getTokenName(aAST.getType());
if (aAstState == AstState.WITH_COMMENTS) {
visitors = mTokenToCommentChecks.get(tokenType);
}
else {
visitors = mTokenToOrdinaryChecks.get(tokenType);
}
notifyVisit(aAST);
final DetailAST child = aAST.getFirstChild();
if (child != null) {
processRec(child);
}
notifyLeave(aAST);
final DetailAST sibling = aAST.getNextSibling();
if (sibling != null) {
processRec(sibling);
}
}
/**
* Notify interested checks that visiting a node.
* @param aAST the node to notify for
*/
private void notifyVisit(DetailAST aAST)
{
final Collection<Check> visitors =
mTokenToChecks.get(TokenTypes.getTokenName(aAST.getType()));
for (Check c : visitors) {
c.visitToken(aAST);
}
}
/**
* Notify interested checks that leaving a node.
*
* Notify checks that leaving a node.
* @param aAST
* the node to notify for
* the node to notify for
* @param aAstState state of AST.
*/
private void notifyLeave(DetailAST aAST)
private void notifyLeave(DetailAST aAST, AstState aAstState)
{
final Collection<Check> visitors =
mTokenToChecks.get(TokenTypes.getTokenName(aAST.getType()));
Collection<Check> visitors;
final String tokenType = TokenTypes.getTokenName(aAST.getType());
if (aAstState == AstState.WITH_COMMENTS) {
visitors = mTokenToCommentChecks.get(tokenType);
}
else {
visitors = mTokenToOrdinaryChecks.get(tokenType);
}
for (Check ch : visitors) {
ch.leaveToken(aAST);
}
@ -432,7 +478,7 @@ public final class TreeWalker
* @return the root of the AST
*/
public static DetailAST parse(FileContents aContents)
throws RecognitionException, TokenStreamException
throws RecognitionException, TokenStreamException
{
final String fullText = aContents.getText().getFullText().toString();
final Reader sr = new StringReader(fullText);
@ -443,13 +489,13 @@ public final class TreeWalker
lexer.setTreatEnumAsKeyword(true);
lexer.setTokenObjectClass("antlr.CommonHiddenStreamToken");
TokenStreamHiddenTokenFilter filter = new TokenStreamHiddenTokenFilter(
lexer);
final TokenStreamHiddenTokenFilter filter =
new TokenStreamHiddenTokenFilter(lexer);
filter.hide(TokenTypes.SINGLE_LINE_COMMENT);
filter.hide(TokenTypes.BLOCK_COMMENT_BEGIN);
final GeneratedJavaRecognizer parser =
new GeneratedJavaRecognizer(filter);
new GeneratedJavaRecognizer(filter);
parser.setFilename(aContents.getFilename());
parser.setASTNodeClass(DetailAST.class.getName());
parser.compilationUnit();
@ -460,35 +506,30 @@ public final class TreeWalker
@Override
public void destroy()
{
for (Check c : mAllChecks) {
for (Check c : mOrdinaryChecks) {
c.destroy();
}
for (Check c : mCommentChecks) {
c.destroy();
}
mCache.destroy();
super.destroy();
}
/**
* @return true if we should use recursive algorithm
* for tree processing, false for iterative one.
*/
private boolean useRecursiveAlgorithm()
{
return mRecursive;
}
/**
* Processes a node calling interested checks at each node.
* Uses iterative algorithm.
* @param aRoot the root of tree for process
* @param aAstState state of AST.
*/
private void processIter(DetailAST aRoot)
private void processIter(DetailAST aRoot, AstState aAstState)
{
DetailAST curNode = aRoot;
while (curNode != null) {
notifyVisit(curNode);
notifyVisit(curNode, aAstState);
DetailAST toVisit = curNode.getFirstChild();
while ((curNode != null) && (toVisit == null)) {
notifyLeave(curNode);
notifyLeave(curNode, aAstState);
toVisit = curNode.getNextSibling();
if (toVisit == null) {
curNode = curNode.getParent();
@ -497,4 +538,206 @@ public final class TreeWalker
curNode = toVisit;
}
}
/**
* Appends comment nodes to existing AST.
* It traverses each node in AST, looks for hidden comment tokens
* and appends found comment tokens as nodes in AST.
* @param aRoot
* root of AST.
* @return root of AST with comment nodes.
*/
private static DetailAST appendHiddenCommentNodes(DetailAST aRoot)
{
DetailAST result = aRoot;
DetailAST curNode = aRoot;
DetailAST lastNode = aRoot;
while (curNode != null) {
if (isPositionGreater(curNode, lastNode)) {
lastNode = curNode;
}
CommonHiddenStreamToken tokenBefore = curNode.getHiddenBefore();
DetailAST currentSibling = curNode;
while (tokenBefore != null) { // threat multiple comments
final DetailAST newCommentNode =
createCommentAstFromToken(tokenBefore);
currentSibling.addPreviousSibling(newCommentNode);
if (currentSibling == result) {
result = newCommentNode;
}
currentSibling = newCommentNode;
tokenBefore = tokenBefore.getHiddenBefore();
}
DetailAST toVisit = curNode.getFirstChild();
while ((curNode != null) && (toVisit == null)) {
toVisit = curNode.getNextSibling();
if (toVisit == null) {
curNode = curNode.getParent();
}
}
curNode = toVisit;
}
if (lastNode != null) {
CommonHiddenStreamToken tokenAfter = lastNode.getHiddenAfter();
DetailAST currentSibling = lastNode;
while (tokenAfter != null) {
final DetailAST newCommentNode =
createCommentAstFromToken(tokenAfter);
currentSibling.addNextSibling(newCommentNode);
currentSibling = newCommentNode;
tokenAfter = tokenAfter.getHiddenAfter();
}
}
return result;
}
/**
* Checks if position of first DetailAST is greater than position of
* second DetailAST. Position is line number and column number in source
* file.
* @param aAST1
* first DetailAST node.
* @param aAst2
* second DetailAST node.
* @return true if position of aAst1 is greater than position of aAst2.
*/
private static boolean isPositionGreater(DetailAST aAST1, DetailAST aAst2)
{
if (aAST1.getLineNo() > aAst2.getLineNo()) {
return true;
}
else if (aAST1.getLineNo() < aAst2.getLineNo()) {
return false;
}
else {
if (aAST1.getColumnNo() > aAst2.getColumnNo()) {
return true;
}
}
return false;
}
/**
* Create comment AST from token. Depending on token type
* SINGLE_LINE_COMMENT or BLOCK_COMMENT_BEGIN is created.
* @param aToken
* Token object.
* @return DetailAST of comment node.
*/
private static DetailAST createCommentAstFromToken(Token aToken)
{
switch (aToken.getType()) {
case TokenTypes.SINGLE_LINE_COMMENT:
return createSlCommentNode(aToken);
case TokenTypes.BLOCK_COMMENT_BEGIN:
return createBlockCommentNode(aToken);
default:
throw new IllegalArgumentException("Unknown comment type");
}
}
/**
* Create single-line comment from token.
* @param aToken
* Token object.
* @return DetailAST with SINGLE_LINE_COMMENT type.
*/
private static DetailAST createSlCommentNode(Token aToken)
{
final DetailAST slComment = new DetailAST();
slComment.setType(TokenTypes.SINGLE_LINE_COMMENT);
slComment.setText("//");
// column counting begins from 0
slComment.setColumnNo(aToken.getColumn() - 1);
slComment.setLineNo(aToken.getLine());
final DetailAST slCommentContent = new DetailAST();
slCommentContent.initialize(aToken);
slCommentContent.setType(TokenTypes.COMMENT_CONTENT);
// column counting begins from 0
// plus length of '//'
slCommentContent.setColumnNo(aToken.getColumn() - 1 + 2);
slCommentContent.setLineNo(aToken.getLine());
slCommentContent.setText(aToken.getText());
slComment.addChild(slCommentContent);
return slComment;
}
/**
* Create block comment from token.
* @param aToken
* Token object.
* @return DetailAST with BLOCK_COMMENT type.
*/
private static DetailAST createBlockCommentNode(Token aToken)
{
final DetailAST blockComment = new DetailAST();
blockComment.initialize(TokenTypes.BLOCK_COMMENT_BEGIN, "/*");
// column counting begins from 0
blockComment.setColumnNo(aToken.getColumn() - 1);
blockComment.setLineNo(aToken.getLine());
final DetailAST blockCommentContent = new DetailAST();
blockCommentContent.initialize(aToken);
blockCommentContent.setType(TokenTypes.COMMENT_CONTENT);
// column counting begins from 0
// plus length of '/*'
blockCommentContent.setColumnNo(aToken.getColumn() - 1 + 2);
blockCommentContent.setLineNo(aToken.getLine());
blockCommentContent.setText(aToken.getText());
final DetailAST blockCommentClose = new DetailAST();
blockCommentClose.initialize(TokenTypes.BLOCK_COMMENT_END, "*/");
final Entry<Integer, Integer> linesColumns = countLinesColumns(
aToken.getText(), aToken.getLine(), aToken.getColumn());
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 aText
* String.
* @param aInitialLinesCnt
* initial value of lines counter.
* @param aInitialColumnsCnt
* initial value of columns counter.
* @return entry(pair), first element is lines counter, second - columns
* counter.
*/
private static Entry<Integer, Integer> countLinesColumns(
String aText, int aInitialLinesCnt, int aInitialColumnsCnt)
{
int lines = aInitialLinesCnt;
int columns = aInitialColumnsCnt;
for (char c : aText.toCharArray()) {
switch (c) {
case '\n':
lines++;
columns = 0;
break;
default:
columns++;
}
}
return new SimpleEntry<Integer, Integer>(lines, columns);
}
}

View File

@ -18,9 +18,10 @@
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.api;
import com.google.common.collect.Sets;
import java.util.Set;
import com.google.common.collect.Sets;
/**
* The base class for checks.
*
@ -52,6 +53,11 @@ public abstract class Check extends AbstractViolationReporter
*/
private ClassLoader mLoader;
public boolean isCommentNodesRequired()
{
return false;
}
/**
* Returns the default token a check is interested in. Only used if the
* configuration for a check does not define the tokens.

View File

@ -78,6 +78,8 @@ public final class DetailAST extends CommonASTWithHiddenTokens
setType(da.getType());
mLineNo = da.getLineNo();
mColumnNo = da.getColumnNo();
hiddenAfter = da.getHiddenAfter();
hiddenBefore = da.getHiddenBefore();
}
@Override
@ -102,6 +104,51 @@ public final class DetailAST extends CommonASTWithHiddenTokens
}
}
/**
* Add previous sibling.
* @param aAST
* DetailAST object.
*/
public void addPreviousSibling(DetailAST aAST)
{
if (aAST != null) {
aAST.setParent(mParent);
final DetailAST previousSibling = this.getPreviousSibling();
if (previousSibling != null) {
aAST.setPreviousSibling(previousSibling);
previousSibling.setNextSibling(aAST);
}
else if (mParent != null) {
mParent.setFirstChild(aAST);
}
aAST.setNextSibling(this);
this.setPreviousSibling(aAST);
}
}
/**
* Add next sibling.
* @param aAST
* DetailAST object.
*/
public void addNextSibling(DetailAST aAST)
{
if (aAST != null) {
aAST.setParent(mParent);
final DetailAST nextSibling = this.getNextSibling();
if (nextSibling != null) {
aAST.setNextSibling(nextSibling);
nextSibling.setPreviousSibling(aAST);
}
aAST.setPreviousSibling(this);
this.setNextSibling(aAST);
}
}
/**
* Sets previous sibling.
* @param aAST a previous sibling
@ -174,36 +221,82 @@ public final class DetailAST extends CommonASTWithHiddenTokens
if (mLineNo == NOT_INITIALIZED) {
// an inner AST that has been initialized
// with initialize(String text)
final DetailAST child = getFirstChild();
final DetailAST sibling = getNextSibling();
if (child != null) {
return child.getLineNo();
DetailAST child = getFirstChild();
while (child != null) {
// comment node can't be start of any java statement/definition
if (TokenTypes.isCommentType(child.getType())) {
child = child.getNextSibling();
}
else {
return child.getLineNo();
}
}
else if (sibling != null) {
return sibling.getLineNo();
DetailAST sibling = getNextSibling();
while (sibling != null) {
// comment node can't be start of any java statement/definition
if (TokenTypes.isCommentType(sibling.getType())) {
sibling = sibling.getNextSibling();
}
else {
return sibling.getLineNo();
}
}
}
return mLineNo;
}
/**
* Set line number.
* @param aLineNo
* line number.
*/
public void setLineNo(int aLineNo)
{
mLineNo = aLineNo;
}
/** @return the column number **/
public int getColumnNo()
{
if (mColumnNo == NOT_INITIALIZED) {
// an inner AST that has been initialized
// with initialize(String text)
final DetailAST child = getFirstChild();
final DetailAST sibling = getNextSibling();
if (child != null) {
return child.getColumnNo();
DetailAST child = getFirstChild();
while (child != null) {
// comment node can't be start of any java statement/definition
if (TokenTypes.isCommentType(child.getType())) {
child = child.getNextSibling();
}
else {
return child.getColumnNo();
}
}
else if (sibling != null) {
return sibling.getColumnNo();
DetailAST sibling = getNextSibling();
while (sibling != null) {
// comment node can't be start of any java statement/definition
if (TokenTypes.isCommentType(sibling.getType())) {
sibling = sibling.getNextSibling();
}
else {
return sibling.getColumnNo();
}
}
}
return mColumnNo;
}
/**
* Set column number.
* @param aColumnNo
* column number.
*/
public void setColumnNo(int aColumnNo)
{
mColumnNo = aColumnNo;
}
/** @return the last child node */
public DetailAST getLastChild()
{
@ -308,4 +401,5 @@ public final class DetailAST extends CommonASTWithHiddenTokens
{
return (DetailAST) super.getFirstChild();
}
}

View File

@ -3437,24 +3437,61 @@ public final class TokenTypes
public static final int LAMBDA = GeneratedJavaTokenTypes.LAMBDA;
/**
* Begining of single line comment: '//'
* Begining of single line comment: '//'.
*
* <pre>
* +--SINLE_LINE_COMMENT
* |
* +--COMMENT_CONTENT
* </pre>
*/
public static final int SINGLE_LINE_COMMENT = GeneratedJavaTokenTypes.SINGLE_LINE_COMMENT;
public static final int SINGLE_LINE_COMMENT =
GeneratedJavaTokenTypes.SINGLE_LINE_COMMENT;
/**
* Begining of block comment: '/*'
* Begining of block comment: '/*'.
*
* <pre>
* +--BLOCK_COMMENT_BEGIN
* |
* +--COMMENT_CONTENT
* +--BLOCK_COMMENT_END
* </pre>
*/
public static final int BLOCK_COMMENT_BEGIN = GeneratedJavaTokenTypes.BLOCK_COMMENT_BEGIN;
public static final int BLOCK_COMMENT_BEGIN =
GeneratedJavaTokenTypes.BLOCK_COMMENT_BEGIN;
/**
* End of block comment: '* /'
* End of block comment: '* /'.
*
* <pre>
* +--BLOCK_COMMENT_BEGIN
* |
* +--COMMENT_CONTENT
* +--BLOCK_COMMENT_END
* </pre>
*/
public static final int BLOCK_COMMENT_END = GeneratedJavaTokenTypes.BLOCK_COMMENT_END;
public static final int BLOCK_COMMENT_END =
GeneratedJavaTokenTypes.BLOCK_COMMENT_END;
/**
* Text of single-line or block comment.
*
*<pre>
* +--SINLE_LINE_COMMENT
* |
* +--COMMENT_CONTENT
* </pre>
*
* <pre>
* +--BLOCK_COMMENT_BEGIN
* |
* +--COMMENT_CONTENT
* +--BLOCK_COMMENT_END
* </pre>
*/
public static final int COMMENT_CONTENT = GeneratedJavaTokenTypes.COMMENT_CONTENT;
public static final int COMMENT_CONTENT =
GeneratedJavaTokenTypes.COMMENT_CONTENT;
////////////////////////////////////////////////////////////////////////
// The interesting code goes here
@ -3552,15 +3589,29 @@ public final class TokenTypes
}
/**
* Check that argument is SINGLE_LINE_COMMENT or BLOCK_COMMENT_BEGIN
* or BLOCK_COMMENT_END or COMMENT_CONTENT.
* @param aType token type
* @return true if aType is comment token type
* Is argument comment-related type (SINGLE_LINE_COMMENT,
* BLOCK_COMMENT_BEGIN, BLOCK_COMMENT_END, COMMENT_CONTENT).
* @param aType
* token type.
* @return true if aType is comment-related type.
*/
public static boolean isCommentType(int aType) {
public static boolean isCommentType(int aType)
{
return aType == TokenTypes.SINGLE_LINE_COMMENT
|| aType == TokenTypes.BLOCK_COMMENT_BEGIN
|| aType == TokenTypes.BLOCK_COMMENT_END
|| aType == TokenTypes.COMMENT_CONTENT;
}
/**
* Is argument comment-related type name (SINGLE_LINE_COMMENT,
* BLOCK_COMMENT_BEGIN, BLOCK_COMMENT_END, COMMENT_CONTENT).
* @param aType
* token type name.
* @return true if aType is comment-related type name.
*/
public static boolean isCommentType(String aType)
{
return isCommentType(getTokenId(aType));
}
}

View File

@ -23,6 +23,8 @@ import java.io.File;
import javax.swing.JFrame;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
/**
* Entry point for starting the checkstyle GUI.
*/
@ -43,4 +45,15 @@ public class Main
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void displayAst(DetailAST ast)
{
JFrame frame = new JFrame("CheckStyle");
final ParseTreeInfoPanel panel = new ParseTreeInfoPanel();
frame.getContentPane().add(panel);
panel.openAst(ast, frame);
frame.setSize(1500, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

View File

@ -29,6 +29,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.TooManyListenersException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
@ -39,7 +40,9 @@ import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import antlr.ANTLRException;
import com.puppycrawl.tools.checkstyle.TreeWalker;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FileContents;
@ -82,6 +85,26 @@ public class ParseTreeInfoPanel extends JPanel
}
}
public void openAst(DetailAST parseTree, final Component aParent)
{
mParseTreeModel.setParseTree(parseTree);
reloadAction.setEnabled(true);
// clear for each new file
getLines2position().clear();
// starts line counting at 1
getLines2position().add(0);
// insert the contents of the file to the text area
// clean the text area before inserting the lines of the new file
if (mJTextArea.getText().length() != 0) {
mJTextArea.replaceRange("", 0, mJTextArea.getText().length());
}
// move back to the top of the file
mJTextArea.moveCaretPosition(0);
}
private class FileSelectionAction extends AbstractAction
{
/**

View File

@ -0,0 +1,85 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2014 Oliver Burn
//
// 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.comments;
import java.io.File;
import java.util.Arrays;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Sets;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.Check;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
public class AllBlockCommentsTest extends BaseCheckTestSupport
{
protected static final Set<String> allComments = Sets.newLinkedHashSet();
public static class BlockCommentListenerCheck extends Check
{
@Override
public boolean isCommentNodesRequired()
{
return true;
}
@Override
public int[] getDefaultTokens()
{
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN};
}
@Override
public void init()
{
allComments.addAll(Arrays.asList("0", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
"17", "18", "19", "20", "\n21\n", "22", "23", "24", "25", "26",
"27", "28", "29", "30", "31", "32", "33", "34", "35", "36",
"37", "38", " 39 ", "40", "41", "42", "43", "44", "45", "46",
"47", "48", "49", "50", "51", "52", "53", "54", "55", "56",
"57", "58", "59", "60", "61"));
}
@Override
public void visitToken(DetailAST aAST)
{
String commentContent = aAST.getFirstChild().getText();
if (!allComments.remove(commentContent)) {
Assert.fail("Unexpected comment: " + commentContent);
}
}
}
@Test
public void testAllBlockComments() throws Exception
{
DefaultConfiguration checkConfig = createCheckConfig(BlockCommentListenerCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("comments" + File.separator
+ "InputFullOfBlockComments.java"), expected);
Assert.assertTrue(allComments.isEmpty());
}
}

View File

@ -0,0 +1,85 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2014 Oliver Burn
//
// 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.comments;
import java.io.File;
import java.util.Arrays;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Sets;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.Check;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
public class AllSinglelineCommentsTest extends BaseCheckTestSupport
{
protected static final Set<String> allComments = Sets.newLinkedHashSet();
public static class SinglelineCommentListenerCheck extends Check
{
@Override
public boolean isCommentNodesRequired()
{
return true;
}
@Override
public int[] getDefaultTokens()
{
return new int[] {TokenTypes.SINGLE_LINE_COMMENT};
}
@Override
public void init()
{
allComments.addAll(Arrays.asList("0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n",
"7\n", "8\n", "9\n", "10\n", "11\n", "12\n", "13\n", "14\n", "15\n", "16\n",
"17\n", "18\n", "19\n", "20\n", "21\n", "22\n", "23\n", "24\n", "25\n", "26\n",
"27\n", "28\n", "29\n", "30\n", "31\n", "32\n", "33\n", "34\n", "35\n", "36\n",
"37\n", "38\n", "39\n", "40\n", "41\n", "42\n", "43\n", "44\n", "45\n", "46\n",
"47\n", "48\n", "49\n", "50\n", "51\n", "52\n", "53\n", "54\n", "55\n", "56\n",
"57\n", "58\n", "59\n", "60\n", "61\n", "62\n", "63"));
}
@Override
public void visitToken(DetailAST aAST)
{
String commentContent = aAST.getFirstChild().getText();
if (!allComments.remove(commentContent)) {
Assert.fail("Unexpected comment: " + commentContent);
}
}
}
@Test
public void testAllBlockComments() throws Exception
{
DefaultConfiguration checkConfig = createCheckConfig(SinglelineCommentListenerCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("comments" + File.separator
+ "InputFullOfSinglelineComments.java"), expected);
Assert.assertTrue(allComments.isEmpty());
}
}

View File

@ -0,0 +1,413 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2014 Oliver Burn
//
// 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.comments;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.BLOCK_COMMENT_BEGIN;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.BLOCK_COMMENT_END;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.CLASS_DEF;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.COMMENT_CONTENT;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.IDENT;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.LCURLY;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.LITERAL_CLASS;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.LITERAL_PROTECTED;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.LITERAL_PUBLIC;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.LPAREN;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.METHOD_DEF;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.MODIFIERS;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.OBJBLOCK;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.PARAMETERS;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.RCURLY;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.RPAREN;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.SINGLE_LINE_COMMENT;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.SLIST;
import static com.puppycrawl.tools.checkstyle.api.TokenTypes.TYPE;
import java.io.File;
import org.junit.Test;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
public class CommentsTest extends BaseCheckTestSupport
{
/*
* +--CLASS_DEF [1,0]
* |
* +--MODIFIERS [1,0]
* |
* +--LITERAL_PUBLIC [1,0]
* +--LITERAL_CLASS [1,7]
* +--BLOCK_COMMENT_BEGIN [1,13]
* |
* +--COMMENT_CONTENT [1,15]
* +--BLOCK_COMMENT_END [3,4]
* +--IDENT [4,0]
* +--OBJBLOCK [5,0]
* |
* +--LCURLY [5,0]
* |
* +--SINGLE_LINE_COMMENT [5,2]
* |
* +--COMMENT_CONTENT [5,4]
* +--RCURLY [6,0]
*/
private static DetailAST buildInput_1()
{
DetailAST classDef = new DetailAST();
classDef.setType(CLASS_DEF);
classDef.setText("CLASS_DEF");
classDef.setLineNo(1);
classDef.setColumnNo(0);
DetailAST modifiers = new DetailAST();
modifiers.setType(MODIFIERS);
modifiers.setText("MODIFIERS");
modifiers.setLineNo(1);
modifiers.setColumnNo(0);
DetailAST literalPublic = new DetailAST();
literalPublic.setType(LITERAL_PUBLIC);
literalPublic.setText("public");
literalPublic.setLineNo(1);
literalPublic.setColumnNo(0);
DetailAST literalClass = new DetailAST();
literalClass.setType(LITERAL_CLASS);
literalClass.setText("class");
literalClass.setLineNo(1);
literalClass.setColumnNo(7);
DetailAST blockCommentStart = new DetailAST();
blockCommentStart.setType(BLOCK_COMMENT_BEGIN);
blockCommentStart.setText("/*");
blockCommentStart.setLineNo(1);
blockCommentStart.setColumnNo(13);
DetailAST blockCommentContent = new DetailAST();
blockCommentContent.setType(COMMENT_CONTENT);
blockCommentContent.setText("\n i'mcomment567\n ");
blockCommentContent.setLineNo(1);
blockCommentContent.setColumnNo(15);
DetailAST blockCommentEnd = new DetailAST();
blockCommentEnd.setType(BLOCK_COMMENT_END);
blockCommentEnd.setText("*/");
blockCommentEnd.setLineNo(3);
blockCommentEnd.setColumnNo(4);
DetailAST ident = new DetailAST();
ident.setType(IDENT);
ident.setText("InputCommentsTest");
ident.setLineNo(4);
ident.setColumnNo(0);
DetailAST objBlock = new DetailAST();
objBlock.setType(OBJBLOCK);
objBlock.setText("OBJBLOCK");
objBlock.setLineNo(5);
objBlock.setColumnNo(0);
DetailAST lcurly = new DetailAST();
lcurly.setType(LCURLY);
lcurly.setText("{");
lcurly.setLineNo(5);
lcurly.setColumnNo(0);
DetailAST slComment = new DetailAST();
slComment.setType(SINGLE_LINE_COMMENT);
slComment.setText("//");
slComment.setLineNo(5);
slComment.setColumnNo(2);
DetailAST slCommentContent = new DetailAST();
slCommentContent.setType(COMMENT_CONTENT);
slCommentContent.setText(" comment to left curly brace\n");
slCommentContent.setLineNo(5);
slCommentContent.setColumnNo(4);
DetailAST rcurly = new DetailAST();
rcurly.setType(RCURLY);
rcurly.setText("}");
rcurly.setLineNo(6);
rcurly.setColumnNo(0);
classDef.setFirstChild(modifiers);
modifiers.setNextSibling(literalClass);
literalClass.setNextSibling(blockCommentStart);
blockCommentStart.setNextSibling(ident);
ident.setNextSibling(objBlock);
modifiers.setFirstChild(literalPublic);
blockCommentStart.setFirstChild(blockCommentContent);
blockCommentContent.setNextSibling(blockCommentEnd);
objBlock.setFirstChild(lcurly);
lcurly.setNextSibling(slComment);
slComment.setNextSibling(rcurly);
slComment.setFirstChild(slCommentContent);
return classDef;
}
/*
* +--CLASS_DEF [2,0]
* |
* +--MODIFIERS [2,0]
* +--SINGLE_LINE_COMMENT [1,0]
* |
* +--COMMENT_CONTENT [1,2]
* +--LITERAL_CLASS [2,0]
* +--IDENT [2,6]
* +--OBJBLOCK [3,0]
* |
* +--LCURLY [3,0]
* +--METHOD_DEF [9,4]
* |
* +--MODIFIERS [9,4]
* |
* +--BLOCK_COMMENT_BEGIN [4,4]
* |
* +--COMMENT_CONTENT [4,6]
* +--BLOCK_COMMENT_END [8,5]
* +--LITERAL_PROTECTED [9,4]
* +--TYPE [9,14]
* |
* +--IDENT [9,14]
* +--IDENT [9,21]
* +--LPAREN [9,25]
* +--PARAMETERS [9,26]
* +--RPAREN [9,26]
* +--SLIST [10,4]
* |
* +--RCURLY [11,4]
* +--RCURLY [12,0]
*/
private static DetailAST buildInput_2()
{
DetailAST classDef = new DetailAST();
classDef.setType(CLASS_DEF);
classDef.setText("CLASS_DEF");
classDef.setLineNo(2);
classDef.setColumnNo(0);
DetailAST modifiers = new DetailAST();
modifiers.setType(MODIFIERS);
modifiers.setText("MODIFIERS");
modifiers.setLineNo(2);
modifiers.setColumnNo(0);
classDef.setFirstChild(modifiers);
DetailAST slComment = new DetailAST();
slComment.setType(SINGLE_LINE_COMMENT);
slComment.setText("//");
slComment.setLineNo(1);
slComment.setColumnNo(0);
DetailAST slCommentContent = new DetailAST();
slCommentContent.setType(COMMENT_CONTENT);
slCommentContent.setText(" my class\n");
slCommentContent.setLineNo(1);
slCommentContent.setColumnNo(2);
slComment.setFirstChild(slCommentContent);
modifiers.setNextSibling(slComment);
DetailAST literalClass = new DetailAST();
literalClass.setType(LITERAL_CLASS);
literalClass.setText("class");
literalClass.setLineNo(2);
literalClass.setColumnNo(0);
slComment.setNextSibling(literalClass);
DetailAST identClassName = new DetailAST();
identClassName.setType(IDENT);
identClassName.setText("A");
identClassName.setLineNo(2);
identClassName.setColumnNo(6);
literalClass.setNextSibling(identClassName);
DetailAST objBlock = new DetailAST();
objBlock.setType(OBJBLOCK);
objBlock.setText("OBJBLOCK");
objBlock.setLineNo(3);
objBlock.setColumnNo(0);
identClassName.setNextSibling(objBlock);
DetailAST lcurly = new DetailAST();
lcurly.setType(LCURLY);
lcurly.setText("{");
lcurly.setLineNo(3);
lcurly.setColumnNo(0);
objBlock.setFirstChild(lcurly);
DetailAST methodDef = new DetailAST();
methodDef.setType(METHOD_DEF);
methodDef.setText("METHOD_DEF");
methodDef.setLineNo(9);
methodDef.setColumnNo(4);
lcurly.setNextSibling(methodDef);
DetailAST rcurly = new DetailAST();
rcurly.setType(RCURLY);
rcurly.setText("}");
rcurly.setLineNo(12);
rcurly.setColumnNo(0);
methodDef.setNextSibling(rcurly);
DetailAST methodModifiers = new DetailAST();
methodModifiers.setType(MODIFIERS);
methodModifiers.setText("MODIFIERS");
methodModifiers.setLineNo(9);
methodModifiers.setColumnNo(4);
methodDef.setFirstChild(methodModifiers);
DetailAST methodType = new DetailAST();
methodType.setType(TYPE);
methodType.setText("TYPE");
methodType.setLineNo(9);
methodType.setColumnNo(14);
methodModifiers.setNextSibling(methodType);
DetailAST identMethodType = new DetailAST();
identMethodType.setType(IDENT);
identMethodType.setText("String");
identMethodType.setLineNo(9);
identMethodType.setColumnNo(14);
methodType.setFirstChild(identMethodType);
DetailAST identMethodName = new DetailAST();
identMethodName.setType(IDENT);
identMethodName.setText("line");
identMethodName.setLineNo(9);
identMethodName.setColumnNo(21);
methodType.setNextSibling(identMethodName);
DetailAST lparen = new DetailAST();
lparen.setType(LPAREN);
lparen.setText("(");
lparen.setLineNo(9);
lparen.setColumnNo(25);
identMethodName.setNextSibling(lparen);
DetailAST parameters = new DetailAST();
parameters.setType(PARAMETERS);
parameters.setText("PARAMETERS");
parameters.setLineNo(9);
parameters.setColumnNo(26);
lparen.setNextSibling(parameters);
DetailAST rparen = new DetailAST();
rparen.setType(RPAREN);
rparen.setText(")");
rparen.setLineNo(9);
rparen.setColumnNo(26);
parameters.setNextSibling(rparen);
DetailAST slist = new DetailAST();
slist.setType(SLIST);
slist.setText("{");
slist.setLineNo(10);
slist.setColumnNo(4);
rparen.setNextSibling(slist);
DetailAST methodRcurly = new DetailAST();
methodRcurly.setType(RCURLY);
methodRcurly.setText("}");
methodRcurly.setLineNo(11);
methodRcurly.setColumnNo(4);
slist.setFirstChild(methodRcurly);
DetailAST blockCommentStart = new DetailAST();
blockCommentStart.setType(BLOCK_COMMENT_BEGIN);
blockCommentStart.setText("/*");
blockCommentStart.setLineNo(4);
blockCommentStart.setColumnNo(4);
DetailAST blockCommentContent = new DetailAST();
blockCommentContent.setType(COMMENT_CONTENT);
blockCommentContent.setText("*\n"
+ " * Lines <b>method</b>.\n"
+ " * \n"
+ " * @return string.\n"
+ " ");
blockCommentContent.setLineNo(4);
blockCommentContent.setColumnNo(6);
blockCommentStart.setFirstChild(blockCommentContent);
DetailAST blockCommentEnd = new DetailAST();
blockCommentEnd.setType(BLOCK_COMMENT_END);
blockCommentEnd.setText("*/");
blockCommentEnd.setLineNo(8);
blockCommentEnd.setColumnNo(5);
blockCommentContent.setNextSibling(blockCommentEnd);
methodModifiers.setFirstChild(blockCommentStart);
DetailAST literalProtected = new DetailAST();
literalProtected.setType(LITERAL_PROTECTED);
literalProtected.setText("protected");
literalProtected.setLineNo(9);
literalProtected.setColumnNo(4);
blockCommentStart.setNextSibling(literalProtected);
return classDef;
}
@Test
public void testCompareExpectedTreeWithInput_1() throws Exception
{
DefaultConfiguration checkConfig = createCheckConfig(CompareTreesWithComments.class);
CompareTreesWithComments.expectedTree = buildInput_1();
final String[] expected = {};
verify(checkConfig, getPath("comments" + File.separator
+ "InputCommentsTest_1.java"), expected);
}
@Test
public void testCompareExpectedTreeWithInput_2() throws Exception
{
DefaultConfiguration checkConfig = createCheckConfig(CompareTreesWithComments.class);
CompareTreesWithComments.expectedTree = buildInput_2();
final String[] expected = {};
verify(checkConfig, getPath("comments" + File.separator
+ "InputCommentsTest_2.java"), expected);
}
}

View File

@ -0,0 +1,67 @@
package com.puppycrawl.tools.checkstyle.comments;
import org.junit.Assert;
import com.puppycrawl.tools.checkstyle.api.Check;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
public class CompareTreesWithComments extends Check
{
protected static DetailAST expectedTree;
@Override
public boolean isCommentNodesRequired()
{
return true;
}
@Override
public int[] getDefaultTokens()
{
return new int[]{};
}
@Override
public void beginTree(DetailAST aRootAST)
{
Assert.assertTrue(isAstEquals(expectedTree, aRootAST));
}
private boolean isAstEquals(DetailAST expected, DetailAST actual)
{
boolean result = false;
if (expected == actual) {
result = true;
}
else if (actual == null || expected == null) {
result = false;
} else {
if (expected.getType() == actual.getType()
&& expected.getLineNo() == actual.getLineNo()
&& expected.getColumnNo() == actual.getColumnNo())
{
if (expected.getText() == null) {
result = actual.getText() == null;
}
else if (expected.getText().equals(actual.getText())) {
result = true;
}
}
if (result) {
DetailAST childExpected = expected.getFirstChild();
DetailAST childActual = actual.getFirstChild();
result = isAstEquals(childExpected, childActual);
if (result) {
DetailAST nextSiblingExpected = expected.getNextSibling();
DetailAST nextSiblingActual = actual.getNextSibling();
result = isAstEquals(nextSiblingExpected, nextSiblingActual);
}
}
}
if (!result) {
System.out.println("Expected: " + expected + " | Actual: " + actual);
}
return result;
}
}

View File

@ -0,0 +1,6 @@
public class /*
i'mcomment567
*/
InputCommentsTest
{ // comment to left curly brace
}

View File

@ -0,0 +1,12 @@
// my class
class A
{
/**
* Lines <b>method</b>.
*
* @return string.
*/
protected String line()
{
}
}

View File

@ -0,0 +1,15 @@
/*0*//*1*/package/*2*/ com/*3*/./*4*/puppycrawl/*5*/./*6*/tools/*7*/./*8*/checkstyle/*9*/./*10*/javadoc/*11*/;/*12*/
/*13*/
/*14*/public/*15*/ class /*16*/InputFullOfBlockComments /*49*/{/*17*/
/*18*/
/*19*/public/*20*/ static/*
21
*/ String/*22*/ main/*23*/(/*24*/String/*25*/[/*26*/]/*27*/ args/*28*/)/*29*/ {/*30*/
/*31*/String /*32*/line /*33*/= /*34*/"/*I'm NOT comment*/blabla"/*35*/;/*36*/
/*37*/System/*38*/./* 39 */out/*40*/./*41*/println/*42*/(/*43*/line/*44*/)/*45*/;/*46*/
/*50*/for/*51*/ (/*52*/Integer/*53*/ i/*54*/:/*55*/ array/*56*/)/*57*/ {/*58*/
/*59*/
}/*60*/
}/*47*/
}/*48*/
/*61*/

View File

@ -0,0 +1,64 @@
//0
package//1
com//2
.//3
puppycrawl//4
.//5
tools//6
.//7
checkstyle//8
.//9
checks//10
.//11
javadoc//12
;//13
//14
public//15
class//16
InputFullOfSinglelineComments//17
{//18
public//19
static//20
void//21
main//22
(//23
String//24
[//25
]//26
args//27
)//28
{//29
for//30
(//31
int//32
i//33
=//34
0//35
;//36
i//37
<=//38
10//39
;//40
i++//41
)//42
{//43
String//44
line//45
=//46
i//47
+//48
""//49
;//50
System//51
.//52
out//53
.//54
println//55
(//56
line//57
)//58
;//59
}//60
}//61
}//62
//63

View File

@ -50,4 +50,7 @@
<suppress checks="." files=".*[\\/]grammars[\\/]Generated[a-zA-Z]*\.java"/>
<suppress checks="." files=".*[\\/]grammars[\\/]Generated[a-zA-Z]*\.java"/>
<suppress checks="." files=".*[\\/]checkstyle[\\/]gui[\\/]"/>
<!-- Methods that build fake AST are very long-->
<suppress checks="MethodLength" files="src[\\/]test[\\/]java[\\/]com[\\/]puppycrawl[\\/]tools[\\/]checkstyle[\\/]comments[\\/]CommentsTest\.java"/>
</suppressions>