Issue #903: Skip type annotations from validation of ModifierOrderCheck

This commit is contained in:
Andrei Selkin 2016-02-14 11:25:21 +03:00 committed by Roman Ivanov
parent 0fe6a55348
commit 4c3a5dcdd0
4 changed files with 123 additions and 2 deletions

View File

@ -154,8 +154,10 @@ public class ModifierOrderCheck
&& offendingModifier == null) {
if (modifier.getType() == TokenTypes.ANNOTATION) {
//Annotation not at start of modifiers, bad
offendingModifier = modifier;
if (!isAnnotationOnType(modifier)) {
//Annotation not at start of modifiers, bad
offendingModifier = modifier;
}
break;
}
@ -193,4 +195,20 @@ public class ModifierOrderCheck
while (modifierIterator.hasNext() && modifier.getType() == TokenTypes.ANNOTATION);
return modifier;
}
/**
* Checks whether annotation on type takes place.
* @param modifier modifier token.
* @return true if annotation on type takes place.
*/
private static boolean isAnnotationOnType(DetailAST modifier) {
boolean annotationOnType = false;
final DetailAST modifiers = modifier.getParent();
final int definitionTokenType = modifiers.getParent().getType();
if (definitionTokenType == TokenTypes.VARIABLE_DEF
|| definitionTokenType == TokenTypes.PARAMETER_DEF) {
annotationOnType = true;
}
return annotationOnType;
}
}

View File

@ -110,4 +110,15 @@ public class ModifierOrderCheckTest
Assert.assertNotSame(unexpectedArray, actual);
Assert.assertNotNull(actual);
}
@Test
public void testSkipTypeAnnotations() throws Exception {
// Type Annotations are avaliable only in Java 8
// We skip type annotations from validation
// See https://github.com/checkstyle/checkstyle/issues/903#issuecomment-172228013
final DefaultConfiguration checkConfig =
createCheckConfig(ModifierOrderCheck.class);
final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY;
verify(checkConfig, getNonCompilablePath("InputTypeAnnotations.java"), expected);
}
}

View File

@ -0,0 +1,86 @@
//Compilable with Java8
package com.puppycrawl.tools.checkstyle.checks.modifier;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class InputTypeAnnotations {
// Simple type definitions with type annotations
private @TypeAnnotation String hello = "Hello, World!";
private @TypeAnnotation final String jdk = "JDK8";
@TypeAnnotation private String projectName = "Checkstyle";
// We can use type Annotations with generic type arguments
private Map.@TypeAnnotation Entry entry;
// Type annotations can also be applied to nested types
private List<@TypeAnnotation String> strings;
// Constructors with type annotations
{
new @TypeAnnotation Object();
}
static {
new @TypeAnnotation Object();
}
public void foo1() {
new @TypeAnnotation Object();
}
// Type annotations work with nested (non static) class constructors too
public void foo2() {
InputTypeAnnotations myObject = new InputTypeAnnotations();
myObject.new @TypeAnnotation Nested();
}
// Type casts
public void foo3() {
String myString = (@TypeAnnotation String) new Object();
}
// Type annotations with method arguments
private void foo4(final @TypeAnnotation String parameterName) { }
// Inheritance
class MySerializableClass<T> implements @TypeAnnotation Serializable { }
// Nested type annotations
Map<@TypeAnnotation String, @TypeAnnotation List<@TypeAnnotation String>> documents;
// Apply type annotations to intersection types
public <E extends @TypeAnnotation Comparator<E> & @TypeAnnotation Comparable> void foo5() { }
// Including parameter bounds and wildcard bounds
class Folder<F extends @TypeAnnotation File> { }
Collection<? super @TypeAnnotation File> c;
List<@TypeAnnotation ? extends Comparable<T>> unchangeable;
// Throwing exceptions
void foo6() throws @TypeAnnotation IOException { }
// Type annotations in instanceof statements
public void foo7() {
boolean isNonNull = "string" instanceof @TypeAnnotation String;
}
class Nested { }
class T { }
}
@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER,
ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@interface TypeAnnotation {
}

View File

@ -66,6 +66,12 @@
<code>strictfp</code>
</li>
</ol>
<p>
ATTENTION: We skip <a href="https://blogs.oracle.com/java-platform-group/entry/java_8_s_new_type">
type annotations</a> from validation.
</p>
</subsection>
<subsection name="Examples">