summaryrefslogtreecommitdiff
path: root/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java')
-rw-r--r--java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java85
1 files changed, 44 insertions, 41 deletions
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
index 3bc0dc093fc8..686791e94c04 100644
--- a/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
@@ -15,11 +15,11 @@
*/
package com.intellij.compiler.notNullVerification;
+import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
import org.jetbrains.org.objectweb.asm.*;
-import java.util.ArrayList;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
/**
@@ -100,6 +100,15 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
myClassName = name;
}
+ private static class NotNullState {
+ @Nullable String message;
+ @NotNull String exceptionType;
+
+ NotNullState(String exceptionType) {
+ this.exceptionType = exceptionType;
+ }
+ }
+
@Override
public MethodVisitor visitMethod(final int access, final String name, String desc, String signature, String[] exceptions) {
final Type[] args = Type.getArgumentTypes(desc);
@@ -107,29 +116,32 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions);
final Map<Integer, String> paramNames = myMethodParamNames.get(myClassName + '.' + name + desc);
return new MethodVisitor(Opcodes.ASM5, v) {
-
- private final List<Integer> myNotNullParams = new ArrayList<Integer>();
+ private final Map<Integer, NotNullState> myNotNullParams = new LinkedHashMap<Integer, NotNullState>();
private int mySyntheticCount = 0;
- private boolean myIsNotNull = false;
- private String myMessage = null;
+ private NotNullState myMethodNotNull;
private Label myStartGeneratedCodeLabel;
+ private AnnotationVisitor collectNotNullArgs(AnnotationVisitor base, final NotNullState state) {
+ return new AnnotationVisitor(Opcodes.ASM5, base) {
+ @Override
+ public void visit(String methodName, Object o) {
+ if (ANNOTATION_DEFAULT_METHOD.equals(methodName) && !((String) o).isEmpty()) {
+ state.message = (String) o;
+ }
+ else if ("exception".equals(methodName) && o instanceof Type && !((Type)o).getClassName().equals(Exception.class.getName())) {
+ state.exceptionType = ((Type)o).getInternalName();
+ }
+ super.visit(methodName, o);
+ }
+ };
+ }
+
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String anno, final boolean visible) {
AnnotationVisitor av = mv.visitParameterAnnotation(parameter, anno, visible);
if (isReferenceType(args[parameter]) && anno.equals(NOT_NULL_TYPE)) {
- myNotNullParams.add(new Integer(parameter));
- av = new AnnotationVisitor(Opcodes.ASM5, 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);
- }
- };
+ NotNullState state = new NotNullState(IAE_CLASS_NAME);
+ myNotNullParams.put(new Integer(parameter), state);
+ av = collectNotNullArgs(av, state);
}
else if (anno.equals(SYNTHETIC_TYPE)) {
// see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail
@@ -143,19 +155,8 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
public AnnotationVisitor visitAnnotation(String anno, boolean isRuntime) {
AnnotationVisitor av = mv.visitAnnotation(anno, isRuntime);
if (isReferenceType(returnType) && anno.equals(NOT_NULL_TYPE)) {
- myIsNotNull = true;
- av = new AnnotationVisitor(Opcodes.ASM5, 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);
- }
- };
+ myMethodNotNull = new NotNullState(ISE_CLASS_NAME);
+ av = collectNotNullArgs(av, myMethodNotNull);
}
return av;
@@ -167,7 +168,8 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
myStartGeneratedCodeLabel = new Label();
mv.visitLabel(myStartGeneratedCodeLabel);
}
- for (Integer param : myNotNullParams) {
+ for (Map.Entry<Integer, NotNullState> entry : myNotNullParams.entrySet()) {
+ Integer param = entry.getKey();
int var = ((access & ACC_STATIC) == 0) ? 1 : 0;
for (int i = 0; i < param; ++i) {
var += args[i].getSize();
@@ -177,14 +179,15 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
Label end = new Label();
mv.visitJumpInsn(IFNONNULL, end);
+ NotNullState state = entry.getValue();
String paramName = paramNames == null ? null : paramNames.get(param);
- String descrPattern = myMessage != null
- ? myMessage
+ String descrPattern = state.message != null
+ ? state.message
: paramName != null ? NULL_ARG_MESSAGE_NAMED : NULL_ARG_MESSAGE_INDEXED;
- String[] args = myMessage != null
+ String[] args = state.message != null
? EMPTY_STRING_ARRAY
: new String[]{paramName != null ? paramName : String.valueOf(param - mySyntheticCount), myClassName, name};
- generateThrow(IAE_CLASS_NAME, end, descrPattern, args);
+ generateThrow(state.exceptionType, end, descrPattern, args);
}
}
@@ -199,13 +202,13 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
@Override
public void visitInsn(int opcode) {
if (opcode == ARETURN) {
- if (myIsNotNull) {
+ if (myMethodNotNull != null) {
mv.visitInsn(DUP);
final Label skipLabel = new Label();
mv.visitJumpInsn(IFNONNULL, skipLabel);
- String descrPattern = myMessage != null ? myMessage : NULL_RESULT_MESSAGE;
- String[] args = myMessage != null ? EMPTY_STRING_ARRAY : new String[]{myClassName, name};
- generateThrow(ISE_CLASS_NAME, skipLabel, descrPattern, args);
+ String descrPattern = myMethodNotNull.message != null ? myMethodNotNull.message : NULL_RESULT_MESSAGE;
+ String[] args = myMethodNotNull.message != null ? EMPTY_STRING_ARRAY : new String[]{myClassName, name};
+ generateThrow(myMethodNotNull.exceptionType, skipLabel, descrPattern, args);
}
}