Skip to content

Commit

Permalink
Fix issue #45: Forbidden java.lang.Deprecated is not always reported …
Browse files Browse the repository at this point in the history
…(if class is deprecated "the old style only" - via javadocs)
  • Loading branch information
uschindler committed Dec 24, 2014
1 parent fc33b08 commit 209a005
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/main/java/de/thetaphi/forbiddenapis/Checker.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
*/
public abstract class Checker {

static final Type DEPRECATED_TYPE = Type.getType(Deprecated.class);
static final String DEPRECATED_DESCRIPTOR = DEPRECATED_TYPE.getDescriptor();

public final boolean isSupportedJDK;

private final long start;
Expand Down Expand Up @@ -369,6 +372,7 @@ private int checkClass(final ClassReader reader) {
reader.accept(new ClassVisitor(Opcodes.ASM5) {
final String className = Type.getObjectType(reader.getClassName()).getClassName();
String source = null;
boolean isDeprecated = false;

ClassSignatureLookup lookupRelatedClass(String internalName) {
final Type type = Type.getObjectType(internalName);
Expand Down Expand Up @@ -486,7 +490,11 @@ private void reportClassViolation(boolean violation, String where) {

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
this.isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0;
reportClassViolation(checkClassDefinition(superName, interfaces), "class declaration");
if (this.isDeprecated) {
reportClassViolation(checkType(DEPRECATED_TYPE), "deprecation on class declaration");
}
}

@Override
Expand All @@ -496,7 +504,13 @@ public void visitSource(String source, String debug) {

@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (visible) reportClassViolation(checkDescriptor(desc), "annotation on class declaration");
if (this.isDeprecated && DEPRECATED_DESCRIPTOR.equals(desc)) {
// don't report 2 times!
return null;
}
if (visible) {
reportClassViolation(checkDescriptor(desc), "annotation on class declaration");
}
return null;
}

Expand All @@ -509,16 +523,26 @@ public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, Str
@Override
public FieldVisitor visitField(final int access, final String name, final String desc, String signature, Object value) {
return new FieldVisitor(Opcodes.ASM5) {
final boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0;
{
// only check signature, if field is not synthetic
if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
reportFieldViolation(checkDescriptor(desc), "field declaration");
}
if (this.isDeprecated) {
reportFieldViolation(checkType(DEPRECATED_TYPE), "deprecation on field declaration");
}
}

@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (visible) reportFieldViolation(checkDescriptor(desc), "annotation on field declaration");
if (this.isDeprecated && DEPRECATED_DESCRIPTOR.equals(desc)) {
// don't report 2 times!
return null;
}
if (visible) {
reportFieldViolation(checkDescriptor(desc), "annotation on field declaration");
}
return null;
}

Expand Down Expand Up @@ -546,13 +570,17 @@ private void reportFieldViolation(boolean violation, String where) {
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature, String[] exceptions) {
return new MethodVisitor(Opcodes.ASM5) {
final boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0;
private int lineNo = -1;

{
// only check signature, if method is not synthetic
if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
reportMethodViolation(checkDescriptor(desc), "method declaration");
}
if (this.isDeprecated) {
reportMethodViolation(checkType(DEPRECATED_TYPE), "deprecation on method declaration");
}
}

private boolean checkMethodAccess(String owner, Method method) {
Expand Down Expand Up @@ -649,7 +677,13 @@ public void visitFieldInsn(int opcode, String owner, String name, String desc) {

@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (visible) reportMethodViolation(checkDescriptor(desc), "annotation on method declaration");
if (this.isDeprecated && DEPRECATED_DESCRIPTOR.equals(desc)) {
// don't report 2 times!
return null;
}
if (visible) {
reportMethodViolation(checkDescriptor(desc), "annotation on method declaration");
}
return null;
}

Expand Down
Binary file added src/test/antunit/Java5DeprecatedAnnotation.class
Binary file not shown.
26 changes: 26 additions & 0 deletions src/test/antunit/Java5DeprecatedAnnotation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* (C) Copyright 2014 Uwe Schindler (Generics Policeman) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* The binary class file is packaged together with the source distribution.
*/

class Java5DeprecatedAnnotation {

/** @deprecated **/
public Java5DeprecatedAnnotation() {
}

}
11 changes: 11 additions & 0 deletions src/test/antunit/TestAnnotations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,15 @@
<au:assertLogContains level="error" text=" 15 error(s)"/>
</target>

<target name="testMissingDeprecatedAnnotation">
<au:expectfailure expectedMessage="Check for forbidden API calls failed, see log">
<forbiddenapis failOnMissingClasses="true" classpath="${basedir}">
<fileset file="Java5DeprecatedAnnotation.class"/>
java.lang.Deprecated @ Deprecated annotation
</forbiddenapis>
</au:expectfailure>
<au:assertLogContains level="error" text="java.lang.Deprecated [Deprecated annotation]"/>
<au:assertLogContains level="error" text=" 1 error(s)"/>
</target>

</project>

0 comments on commit 209a005

Please sign in to comment.