diff options
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.java | 85 |
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); } } |