From 5276c18bcb39772c9cddd20daeef7e3dff777c1a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 24 Sep 2018 15:59:19 +0200 Subject: [PATCH] [java] makes not-null instrumenter compatible with ASM 6.2 (IDEA-191331) --- .../NotNullVerifyingInstrumenter.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 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 fc4241e37e59..4b57a2e794ae 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 @@ -25,14 +25,17 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode @SuppressWarnings("SSBasedInspection") private static final String[] EMPTY_STRING_ARRAY = new String[0]; + @SuppressWarnings("ConstantConditions") private static final boolean NEW_ASM = Opcodes.API_VERSION > Opcodes.ASM6; + private final Map> myMethodParamNames; private String myClassName; private boolean myIsModification = false; private RuntimeException myPostponedError; private final AuxiliaryMethodGenerator myAuxGenerator; private final Set myNotNullAnnotations = new HashSet(); - private boolean myStatic; + private boolean myEnum; private boolean myInner; + private boolean myEnclosed; private NotNullVerifyingInstrumenter(ClassVisitor classVisitor, ClassReader reader, String[] notNullAnnotations) { super(Opcodes.API_VERSION, classVisitor); @@ -95,13 +98,21 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); myClassName = name; - myStatic = isStatic(access); + myEnum = (access & ACC_ENUM) != 0; + } + + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + super.visitInnerClass(name, outerName, innerName, access); + if (myClassName.equals(name)) { + myInner = (access & ACC_STATIC) == 0; + } } @Override public void visitOuterClass(String owner, String name, String desc) { super.visitOuterClass(owner, name, desc); - myInner = true; + myEnclosed = true; } private static class NotNullState { @@ -141,11 +152,13 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode final boolean isStatic = isStatic(access); final Type[] args = Type.getArgumentTypes(desc); - boolean hasOuterClassParameter = myInner && !myStatic && "".equals(name); + boolean hasOuterClassParameter = myEnclosed && myInner && "".equals(name); // see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail final int syntheticCount = signature == null ? 0 : hasOuterClassParameter ? 1 : Math.max(0, args.length - getSignatureParameterCount(signature)); // workaround for ASM workaround for javac bug: http://forge.ow2.org/tracker/?func=detail&aid=317788&group_id=23&atid=100023 - final int paramAnnotationOffset = signature == null ? 0 : hasOuterClassParameter ? Math.max(0, args.length - getSignatureParameterCount(signature) - 1) : 0; + final int paramAnnotationOffset = !"".equals(name) ? 0 : NEW_ASM + ? (myEnum ? -2 : myInner ? -1 : 0) + : signature != null && hasOuterClassParameter ? Math.max(0, args.length - getSignatureParameterCount(signature) - 1) : 0; final Type returnType = Type.getReturnType(desc); final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions); @@ -188,7 +201,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode @Override public AnnotationVisitor visitParameterAnnotation(int parameter, String anno, boolean visible) { AnnotationVisitor base = mv.visitParameterAnnotation(parameter, anno, visible); - if (parameter < paramAnnotationOffset) return base; + if (!NEW_ASM && parameter < paramAnnotationOffset) return base; return checkNotNullParameter(parameter - paramAnnotationOffset, anno, base); }