Ignore comments in GenericIllegalRegexp check,
contributed by Daniel Grenner
This commit is contained in:
parent
22d0ed9d4c
commit
3ad02e2dcd
|
|
@ -90,6 +90,12 @@
|
|||
<td><a href="property_types.html#boolean">Boolean</a></td>
|
||||
<td><span class="default">false</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ignoreComments</td>
|
||||
<td>Controls whether to ignore text in comments when searching.</td>
|
||||
<td><a href="property_types.html#boolean">Boolean</a></td>
|
||||
<td><span class="default">false</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>message</td>
|
||||
<td>message which is used to notify about violations,
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@
|
|||
<property> tags, improves usability for centralized
|
||||
configuration files.</li>
|
||||
|
||||
<li class="body">Ignore comments in GenericIllegalRegexp check,
|
||||
contributed by Daniel Grenner (request 680988, patch 902109).
|
||||
</ul>
|
||||
|
||||
<p class="body">
|
||||
|
|
|
|||
|
|
@ -102,4 +102,29 @@ class Comment implements TextBlock
|
|||
{
|
||||
return mLastCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this comment intersects with a specified
|
||||
* part of the file.
|
||||
*
|
||||
* @param aStartLineNo the starting line number in the file
|
||||
* @param aStartColNo the starting column number in the file
|
||||
* @param aEndLineNo the ending line number in the file
|
||||
* @param aEndColNo the ending column number in the file
|
||||
* @return true if the positions intersects with this comment.
|
||||
**/
|
||||
public boolean intersects(int aStartLineNo, int aStartColNo,
|
||||
int aEndLineNo, int aEndColNo)
|
||||
{
|
||||
// compute a single number for start and end
|
||||
// to simpify conditional logic
|
||||
final long multiplier = Integer.MAX_VALUE;
|
||||
final long thisStart = ((long) mFirstLine) * multiplier + mFirstCol;
|
||||
final long thisEnd = ((long) mLastLine) * multiplier + mLastCol;
|
||||
final long inStart = ((long) aStartLineNo) * multiplier + aStartColNo;
|
||||
final long inEnd = ((long) aEndLineNo) * multiplier + aEndColNo;
|
||||
|
||||
return ((thisStart < inStart) && (inStart < thisEnd))
|
||||
|| ((thisStart < inEnd) && (inEnd < thisEnd));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.grammars.CommentListener;
|
||||
|
||||
|
|
@ -241,4 +243,47 @@ public final class FileContents implements CommentListener
|
|||
return MATCH_SINGLELINE_COMMENT.match(mLines[aLineNo]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified position intersects with a comment.
|
||||
* @param aStartLineNo the starting line number
|
||||
* @param aStartColNo the starting column number
|
||||
* @param aEndLineNo the ending line number
|
||||
* @param aEndColNo the ending column number
|
||||
* @return true if the positions intersects with a comment.
|
||||
**/
|
||||
public boolean hasIntersectionWithComment(
|
||||
int aStartLineNo, int aStartColNo, int aEndLineNo, int aEndColNo)
|
||||
{
|
||||
// Check C comments (all comments should be checked)
|
||||
Collection values = mCComments.values();
|
||||
|
||||
Iterator it = values.iterator();
|
||||
while (it.hasNext()) {
|
||||
List row = (List) it.next();
|
||||
Iterator rowIterator = row.iterator();
|
||||
while (rowIterator.hasNext()) {
|
||||
Comment comment = (Comment) rowIterator.next();
|
||||
if (comment.intersects(
|
||||
aStartLineNo, aStartColNo, aEndLineNo, aEndColNo))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check CPP comments (line searching is possible)
|
||||
for (int lineNumber = aStartLineNo; lineNumber <= aEndLineNo;
|
||||
lineNumber++)
|
||||
{
|
||||
Comment comment = (Comment) mCPlusPlusComments.get(
|
||||
new Integer(lineNumber));
|
||||
if (comment != null && comment.intersects(aStartLineNo, aStartColNo,
|
||||
aEndLineNo, aEndColNo))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package com.puppycrawl.tools.checkstyle.checks;
|
|||
import org.apache.regexp.RE;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.FileContents;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -43,6 +44,7 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
|||
* </pre>
|
||||
* @author lkuehne
|
||||
* @author <a href="mailto:bschneider@vecna.com">Bill Schneider</a>
|
||||
* @author Daniel Grenner
|
||||
*/
|
||||
public class GenericIllegalRegexpCheck extends AbstractFormatCheck
|
||||
{
|
||||
|
|
@ -55,6 +57,9 @@ public class GenericIllegalRegexpCheck extends AbstractFormatCheck
|
|||
/** case insensitive? **/
|
||||
private boolean mIgnoreCase;
|
||||
|
||||
/** Ignore comments in code? **/
|
||||
private boolean mIgnoreComments;
|
||||
|
||||
/**
|
||||
* Setter for message property.
|
||||
* @param aMessage custom message which should be used
|
||||
|
|
@ -88,6 +93,15 @@ public class GenericIllegalRegexpCheck extends AbstractFormatCheck
|
|||
mIgnoreCase = aCaseInsensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if comments should be ignored.
|
||||
* @param aIgnoreComments True if comments should be ignored.
|
||||
*/
|
||||
public void setIgnoreComments(boolean aIgnoreComments)
|
||||
{
|
||||
mIgnoreComments = aIgnoreComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates an new GenericIllegalRegexpCheck.
|
||||
*/
|
||||
|
|
@ -106,10 +120,18 @@ public class GenericIllegalRegexpCheck extends AbstractFormatCheck
|
|||
public void beginTree(DetailAST aRootAST)
|
||||
{
|
||||
final String[] lines = getLines();
|
||||
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
|
||||
final String line = lines[i];
|
||||
if (getRegexp().match(line)) {
|
||||
final boolean foundMatch;
|
||||
if (mIgnoreComments) {
|
||||
foundMatch = findNonCommentMatch(line, i + 1, 0);
|
||||
}
|
||||
else {
|
||||
foundMatch = getRegexp().match(line);
|
||||
}
|
||||
if (foundMatch) {
|
||||
if ("".equals(mMessage)) {
|
||||
log(i + 1, "illegal.regexp", getFormat());
|
||||
}
|
||||
|
|
@ -120,6 +142,47 @@ public class GenericIllegalRegexpCheck extends AbstractFormatCheck
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds matches that are not inside comments.
|
||||
* @param aLine The text that should be matched.
|
||||
* @param aLineNumber The current line number.
|
||||
* @param aStartPosition The position to start searching from.
|
||||
* @return true if a match is done where there is no comment.
|
||||
*/
|
||||
private boolean findNonCommentMatch(
|
||||
String aLine, int aLineNumber, int aStartPosition)
|
||||
{
|
||||
final RE regexp = getRegexp();
|
||||
final boolean foundMatch = regexp.match(aLine, aStartPosition);
|
||||
if (foundMatch) {
|
||||
// match is found, check for intersection with comment
|
||||
int startCol = regexp.getParenStart(0);
|
||||
int endCol = regexp.getParenEnd(0);
|
||||
final FileContents fileContents = getFileContents();
|
||||
if (fileContents.hasIntersectionWithComment(aLineNumber,
|
||||
startCol, aLineNumber, endCol))
|
||||
{
|
||||
// was part of comment
|
||||
if (endCol < aLine.length()) {
|
||||
// check if the expression is on the rest of the line
|
||||
return findNonCommentMatch(aLine, aLineNumber, endCol);
|
||||
}
|
||||
else {
|
||||
// end of line reached
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// not intersecting with comment
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no match is found
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return the regexp to match against */
|
||||
public RE getRegexp()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,5 +17,7 @@ public class InputTrailingComment {
|
|||
/* c-style 1 */ /*c-style 2 */
|
||||
|
||||
void method2(long ms /* we should ignore this */) {
|
||||
/* comment before text */int z;
|
||||
/* int y */int y/**/;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,4 +68,143 @@ public class GenericIllegalRegexpCheckTest
|
|||
final String[] expectedFalse = {};
|
||||
verify(checkConfigFalse, getPath("InputSemantic.java"), expectedFalse);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsCppStyle()
|
||||
throws Exception
|
||||
{
|
||||
// See if the comment is removed properly
|
||||
final String illegal = "don't use trailing comments";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsFalseCppStyle()
|
||||
throws Exception
|
||||
{
|
||||
// See if the comment is removed properly
|
||||
final String illegal = "don't use trailing comments";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "false");
|
||||
final String[] expected = {
|
||||
"2: Line matches the illegal pattern '" + illegal + "'."
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsCStyle()
|
||||
throws Exception
|
||||
{
|
||||
// See if the comment is removed properly
|
||||
final String illegal = "c-style 1";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsFalseCStyle()
|
||||
throws Exception
|
||||
{
|
||||
final String illegal = "c-style 1";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "false");
|
||||
final String[] expected = {
|
||||
"17: Line matches the illegal pattern '" + illegal + "'."
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsMultipleCStyle()
|
||||
throws Exception
|
||||
{
|
||||
// See if a second comment on the same line is removed properly
|
||||
final String illegal = "c-style 2";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsMultiLine()
|
||||
throws Exception
|
||||
{
|
||||
final String illegal = "Let's check multi-line comments";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsInlineStart()
|
||||
throws Exception
|
||||
{
|
||||
final String illegal = "long ms /";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsInlineEnd()
|
||||
throws Exception
|
||||
{
|
||||
final String illegal = "int z";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
"20: Line matches the illegal pattern '" + illegal + "'."
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsInlineMiddle()
|
||||
throws Exception
|
||||
{
|
||||
final String illegal = "int y";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
"21: Line matches the illegal pattern '" + illegal + "'."
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
|
||||
public void testIgnoreCommentsNoSpaces()
|
||||
throws Exception
|
||||
{
|
||||
// make sure the comment is not turned into spaces
|
||||
final String illegal = "long ms ";
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(GenericIllegalRegexpCheck.class);
|
||||
checkConfig.addAttribute("format", illegal);
|
||||
checkConfig.addAttribute("ignoreComments", "true");
|
||||
final String[] expected = {
|
||||
};
|
||||
verify(checkConfig, getPath("InputTrailingComment.java"), expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue