mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
IDEABKL-6771 Add optional parameter 'exceptionMessage' to @NotNull annotation
This commit is contained in:
+30
-4
@@ -34,6 +34,8 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
private static final String CONSTRUCTOR_NAME = "<init>";
|
||||
private static final String EXCEPTION_INIT_SIGNATURE = "(L" + STRING_CLASS_NAME + ";)V";
|
||||
|
||||
private static final String ANNOTATION_DEFAULT_METHOD = "value";
|
||||
|
||||
private static final String NULL_ARG_MESSAGE = "Argument %d for @NotNull parameter of %s.%s must not be null";
|
||||
private static final String NULL_RESULT_MESSAGE = "@NotNull method %s.%s must not return null";
|
||||
|
||||
@@ -65,6 +67,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
private final List<Integer> myNotNullParams = new ArrayList<Integer>();
|
||||
private int mySyntheticCount = 0;
|
||||
private boolean myIsNotNull = false;
|
||||
private String myMessage = null;
|
||||
private Label myStartGeneratedCodeLabel;
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String anno, final boolean visible) {
|
||||
@@ -76,7 +79,19 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
// see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail
|
||||
mySyntheticCount++;
|
||||
}
|
||||
return av;
|
||||
|
||||
return new AnnotationVisitor(Opcodes.ASM4, av) {
|
||||
@Override
|
||||
public void visit(String methodName, Object o) {
|
||||
if(ANNOTATION_DEFAULT_METHOD.equals(methodName)) {
|
||||
String message = (String) o;
|
||||
if(!message.isEmpty()) {
|
||||
myMessage = message;
|
||||
}
|
||||
}
|
||||
super.visit(methodName, o);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,7 +101,18 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
myIsNotNull = true;
|
||||
}
|
||||
|
||||
return av;
|
||||
return new AnnotationVisitor(Opcodes.ASM4, av) {
|
||||
@Override
|
||||
public void visit(String methodName, Object o) {
|
||||
if(ANNOTATION_DEFAULT_METHOD.equals(methodName)) {
|
||||
String message = (String) o;
|
||||
if(!message.isEmpty()) {
|
||||
myMessage = message;
|
||||
}
|
||||
}
|
||||
super.visit(methodName, o);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,7 +131,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
Label end = new Label();
|
||||
mv.visitJumpInsn(IFNONNULL, end);
|
||||
|
||||
generateThrow(IAE_CLASS_NAME, String.format(NULL_ARG_MESSAGE, param - mySyntheticCount, myClassName, name), end);
|
||||
generateThrow(IAE_CLASS_NAME, myMessage == null ? String.format(NULL_ARG_MESSAGE, param - mySyntheticCount, myClassName, name) : myMessage, end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +150,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
mv.visitInsn(DUP);
|
||||
final Label skipLabel = new Label();
|
||||
mv.visitJumpInsn(IFNONNULL, skipLabel);
|
||||
generateThrow(ISE_CLASS_NAME, String.format(NULL_RESULT_MESSAGE, myClassName, name), skipLabel);
|
||||
generateThrow(ISE_CLASS_NAME, myMessage == null ? String.format(NULL_RESULT_MESSAGE, myClassName, name) : myMessage, skipLabel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConstructorParamWithMessage {
|
||||
public ConstructorParamWithMessage(@NotNull("ConstructorParam.ConstructorParam.o cant be null") Object o) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SimpleParamWithMessage {
|
||||
public void test(@NotNull("SimpleParamWithMessage.test(o) cant be null") Object o) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SimpleReturnWithMessage {
|
||||
@NotNull("This method cannot return null")
|
||||
public Object test() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+20
@@ -70,6 +70,13 @@ public class NotNullVerifyingInstrumenterTest extends UsefulTestCase {
|
||||
verifyCallThrowsException("@NotNull method SimpleReturn.test must not return null", instance, method);
|
||||
}
|
||||
|
||||
public void testSimpleReturnWithMessage() throws Exception {
|
||||
Class testClass = prepareTest();
|
||||
Object instance = testClass.newInstance();
|
||||
Method method = testClass.getMethod("test");
|
||||
verifyCallThrowsException("This method cannot return null", instance, method);
|
||||
}
|
||||
|
||||
public void testMultipleReturns() throws Exception {
|
||||
Class testClass = prepareTest();
|
||||
Object instance = testClass.newInstance();
|
||||
@@ -84,12 +91,25 @@ public class NotNullVerifyingInstrumenterTest extends UsefulTestCase {
|
||||
verifyCallThrowsException("Argument 0 for @NotNull parameter of SimpleParam.test must not be null", instance, method, (Object)null);
|
||||
}
|
||||
|
||||
public void testSimpleParamWithMessage() throws Exception {
|
||||
Class testClass = prepareTest();
|
||||
Object instance = testClass.newInstance();
|
||||
Method method = testClass.getMethod("test", Object.class);
|
||||
verifyCallThrowsException("SimpleParamWithMessage.test(o) cant be null", instance, method, (Object)null);
|
||||
}
|
||||
|
||||
public void testConstructorParam() throws Exception {
|
||||
Class testClass = prepareTest();
|
||||
Constructor method = testClass.getConstructor(Object.class);
|
||||
verifyCallThrowsException("Argument 0 for @NotNull parameter of ConstructorParam.<init> must not be null", null, method, (Object)null);
|
||||
}
|
||||
|
||||
public void testConstructorParamWithMessage() throws Exception {
|
||||
Class testClass = prepareTest();
|
||||
Constructor method = testClass.getConstructor(Object.class);
|
||||
verifyCallThrowsException("ConstructorParam.ConstructorParam.o cant be null", null, method, (Object)null);
|
||||
}
|
||||
|
||||
public void testEnumConstructor() throws Exception {
|
||||
Class testClass = prepareTest();
|
||||
Object field = testClass.getField("Value");
|
||||
|
||||
Reference in New Issue
Block a user