List of usage examples for org.objectweb.asm.tree MethodInsnNode getPrevious
public AbstractInsnNode getPrevious()
From source file:com.android.ide.eclipse.apt.internal.analysis.InnerClassAnalyzer.java
License:Apache License
/** * Checks if a method of an inner class accesses the private content of an outer class (field or method) * @param methodNode//from w w w. j a v a2 s . c o m * @param method * @return True if the outer access is confirmed, false otherwise. */ private boolean confirmParentClassAccess(final MethodNode methodNode, final MethodInsnNode method) { final String methodNodeName = methodNode.name; AbstractInsnNode prev = method.getPrevious(); boolean result = false; while (!result) { if (methodNodeName.startsWith("<init>")) { if (prev.getOpcode() == Opcodes.ALOAD) { final VarInsnNode varInsn = (VarInsnNode) prev; result = varInsn.var == 1; } } else { if (prev.getOpcode() == Opcodes.GETFIELD) { final FieldInsnNode getField = (FieldInsnNode) prev; final String field = getField.owner + getField.name; final String testField = mInnerClass.name + "this$0"; result = field.equals(testField); } } if (prev.getType() == AbstractInsnNode.LINE) { break; } else { prev = prev.getPrevious(); } } return result; }
From source file:com.android.tools.lint.checks.WakelockDetector.java
License:Apache License
/** Search from the given node towards the target; return false if we reach * an exit point such as a return or a call on the way there that is not within * a try/catch clause./*from w w w. ja va2 s .com*/ * * @param node the current node * @return true if the target was reached * XXX RETURN VALUES ARE WRONG AS OF RIGHT NOW */ protected int dfs(ControlFlowGraph.Node node) { AbstractInsnNode instruction = node.instruction; if (instruction.getType() == AbstractInsnNode.JUMP_INSN) { int opcode = instruction.getOpcode(); if (opcode == Opcodes.RETURN || opcode == Opcodes.ARETURN || opcode == Opcodes.LRETURN || opcode == Opcodes.IRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.ATHROW) { if (DEBUG) { System.out.println("Found exit via explicit return: " //$NON-NLS-1$ + node.toString(false)); } return SEEN_RETURN; } } if (!DEBUG) { // There are no cycles, so no *NEED* for this, though it does avoid // researching shared labels. However, it makes debugging harder (no re-entry) // so this is only done when debugging is off if (node.visit != 0) { return 0; } node.visit = 1; } // Look for the target. This is any method call node which is a release on the // lock (later also check it's the same instance, though that's harder). // This is because finally blocks tend to be inlined so from a single try/catch/finally // with a release() in the finally, the bytecode can contain multiple repeated // (inlined) release() calls. if (instruction.getType() == AbstractInsnNode.METHOD_INSN) { MethodInsnNode method = (MethodInsnNode) instruction; if (method.name.equals(RELEASE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) { return SEEN_TARGET; } else if (method.name.equals(ACQUIRE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) { // OK } else if (method.name.equals(IS_HELD_METHOD) && method.owner.equals(WAKELOCK_OWNER)) { // OK } else { // Some non acquire/release method call: if this is not associated with a // try-catch block, it would mean the exception would exit the method, // which would be an error if (node.exceptions == null || node.exceptions.isEmpty()) { // Look up the corresponding frame, if any AbstractInsnNode curr = method.getPrevious(); boolean foundFrame = false; while (curr != null) { if (curr.getType() == AbstractInsnNode.FRAME) { foundFrame = true; break; } curr = curr.getPrevious(); } if (!foundFrame) { if (DEBUG) { System.out.println("Found exit via unguarded method call: " //$NON-NLS-1$ + node.toString(false)); } return SEEN_RETURN; } } } } // if (node.instruction is a call, and the call is not caught by // a try/catch block (provided the release is not inside the try/catch block) // then return false int status = 0; boolean implicitReturn = true; List<Node> successors = node.successors; List<Node> exceptions = node.exceptions; if (exceptions != null) { if (!exceptions.isEmpty()) { implicitReturn = false; } for (Node successor : exceptions) { status = dfs(successor) | status; if ((status & SEEN_RETURN) != 0) { if (DEBUG) { System.out.println("Found exit via exception: " //$NON-NLS-1$ + node.toString(false)); } return status; } } if (status != 0) { status |= SEEN_EXCEPTION; } } if (successors != null) { if (!successors.isEmpty()) { implicitReturn = false; if (successors.size() > 1) { status |= SEEN_BRANCH; } } for (Node successor : successors) { status = dfs(successor) | status; if ((status & SEEN_RETURN) != 0) { if (DEBUG) { System.out.println("Found exit via branches: " //$NON-NLS-1$ + node.toString(false)); } return status; } } } if (implicitReturn) { status |= SEEN_RETURN; if (DEBUG) { System.out.println("Found exit: via implicit return: " //$NON-NLS-1$ + node.toString(false)); } } return status; }
From source file:com.microsoft.Malmo.OverclockingClassTransformer.java
License:Open Source License
private static void overclockRenderer(ClassNode node, boolean isObfuscated) { // We're attempting to turn this line from Minecraft.runGameLoop: // this.updateDisplay(); // into this: // TimeHelper.updateDisplay(); // TimeHelper's method then decides whether or not to pass the call on to Minecraft.updateDisplay(). final String methodName = isObfuscated ? "as" : "runGameLoop"; final String methodDescriptor = "()V"; // No params, returns void. System.out.println("MALMO: Found Minecraft, attempting to transform it"); for (MethodNode method : node.methods) { if (method.name.equals(methodName) && method.desc.equals(methodDescriptor)) { System.out.println("MALMO: Found Minecraft.runGameLoop() method, attempting to transform it"); for (AbstractInsnNode instruction : method.instructions.toArray()) { if (instruction.getOpcode() == Opcodes.INVOKEVIRTUAL) { MethodInsnNode visitMethodNode = (MethodInsnNode) instruction; if (visitMethodNode.name.equals(isObfuscated ? "h" : "updateDisplay")) { visitMethodNode.owner = "com/microsoft/Malmo/Utils/TimeHelper"; if (isObfuscated) { visitMethodNode.name = "updateDisplay"; }//from w w w .ja v a 2 s. c o m visitMethodNode.setOpcode(Opcodes.INVOKESTATIC); method.instructions.remove(visitMethodNode.getPrevious()); // ALOAD 0 not needed for static invocation. System.out.println("MALMO: Hooked into call to Minecraft.updateDisplay()"); } } } } } }
From source file:cuchaz.enigma.CompiledSourceTypeLoader.java
License:Open Source License
private void removeRedundantClassCalls(ClassNode node) { // remove <obj>.getClass() calls that are seemingly injected // DUP/*from w ww.j a va 2 s. c om*/ // INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class; // POP for (MethodNode methodNode : node.methods) { AbstractInsnNode insnNode = methodNode.instructions.getFirst(); while (insnNode != null) { if (insnNode instanceof MethodInsnNode && insnNode.getOpcode() == Opcodes.INVOKEVIRTUAL) { MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode; if (methodInsnNode.name.equals("getClass") && methodInsnNode.owner.equals("java/lang/Object") && methodInsnNode.desc.equals("()Ljava/lang/Class;")) { AbstractInsnNode previous = methodInsnNode.getPrevious(); AbstractInsnNode next = methodInsnNode.getNext(); if (previous.getOpcode() == Opcodes.DUP && next.getOpcode() == Opcodes.POP) { insnNode = previous.getPrevious();//reset the iterator so it gets the new next instruction methodNode.instructions.remove(previous); methodNode.instructions.remove(methodInsnNode); methodNode.instructions.remove(next); } } } insnNode = insnNode.getNext(); } } }
From source file:cuchaz.enigma.TranslatingTypeLoader.java
License:Open Source License
private byte[] loadType(String className) { // NOTE: don't know if class name is obf or deobf ClassEntry classEntry = new ClassEntry(className); ClassEntry obfClassEntry = this.obfuscatingTranslator.getTranslatedClass(classEntry); // is this an inner class referenced directly? (ie trying to load b instead of a$b) if (!obfClassEntry.isInnerClass()) { List<ClassEntry> classChain = this.jarIndex.getObfClassChain(obfClassEntry); if (classChain.size() > 1) { System.err.println(String.format("WARNING: no class %s after inner class reconstruction. Try %s", className, obfClassEntry.buildClassEntry(classChain))); return null; }/* w w w . j ava 2s . c om*/ } // is this a class we should even know about? if (!this.jarIndex.containsObfClass(obfClassEntry)) { return null; } // DEBUG //System.out.println(String.format("Looking for %s (obf: %s)", classEntry.getName(), obfClassEntry.getName())); // find the class in the jar ClassNode node = findClassInJar(obfClassEntry); if (node == null) { // couldn't find it return null; } // remove <obj>.getClass() calls that are seemingly injected // DUP // INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class; // POP for (MethodNode methodNode : node.methods) { AbstractInsnNode insnNode = methodNode.instructions.getFirst(); while (insnNode != null) { if (insnNode instanceof MethodInsnNode && insnNode.getOpcode() == Opcodes.INVOKEVIRTUAL) { MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode; if (methodInsnNode.name.equals("getClass") && methodInsnNode.owner.equals("java/lang/Object") && methodInsnNode.desc.equals("()Ljava/lang/Class;")) { AbstractInsnNode previous = methodInsnNode.getPrevious(); AbstractInsnNode next = methodInsnNode.getNext(); if (previous.getOpcode() == Opcodes.DUP && next.getOpcode() == Opcodes.POP) { insnNode = previous.getPrevious();//reset the iterator so it gets the new next instruction methodNode.instructions.remove(previous); methodNode.instructions.remove(methodInsnNode); methodNode.instructions.remove(next); } } } insnNode = insnNode.getNext(); } } ClassWriter writer = new ClassWriter(0); transformInto(node, writer); // we have a transformed class! return writer.toByteArray(); }
From source file:edu.mit.streamjit.impl.common.MessageConstraint.java
License:Open Source License
/** * Parse the given getHandle() call instruction and preceding instructions * into a WorkerData. This is a rather brittle pattern-matching job and * will fail on obfuscated bytecodes.// w w w .j ava 2s. c o m * @param call * @return */ private static WorkerData dataFromCall(Class<?> klass, MethodInsnNode call) { //Latency is either an integer constant or a getfield on this. Field latencyField = null; int constantLatency = Integer.MIN_VALUE; AbstractInsnNode latencyInsn = call.getPrevious(); if (latencyInsn instanceof FieldInsnNode) { FieldInsnNode fieldInsn = (FieldInsnNode) latencyInsn; if (fieldInsn.getOpcode() != Opcodes.GETFIELD) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": latency field insn opcode " + fieldInsn.getOpcode()); if (!fieldInsn.desc.equals(Type.INT_TYPE.getDescriptor())) throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": latency field desc " + fieldInsn.desc); if (!fieldInsn.owner.equals(Type.getType(klass).getInternalName())) throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": latency field owner " + fieldInsn.owner); //Move latencyInsn to sync up with the other else-if branches. latencyInsn = latencyInsn.getPrevious(); //We must be loading from this. if (latencyInsn.getOpcode() != Opcodes.ALOAD) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": getfield subject opcode " + latencyInsn.getOpcode()); int varIdx = ((VarInsnNode) latencyInsn).var; if (varIdx != 0) throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": getfield not from this but from " + varIdx); //Check the field we're loading from is constant (final). //A static field is okay here since it isn't a reference parameter. try { latencyField = klass.getDeclaredField(fieldInsn.name); if (!Modifier.isFinal(latencyField.getModifiers())) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": latency field not final: " + latencyField.toGenericString()); } catch (NoSuchFieldException ex) { throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": getfield not from this but from " + varIdx); } } else if (latencyInsn instanceof LdcInsnNode) { Object constant = ((LdcInsnNode) latencyInsn).cst; if (!(constant instanceof Integer)) throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": ldc " + constant); constantLatency = ((Integer) constant); } else switch (latencyInsn.getOpcode()) { case Opcodes.ICONST_M1: constantLatency = -1; break; case Opcodes.ICONST_0: constantLatency = 0; break; case Opcodes.ICONST_1: constantLatency = 1; break; case Opcodes.ICONST_2: constantLatency = 2; break; case Opcodes.ICONST_3: constantLatency = 3; break; case Opcodes.ICONST_4: constantLatency = 4; break; case Opcodes.ICONST_5: constantLatency = 5; break; case Opcodes.BIPUSH: case Opcodes.SIPUSH: constantLatency = ((IntInsnNode) latencyInsn).operand; break; default: throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": latencyInsn opcode " + latencyInsn.getOpcode()); } //Finally, we've parsed the latency parameter. //Next is an aload_0 for the sender parameter. AbstractInsnNode senderInsn = latencyInsn.getPrevious(); if (senderInsn.getOpcode() != Opcodes.ALOAD || ((VarInsnNode) senderInsn).var != 0) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": bad sender"); //Finally, a getfield of this for a final Portal instance field. AbstractInsnNode portalInsn = senderInsn.getPrevious(); if (!(portalInsn instanceof FieldInsnNode)) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal getfield opcode " + portalInsn.getOpcode()); FieldInsnNode fieldInsn = (FieldInsnNode) portalInsn; if (fieldInsn.getOpcode() != Opcodes.GETFIELD) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal field insn opcode " + fieldInsn.getOpcode()); if (!fieldInsn.desc.equals(Type.getType(Portal.class).getDescriptor())) throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": portal field desc " + fieldInsn.desc); if (!fieldInsn.owner.equals(Type.getType(klass).getInternalName())) throw new IllegalStreamGraphException( "Unsupported getHandle() use in " + klass + ": portal field owner " + fieldInsn.owner); portalInsn = portalInsn.getPrevious(); //We must be loading from this. if (portalInsn.getOpcode() != Opcodes.ALOAD) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal getfield subject opcode " + portalInsn.getOpcode()); int varIdx = ((VarInsnNode) portalInsn).var; if (varIdx != 0) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal getfield not from this but from " + varIdx); //Check the field we're loading from is constant (final) and nonstatic. Field portalField; try { portalField = klass.getDeclaredField(fieldInsn.name); if (!Modifier.isFinal(portalField.getModifiers())) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal field not final: " + portalField.toGenericString()); if (Modifier.isStatic(portalField.getModifiers())) throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal field is static: " + portalField.toGenericString()); } catch (NoSuchFieldException ex) { throw new IllegalStreamGraphException("Unsupported getHandle() use in " + klass + ": portal getfield not from this but from " + varIdx); } return latencyField != null ? new WorkerData(portalField, latencyField) : new WorkerData(portalField, constantLatency); }
From source file:org.evosuite.instrumentation.testability.transformer.BooleanCallsTransformer.java
License:Open Source License
@Override protected AbstractInsnNode transformMethodInsnNode(MethodNode mn, MethodInsnNode methodNode) { if (methodNode.owner.equals(Type.getInternalName(BooleanHelper.class))) return methodNode; methodNode.desc = this.booleanTestabilityTransformation.transformMethodDescriptor(methodNode.owner, methodNode.name, methodNode.desc); methodNode.name = DescriptorMapping.getInstance().getMethodName(methodNode.owner, methodNode.name, methodNode.desc);//from w w w. j a v a2 s.c om if (DescriptorMapping.getInstance().isBooleanMethod(methodNode.desc)) { BooleanTestabilityTransformation.logger.info("Method needs value transformation: " + methodNode.name); if (DescriptorMapping.getInstance().hasBooleanParameters(methodNode.desc)) { BooleanTestabilityTransformation.logger .info("Method needs parameter transformation: " + methodNode.name); TransformationStatistics.transformBackToBooleanParameter(); int firstBooleanParameterIndex = -1; Type[] types = Type.getArgumentTypes(methodNode.desc); for (int i = 0; i < types.length; i++) { if (types[i].getDescriptor().equals("Z")) { if (firstBooleanParameterIndex == -1) { firstBooleanParameterIndex = i; break; } } } if (firstBooleanParameterIndex != -1) { int numOfPushs = types.length - 1 - firstBooleanParameterIndex; // int numOfPushs = types.length - firstBooleanParameterIndex; if (numOfPushs == 0) { if (!(methodNode.getPrevious().getOpcode() == Opcodes.ICONST_1 || methodNode.getPrevious().getOpcode() == Opcodes.ICONST_0)) { //the boolean parameter is the last parameter MethodInsnNode booleanHelperInvoke = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "intToBoolean", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] { Type.INT_TYPE })); mn.instructions.insertBefore(methodNode, booleanHelperInvoke); } } else { InsnList insnlist = new InsnList(); for (int i = 0; i < numOfPushs; i++) { MethodInsnNode booleanHelperPushParameter; if (types[types.length - 1 - i] == Type.BOOLEAN_TYPE || types[types.length - 1 - i] == Type.CHAR_TYPE || types[types.length - 1 - i] == Type.BYTE_TYPE || types[types.length - 1 - i] == Type.SHORT_TYPE || types[types.length - 1 - i] == Type.INT_TYPE || types[types.length - 1 - i] == Type.FLOAT_TYPE || types[types.length - 1 - i] == Type.LONG_TYPE || types[types.length - 1 - i] == Type.DOUBLE_TYPE) { if (types[types.length - 1 - i] == Type.BOOLEAN_TYPE) { booleanHelperPushParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushParameter", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE })); } else { booleanHelperPushParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushParameter", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { types[types.length - 1 - i] })); } } else { booleanHelperPushParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushParameter", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(Object.class) })); } insnlist.add(booleanHelperPushParameter); } for (int i = firstBooleanParameterIndex; i < types.length; i++) { if (i == firstBooleanParameterIndex) { MethodInsnNode booleanHelperInvoke = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "intToBoolean", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] { Type.INT_TYPE })); insnlist.add(booleanHelperInvoke); } else { MethodInsnNode booleanHelperPopParameter; boolean objectNeedCast = false; if (types[i] == Type.BOOLEAN_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterBooleanFromInt", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.CHAR_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterChar", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.BYTE_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterByte", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.SHORT_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterShort", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.INT_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterInt", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.FLOAT_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterFloat", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.LONG_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterLong", Type.getMethodDescriptor(types[i], new Type[] {})); } else if (types[i] == Type.DOUBLE_TYPE) { booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterDouble", Type.getMethodDescriptor(types[i], new Type[] {})); } else { objectNeedCast = true; booleanHelperPopParameter = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "popParameterObject", Type.getMethodDescriptor(Type.getType(Object.class), new Type[] {})); } insnlist.add(booleanHelperPopParameter); if (objectNeedCast) { TypeInsnNode tin = new TypeInsnNode(Opcodes.CHECKCAST, types[i].getInternalName()); insnlist.add(tin); } } } mn.instructions.insertBefore(methodNode, insnlist); } } } if (Type.getReturnType(methodNode.desc).equals(Type.BOOLEAN_TYPE)) { BooleanTestabilityTransformation.logger .info("Method needs return transformation: " + methodNode.name); TransformationStatistics.transformBackToBooleanParameter(); MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "booleanToInt", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.BOOLEAN_TYPE })); mn.instructions.insert(methodNode, n); return n; } } else { BooleanTestabilityTransformation.logger.info("Method needs no transformation: " + methodNode.name); } // TODO: If this is a method that is not transformed, and it requires a Boolean parameter // then we need to convert this boolean back to an int // For example, we could use flow analysis to determine the point where the value is added to the stack // and insert a conversion function there return methodNode; }
From source file:org.jooby.internal.apitool.BytecodeRouteParser.java
License:Apache License
private java.lang.reflect.Type parameterType(final ClassLoader loader, final AbstractInsnNode n) { if (n instanceof MethodInsnNode) { MethodInsnNode node = (MethodInsnNode) n; if (mutantValue().test(node)) { /** value(); intValue(); booleanValue(); */ return TypeDescriptorParser.parse(loader, node.desc); } else if (mutantToSomething().test(node) || getOrCreateKotlinClass().test(node)) { /** to(String.class); toOptional; toList(); */ String owner = Type.getReturnType(node.desc).getClassName(); AbstractInsnNode prev = node.getPrevious(); if (prev instanceof FieldInsnNode && ((MethodInsnNode) n).name.equals("toEnum")) { /** toEnum(Letter.A); */ return loadType(loader, ((FieldInsnNode) prev).owner); }//from w ww . j av a 2 s . c om java.lang.reflect.Type toType = String.class; if (prev instanceof LdcInsnNode) { /** to(Foo.class); */ Object cst = ((LdcInsnNode) prev).cst; if (cst instanceof Type) { toType = loadType(loader, ((Type) cst).getClassName()); } } else if (prev instanceof FieldInsnNode) { toType = loadType(loader, ((FieldInsnNode) prev).owner); } // JoobyKt.toOptional AbstractInsnNode next = node.getNext(); if (next instanceof MethodInsnNode) { String joobyKt = ((MethodInsnNode) next).owner; String methodName = ((MethodInsnNode) next).name; if ("toOptional".equals(methodName) && "org/jooby/JoobyKt".equals(joobyKt)) { owner = Optional.class.getName(); } } Set<String> skipOwners = ImmutableSet.of(Object.class.getName(), Enum.class.getName(), "kotlin.reflect.KClass"); if (skipOwners.contains(owner)) { return toType; } /** toList(Foo.class); */ return Types.newParameterizedType(loadType(loader, owner), toType); } } else if (n instanceof VarInsnNode) { return new Insn<>(null, n).prev().filter(is(MethodInsnNode.class)).findFirst() .map(MethodInsnNode.class::cast).filter(file()).map(m -> { return m.name.equals("files") ? Types.newParameterizedType(List.class, File.class) : File.class; }).orElse(Object.class); } else if (n instanceof TypeInsnNode) { TypeInsnNode typeInsn = (TypeInsnNode) n; if (typeInsn.getOpcode() == Opcodes.CHECKCAST) { return loadType(loader, typeInsn.desc); } } else if (n != null && Opcodes.DUP == n.getOpcode()) { // Kotlin 1.2.x // mv.visitInsn(DUP); // mv.visitLdcInsn("req.param(\"p1\")"); // mv.visitMethodInsn(INVOKESTATIC, "kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull", "(Ljava/lang/Object;Ljava/lang/String;)V", false); // mv.visitMethodInsn(INVOKESTATIC, "org/jooby/JoobyKt", "getValue", "(Lorg/jooby/Mutant;)Ljava/lang/String;", false); AbstractInsnNode next = new Insn<>(null, n).next().filter(MethodInsnNode.class::isInstance).skip(1) .findFirst().orElse(null); java.lang.reflect.Type result = parameterType(loader, next); if (result == Object.class) { next = new Insn<>(null, n).next().filter(TypeInsnNode.class::isInstance).findFirst().orElse(null); result = parameterType(loader, next); } return result; } else if (n instanceof FieldInsnNode) { AbstractInsnNode next = n.getNext(); if (next instanceof MethodInsnNode) { if (((MethodInsnNode) next).name.equals("toOptional")) { return Types.newParameterizedType(Optional.class, loadType(loader, ((FieldInsnNode) n).owner)); } else if (((MethodInsnNode) next).name.equals("getOrCreateKotlinClass")) { return loadType(loader, ((FieldInsnNode) n).owner); } } } return Object.class; }
From source file:org.jooby.internal.apitool.BytecodeRouteParser.java
License:Apache License
private Integer statusCodeFor(MethodInsnNode node) { if (node.name.equals("noContent")) { return 204; }/*www. ja va 2 s .co m*/ if (node.name.equals("with")) { AbstractInsnNode previous = node.getPrevious(); if (previous instanceof IntInsnNode) { return ((IntInsnNode) previous).operand; } if (previous instanceof FieldInsnNode) { String owner = ((FieldInsnNode) previous).owner.replace("/", "."); if (owner.equals(Status.class.getName())) { String statusName = ((FieldInsnNode) previous).name; return Try.apply(() -> Status.class.getDeclaredField(statusName).get(null)) .map(it -> ((Status) it).value()).orElse(null); } } } return null; }
From source file:org.jooby.internal.apitool.Insn.java
License:Apache License
public static List<LdcInsnNode> ldcFor(MethodInsnNode node) { AbstractInsnNode it = new Insn<>(null, node.getPrevious()).prev().filter(is(MethodInsnNode.class)) .findFirst().orElseGet(() -> Insn.first(node)); /** Collect all ldc between a previous method invocation and current invocation: */ List<LdcInsnNode> ldc = new ArrayList<>(); while (it != node) { if (it instanceof LdcInsnNode) { ldc.add((LdcInsnNode) it);/*from ww w. j a va2 s .c o m*/ } it = it.getNext(); } return ldc; }