mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-146460 Assertions aren't generated for @NotNull method parameters and return types if @NotNull assertion is changed to TYPE_USE only
This commit is contained in:
+30
-11
@@ -145,7 +145,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(final int access, final String name, String desc, String signature, String[] exceptions) {
|
||||
public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature, String[] exceptions) {
|
||||
if ((access & Opcodes.ACC_BRIDGE) != 0) {
|
||||
return new FailSafeMethodVisitor(Opcodes.API_VERSION, super.visitMethod(access, name, desc, signature, exceptions));
|
||||
}
|
||||
@@ -175,16 +175,33 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
};
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String anno, final boolean visible) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(parameter, anno, visible);
|
||||
if (isReferenceType(args[parameter]) && myNotNullAnnos.contains(anno)) {
|
||||
NotNullState state = new NotNullState(anno, IAE_CLASS_NAME);
|
||||
myNotNullParams.put(new Integer(parameter), state);
|
||||
av = collectNotNullArgs(av, state);
|
||||
@Override
|
||||
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
|
||||
TypeReference ref = new TypeReference(typeRef);
|
||||
if (ref.getSort() == TypeReference.METHOD_RETURN) {
|
||||
return checkNotNullMethod(desc, mv.visitTypeAnnotation(typeRef, typePath, desc, visible));
|
||||
}
|
||||
else if (anno.equals(SYNTHETIC_TYPE)) {
|
||||
if (ref.getSort() == TypeReference.METHOD_FORMAL_PARAMETER) {
|
||||
return checkNotNullParameter(ref.getFormalParameterIndex(), desc, mv.visitTypeAnnotation(typeRef, typePath, desc, visible));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String anno, final boolean visible) {
|
||||
if (anno.equals(SYNTHETIC_TYPE)) {
|
||||
// see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail
|
||||
mySyntheticCount++;
|
||||
return null;
|
||||
}
|
||||
|
||||
return checkNotNullParameter(parameter, anno, mv.visitParameterAnnotation(parameter, anno, visible));
|
||||
}
|
||||
|
||||
private AnnotationVisitor checkNotNullParameter(int parameter, String anno, AnnotationVisitor av) {
|
||||
if (isReferenceType(args[parameter]) && myNotNullAnnos.contains(anno)) {
|
||||
NotNullState state = new NotNullState(anno, IAE_CLASS_NAME);
|
||||
myNotNullParams.put(parameter, state);
|
||||
return collectNotNullArgs(av, state);
|
||||
}
|
||||
|
||||
return av;
|
||||
@@ -192,12 +209,14 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String anno, boolean isRuntime) {
|
||||
AnnotationVisitor av = mv.visitAnnotation(anno, isRuntime);
|
||||
return checkNotNullMethod(anno, mv.visitAnnotation(anno, isRuntime));
|
||||
}
|
||||
|
||||
private AnnotationVisitor checkNotNullMethod(String anno, AnnotationVisitor av) {
|
||||
if (isReferenceType(returnType) && myNotNullAnnos.contains(anno)) {
|
||||
myMethodNotNull = new NotNullState(anno, ISE_CLASS_NAME);
|
||||
av = collectNotNullArgs(av, myMethodNotNull);
|
||||
return collectNotNullArgs(av, myMethodNotNull);
|
||||
}
|
||||
|
||||
return av;
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.TYPE_USE, ElementType.METHOD, ElementType.PARAMETER})
|
||||
@interface FooAnno {}
|
||||
|
||||
public class TypeUseAndMemberAnnotations {
|
||||
@FooAnno
|
||||
public Object foo1() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object foo2(@FooAnno String arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface FooAnno {}
|
||||
|
||||
public class TypeUseOnlyAnnotations {
|
||||
@FooAnno
|
||||
public Object foo1() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object foo2(@FooAnno String arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+15
-1
@@ -182,6 +182,20 @@ public class NotNullVerifyingInstrumenterTest extends UsefulTestCase {
|
||||
verifyCallThrowsException("@BarAnno method MultipleAnnotations.foo2 must not return null", instance, test.getMethod("foo2"));
|
||||
}
|
||||
|
||||
public void testTypeUseOnlyAnnotations() throws Exception {
|
||||
Class<?> test = prepareTest(false, "FooAnno");
|
||||
Object instance = test.newInstance();
|
||||
verifyCallThrowsException("@FooAnno method TypeUseOnlyAnnotations.foo1 must not return null", instance, test.getMethod("foo1"));
|
||||
verifyCallThrowsException("Argument 0 for @FooAnno parameter of TypeUseOnlyAnnotations.foo2 must not be null", instance, test.getMethod("foo2", String.class), (String)null);
|
||||
}
|
||||
|
||||
public void testTypeUseAndMemberAnnotations() throws Exception {
|
||||
Class<?> test = prepareTest(false, "FooAnno");
|
||||
Object instance = test.newInstance();
|
||||
verifyCallThrowsException("@FooAnno method TypeUseAndMemberAnnotations.foo1 must not return null", instance, test.getMethod("foo1"));
|
||||
verifyCallThrowsException("Argument 0 for @FooAnno parameter of TypeUseAndMemberAnnotations.foo2 must not be null", instance, test.getMethod("foo2", String.class), (String)null);
|
||||
}
|
||||
|
||||
public void testMalformedBytecode() throws Exception {
|
||||
Class<?> testClass = prepareTest(false, AnnotationUtil.NOT_NULL);
|
||||
verifyCallThrowsException("Argument 0 for @NotNull parameter of MalformedBytecode$NullTest2.handle must not be null", null, testClass.getMethod("main"));
|
||||
@@ -246,7 +260,7 @@ public class NotNullVerifyingInstrumenterTest extends UsefulTestCase {
|
||||
mainClass = aClass;
|
||||
}
|
||||
}
|
||||
assertTrue(modified);
|
||||
assertTrue("Class file not instrumented!", modified);
|
||||
assertNotNull("Class " + baseClassName + " not found!", mainClass);
|
||||
return mainClass;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user