void (String methodName, String desc, Handle bsm, Object... bsmArgs) { final Type returnType = Type.getReturnType(desc); addClassUsage(TypeRepr.getType(myContext, returnType)); // common args processing for (Object arg : bsmArgs) { if (arg instanceof Type) { final Type type = (Type)arg; if (type.getSort() == Type.METHOD) { for (Type argType : type.getArgumentTypes()) { addClassUsage(TypeRepr.getType(myContext, argType)); } addClassUsage(TypeRepr.getType(myContext, type.getReturnType())); } else { addClassUsage(TypeRepr.getType(myContext, type)); } } else if (arg instanceof Handle) { processMethodHandle((Handle)arg); } } if (LAMBDA_FACTORY_CLASS.equals(bsm.getOwner())) { // This invokeDynamic implements a lambda or method reference usage. // Need to register method usage for the corresponding SAM-type. // First three arguments to the bootstrap methods are provided automatically by VM. // Arguments in args array are expected to be as following: // [0]: Type: Signature and return type of method to be implemented by the function object. // [1]: Handle: implementation method handle // [2]: Type: The signature and return type that should be enforced dynamically at invocation time. May be the same as samMethodType, or may be a specialization of it // [...]: optional additional arguments if (returnType.getSort() == Type.OBJECT && bsmArgs.length >= 3) { if (bsmArgs[0] instanceof Type) { final Type samMethodType = (Type)bsmArgs[0]; if (samMethodType.getSort() == Type.METHOD) { registerMethodUsage(returnType.getInternalName(), methodName, samMethodType.getDescriptor()); // reflect dynamic proxy instantiation with NewClassUsage myUsages.add(UsageRepr.createClassNewUsage(myContext, myContext.get(returnType.getInternalName()))); } } } } super.visitInvokeDynamicInsn(methodName, desc, bsm, bsmArgs); }