Ignore comments in GenericIllegalRegexp check,

contributed by Daniel Grenner
This commit is contained in:
Lars Kühne 2004-02-29 13:43:28 +00:00
parent 22d0ed9d4c
commit 3ad02e2dcd
7 changed files with 283 additions and 1 deletions

View File

@ -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,

View File

@ -143,6 +143,8 @@
&lt;property&gt; 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">

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -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()
{

View File

@ -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/**/;
}
}

View File

@ -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);
}
}