mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
work around javac/asm parameter index mismatch when @NotNull-instrumenting enum constructors
This commit is contained in:
+21
-13
@@ -18,6 +18,8 @@ package com.intellij.compiler.notNullVerification;
|
||||
import com.intellij.compiler.instrumentation.FailSafeClassReader;
|
||||
import com.intellij.compiler.instrumentation.FailSafeMethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureReader;
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
@@ -30,8 +32,6 @@ import java.util.Set;
|
||||
* @author ven
|
||||
*/
|
||||
public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcodes {
|
||||
private static final String SYNTHETIC_CLASS_NAME = "java/lang/Synthetic";
|
||||
private static final String SYNTHETIC_TYPE = "L" + SYNTHETIC_CLASS_NAME + ";";
|
||||
private static final String IAE_CLASS_NAME = "java/lang/IllegalArgumentException";
|
||||
private static final String ISE_CLASS_NAME = "java/lang/IllegalStateException";
|
||||
|
||||
@@ -151,12 +151,15 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
}
|
||||
|
||||
final Type[] args = Type.getArgumentTypes(desc);
|
||||
|
||||
// see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail
|
||||
final int syntheticCount = signature == null ? 0 : Math.max(0, args.length - getSignatureParameterCount(signature));
|
||||
|
||||
final Type returnType = Type.getReturnType(desc);
|
||||
final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions);
|
||||
final Map<Integer, String> paramNames = myMethodParamNames.get(myClassName + '.' + name + desc);
|
||||
return new FailSafeMethodVisitor(Opcodes.API_VERSION, v) {
|
||||
private final Map<Integer, NotNullState> myNotNullParams = new LinkedHashMap<Integer, NotNullState>();
|
||||
private int mySyntheticCount = 0;
|
||||
private NotNullState myMethodNotNull;
|
||||
private Label myStartGeneratedCodeLabel;
|
||||
|
||||
@@ -185,20 +188,13 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
return checkNotNullMethod(desc, av);
|
||||
}
|
||||
if (ref.getSort() == TypeReference.METHOD_FORMAL_PARAMETER) {
|
||||
return checkNotNullParameter(ref.getFormalParameterIndex(), desc, av);
|
||||
return checkNotNullParameter(ref.getFormalParameterIndex() + syntheticCount, desc, av);
|
||||
}
|
||||
return av;
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String anno, final boolean visible) {
|
||||
AnnotationVisitor av = mv.visitParameterAnnotation(parameter, anno, visible);
|
||||
if (anno.equals(SYNTHETIC_TYPE)) {
|
||||
// see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail
|
||||
mySyntheticCount++;
|
||||
return av;
|
||||
}
|
||||
|
||||
return checkNotNullParameter(parameter, anno, av);
|
||||
return checkNotNullParameter(parameter, anno, mv.visitParameterAnnotation(parameter, anno, visible));
|
||||
}
|
||||
|
||||
private AnnotationVisitor checkNotNullParameter(int parameter, String anno, AnnotationVisitor av) {
|
||||
@@ -246,7 +242,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
String descrPattern = state.getNullParamMessage(paramName);
|
||||
String[] args = state.message != null
|
||||
? EMPTY_STRING_ARRAY
|
||||
: new String[]{paramName != null ? paramName : String.valueOf(param - mySyntheticCount), myClassName, name};
|
||||
: new String[]{paramName != null ? paramName : String.valueOf(param - syntheticCount), myClassName, name};
|
||||
reportError(state.exceptionType, end, descrPattern, args);
|
||||
}
|
||||
}
|
||||
@@ -297,6 +293,18 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
|
||||
};
|
||||
}
|
||||
|
||||
private static int getSignatureParameterCount(String signature) {
|
||||
final int[] count = {0};
|
||||
new SignatureReader(signature).accept(new SignatureVisitor(Opcodes.ASM6) {
|
||||
@Override
|
||||
public SignatureVisitor visitParameterType() {
|
||||
count[0]++;
|
||||
return super.visitParameterType();
|
||||
}
|
||||
});
|
||||
return count[0];
|
||||
}
|
||||
|
||||
private static boolean isReferenceType(final Type type) {
|
||||
return type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface TypeUseNotNull {}
|
||||
|
||||
enum TypeUseInEnumConstructor {
|
||||
Foo(null, "a", "b");
|
||||
|
||||
TypeUseInEnumConstructor(String nuS, @TypeUseNotNull String nnS, @TypeUseNotNull String nnS2) {
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -190,6 +190,11 @@ public class NotNullVerifyingInstrumenterTest extends UsefulTestCase {
|
||||
test.getMethod("foo3", List.class).invoke(instance, (List)null);
|
||||
}
|
||||
|
||||
public void testTypeUseInEnumConstructor() throws Exception {
|
||||
Class<?> test = prepareTest(false, "TypeUseNotNull");
|
||||
assertSize(1, test.getEnumConstants());
|
||||
}
|
||||
|
||||
public void testTypeUseAndMemberAnnotations() throws Exception {
|
||||
Class<?> test = prepareTest(false, "FooAnno");
|
||||
Object instance = test.newInstance();
|
||||
|
||||
Reference in New Issue
Block a user