Fixed the LeftCurly check to ignore leading annotations. Thanks to Tim Carpenter for patch #2506439. An excellent quality patch.

This commit is contained in:
Oliver Burn 2009-03-08 10:30:30 +00:00
parent 211e2414ae
commit ad34b2a35e
4 changed files with 153 additions and 5 deletions

View File

@ -126,7 +126,11 @@ public class LeftCurlyCheck
switch (aAST.getType()) {
case TokenTypes.CTOR_DEF :
case TokenTypes.METHOD_DEF :
startToken = aAST;
// Orig
//startToken = aAST;
// New
startToken = skipAnnotationOnlyLines(aAST);
// End
brace = aAST.findFirstToken(TokenTypes.SLIST);
break;
@ -135,11 +139,11 @@ public class LeftCurlyCheck
case TokenTypes.ANNOTATION_DEF :
case TokenTypes.ENUM_DEF :
case TokenTypes.ENUM_CONSTANT_DEF :
startToken = aAST.getFirstChild();
startToken = (DetailAST) skipAnnotationOnlyLines(aAST);
final DetailAST objBlock = aAST.findFirstToken(TokenTypes.OBJBLOCK);
brace = (objBlock == null)
? null
: objBlock.getFirstChild();
: (DetailAST) objBlock.getFirstChild();
break;
case TokenTypes.LITERAL_WHILE:
@ -156,7 +160,7 @@ public class LeftCurlyCheck
case TokenTypes.LITERAL_ELSE :
startToken = aAST;
final DetailAST candidate = aAST.getFirstChild();
final DetailAST candidate = (DetailAST) aAST.getFirstChild();
brace =
(candidate.getType() == TokenTypes.SLIST)
? candidate
@ -178,6 +182,62 @@ public class LeftCurlyCheck
}
}
/**
* Skip lines that only contain <code>TokenTypes.ANNOTATION</code>s.
* If the received <code>DetailAST</code>
* has annotations within its modifiers then first token on the line
* of the first token afer all annotations is return. This might be
* an annotation.
* Otherwise, the received <code>DetailAST</code> is returned.
* @param aAST <code>DetailAST</code>.
* @return <code>DetailAST</code>.
*/
private DetailAST skipAnnotationOnlyLines(DetailAST aAST)
{
final DetailAST modifiers = aAST.findFirstToken(TokenTypes.MODIFIERS);
if (modifiers == null) {
return aAST;
}
DetailAST lastAnnot = findLastAnnotation(modifiers);
if (lastAnnot == null) {
// There are no annotations.
return aAST;
}
final DetailAST tokenAfterLast = lastAnnot.getNextSibling() != null
? lastAnnot.getNextSibling()
: modifiers.getNextSibling();
if (tokenAfterLast.getLineNo() > lastAnnot.getLineNo()) {
return tokenAfterLast;
}
else {
final int lastAnnotLineNumber = lastAnnot.getLineNo();
while (lastAnnot.getPreviousSibling() != null
&& (lastAnnot.getPreviousSibling().getLineNo()
== lastAnnotLineNumber))
{
lastAnnot = lastAnnot.getPreviousSibling();
}
return lastAnnot;
}
}
/**
* Find the last token of type <code>TokenTypes.ANNOTATION</code>
* under the given set of modifiers.
* @param aModifiers <code>DetailAST</code>.
* @return <code>DetailAST</code> or null if there are no annotations.
*/
private DetailAST findLastAnnotation(DetailAST aModifiers)
{
DetailAST aAnnot = aModifiers.findFirstToken(TokenTypes.ANNOTATION);
while (aAnnot != null && aAnnot.getNextSibling() != null
&& aAnnot.getNextSibling().getType() == TokenTypes.ANNOTATION)
{
aAnnot = aAnnot.getNextSibling();
}
return aAnnot;
}
/**
* Verifies that a specified left curly brace is placed correctly
* according to policy.

View File

@ -0,0 +1,59 @@
package com.puppycrawl.tools.checkstyle;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
@TestClassAnnotation
class InputLeftCurlyAnnotations
{
private static final int X = 10;
@Override
public boolean equals(Object other)
{
return false;
}
@Override
@SuppressWarnings("unused")
public int hashCode()
{
int a = 10;
return 1;
}
@Override @SuppressWarnings({"unused", "unchecked", "static-access"}) public String toString()
{
Integer i = this.X;
List<String> l = new ArrayList();
return "SomeString";
}
}
@TestClassAnnotation
class InputLeftCurlyAnnotations2 {
private static final int X = 10;
@Override
public boolean equals(Object other) {
return false;
}
@Override
@SuppressWarnings("unused")
public int hashCode() {
int a = 10;
return 1;
}
@Override @SuppressWarnings({"unused", "unchecked", "static-access"}) public String toString()
{
Integer i = this.X;
List<String> l = new ArrayList();
return "SomeString";
}
}
@Target(ElementType.TYPE)
@interface TestClassAnnotation {
}

View File

@ -119,7 +119,7 @@ public class LeftCurlyCheckTest extends BaseCheckTestSupport
};
verify(mCheckConfig, getPath("InputLeftCurlyOther.java"), expected);
}
@Test
public void testNL3() throws Exception
{
@ -146,4 +146,28 @@ public class LeftCurlyCheckTest extends BaseCheckTestSupport
};
verify(mCheckConfig, getPath("InputBraces.java"), expected);
}
@Test
public void testDefaultWithAnnotations() throws Exception
{
final String[] expected = {
"10:1: '{' should be on the previous line.",
"14:5: '{' should be on the previous line.",
"21:5: '{' should be on the previous line."
};
verify(mCheckConfig, getPath("InputLeftCurlyAnnotations.java"), expected);
}
@Test
public void testNLWithAnnotations() throws Exception
{
mCheckConfig.addAttribute("option", LeftCurlyOption.NL.toString());
final String[] expected = {
"35:34: '{' should be on a new line.",
"38:41: '{' should be on a new line.",
"44:27: '{' should be on a new line.",
"58:32: '{' should be on a new line."
};
verify(mCheckConfig, getPath("InputLeftCurlyAnnotations.java"), expected);
}
}

View File

@ -112,6 +112,11 @@
user specifies a directory with the <i>-r</i> option that does
not contain any files. Thanks to Florian for patch #2151706.
</li>
<li>
Fixed the <a href="config_blocks.html#LeftCurly">LeftCurly</a> check
to ignore leading annotations. Thanks to Tim Carpenter for patch
#2506439.
</li>
</ul>
<p>Notes:</p>