org.objectweb.asm.Opcodes# INVOKESPECIAL 源码实例Demo

下面列出了org.objectweb.asm.Opcodes# INVOKESPECIAL 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。


@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
	if (opcode != Opcodes.INVOKESPECIAL) {
		super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
	}

	if (!owner.equals(ITEM_GROUP) || !name.equals("<init>")) {
		return;
	}

	if (!descriptor.equals("(Ljava/lang/String;)V") && !descriptor.equals("(ILjava/lang/String;)V")) {
		Patchwork.LOGGER.error("Unexpected descriptor for super() in ItemGroup: " + descriptor);
	}

	super.visitMethodInsn(Opcodes.INVOKESPECIAL, PATCHWORK_ITEM_GROUP, name, descriptor, isInterface);
}
 
源代码2 项目: bazel   文件: InterfaceDesugaring.java

static String normalizeInterfaceMethodName(String name, boolean isLambda, int opcode) {
  if (isLambda) {
    // Rename lambda method to reflect the new owner.  Not doing so confuses LambdaDesugaring
    // if it's run over this class again. LambdaDesugaring has already renamed the method from
    // its original name to include the interface name at this point.
    return name + DependencyCollector.INTERFACE_COMPANION_SUFFIX;
  }

  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      // Rename static methods holding default method implementations since their descriptor
      // differs from the original method (due to explicit receiver parameter). This avoids
      // possible clashes with static interface methods or generated stubs for default methods
      // that could otherwise have the same name and descriptor by coincidence.
      return name + DEFAULT_COMPANION_METHOD_SUFFIX;
    case Opcodes.INVOKESTATIC: // moved but with same name
      return name + "$$STATIC$$"; // TODO(b/117453106): Stop renaming static interface methods
    case Opcodes.INVOKEINTERFACE: // not moved
    case Opcodes.INVOKEVIRTUAL: // tolerate being called for non-interface methods
      return name;
    default:
      throw new IllegalArgumentException("Unexpected opcode calling " + name + ": " + opcode);
  }
}
 
源代码3 项目: bazel   文件: NestBridgeRefConverter.java

@Override
public void visitMethodInsn(
    int opcode, String owner, String name, String descriptor, boolean isInterface) {
  MethodKey methodKey = MethodKey.create(ClassName.create(owner), name, descriptor);
  MemberUseKind useKind = MemberUseKind.fromValue(opcode);

  // Desugar invokevirtual on private instance methods within the same class.
  if (!isInterface
      && useKind == MemberUseKind.INVOKEVIRTUAL
      && methodKey.owner().equals(enclosingMethodKey.owner())
      && nestDigest.isPrivateInstanceMethod(methodKey)) {
    super.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, descriptor, isInterface);
    return;
  }

  if ((isInterface || isCrossMateRefInNest(methodKey, enclosingMethodKey))
      && nestDigest.hasAnyUse(methodKey, useKind)) {
    methodKey.accept(useKind, isInterface, methodToBridgeRedirector, mv);
    return;
  }
  super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
 

private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      invokespecial(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEVIRTUAL:
      invokevirtual(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKESTATIC:
      invokestatic(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEINTERFACE:
      invokeinterface(owner, name, descriptor);
      break;
    default:
      throw new IllegalArgumentException();
  }
}
 

@Override
public void visitInsn(int opcode) {
	if ((opcode == Opcodes.ARETURN) || (opcode == Opcodes.IRETURN)
			|| (opcode == Opcodes.LRETURN)
			|| (opcode == Opcodes.FRETURN)
			|| (opcode == Opcodes.DRETURN)) {
		throw new RuntimeException(new UnmodifiableClassException("Constructors are supposed to return void"));
	}
	if (opcode == Opcodes.RETURN) {
		super.visitVarInsn(Opcodes.ALOAD, 0);
		super.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ScottReportingRule.class));
		super.visitInsn(Opcodes.DUP);
		super.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ScottReportingRule.class), "<init>", "()V", false);

		super.visitFieldInsn(Opcodes.PUTFIELD,
				className, "scottReportingRule",
				Type.getDescriptor(ScottReportingRule.class));
	}
	
	super.visitInsn(opcode);
}
 

private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      invokespecial(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEVIRTUAL:
      invokevirtual(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKESTATIC:
      invokestatic(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEINTERFACE:
      invokeinterface(owner, name, descriptor);
      break;
    default:
      throw new IllegalArgumentException();
  }
}
 

private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      invokespecial(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEVIRTUAL:
      invokevirtual(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKESTATIC:
      invokestatic(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEINTERFACE:
      invokeinterface(owner, name, descriptor);
      break;
    default:
      throw new IllegalArgumentException();
  }
}
 
源代码8 项目: Mixin   文件: Target.java

/**
 * Find the first <tt>&lt;init&gt;</tt> invocation after the specified
 * <tt>NEW</tt> insn 
 * 
 * @param newNode NEW insn
 * @return INVOKESPECIAL opcode of ctor, or null if not found
 */
public MethodInsnNode findInitNodeFor(TypeInsnNode newNode) {
    int start = this.indexOf(newNode);
    for (Iterator<AbstractInsnNode> iter = this.insns.iterator(start); iter.hasNext();) {
        AbstractInsnNode insn = iter.next();
        if (insn instanceof MethodInsnNode && insn.getOpcode() == Opcodes.INVOKESPECIAL) {
            MethodInsnNode methodNode = (MethodInsnNode)insn;
            if (Constants.CTOR.equals(methodNode.name) && methodNode.owner.equals(newNode.desc)) {
                return methodNode;
            }
        }
    }
    return null;
}
 

private boolean needsFrameGuard(int opcode, String owner, String name, String desc) {
    if (owner.startsWith("java/") || owner.startsWith("javax/")) {
        //System.out.println("SKIP:: " + owner + "." + name + desc);
        return false;
    }

    // Always create save-point before Continuation methods (like suspend)
    if (CONTINUATION_CLASS_INTERNAL_NAME.equals(owner)) {
        return CONTINUATION_CLASS_CONTINUABLE_METHODS.contains(name);
    }

    // No need to create save-point before constructors -- it's forbidden to suspend in constructors anyway
    if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
        return false;
    }

    if (opcode == Opcodes.INVOKEDYNAMIC) {
        // TODO verify CallSite to be continuable?
        return true;
    }

    if (opcode == Opcodes.INVOKEINTERFACE ||
        opcode == Opcodes.INVOKESPECIAL   ||
        opcode == Opcodes.INVOKESTATIC    ||
        opcode == Opcodes.INVOKEVIRTUAL) {
        ContinuableClassInfo classInfo;
        try {
            classInfo = cciResolver.resolve(owner);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        return null != classInfo && classInfo.isContinuableMethod(opcode, name, desc, desc);
    }
    return false;
}
 

public int getOpcode(InstanceMethodInvoke.Type type) {
    switch (type) {
    case INTERFACE:
        return Opcodes.INVOKEINTERFACE;
    case SPECIAL:
        return Opcodes.INVOKESPECIAL;
    case VIRTUAL:
    default:
        return Opcodes.INVOKEVIRTUAL;
    }
}
 
源代码11 项目: JReFrameworker   文件: CheckMethodAdapter.java

private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  checkVisitCodeCalled();
  checkVisitMaxsNotCalled();
  checkOpcodeMethod(opcode, Method.VISIT_METHOD_INSN);
  if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
    checkMethodIdentifier(version, name, "name");
  }
  checkInternalName(version, owner, "owner");
  checkMethodDescriptor(version, descriptor);
  if (opcode == Opcodes.INVOKEVIRTUAL && isInterface) {
    throw new IllegalArgumentException("INVOKEVIRTUAL can't be used with interfaces");
  }
  if (opcode == Opcodes.INVOKEINTERFACE && !isInterface) {
    throw new IllegalArgumentException("INVOKEINTERFACE can't be used with classes");
  }
  if (opcode == Opcodes.INVOKESPECIAL && isInterface && (version & 0xFFFF) < Opcodes.V1_8) {
    throw new IllegalArgumentException(
        "INVOKESPECIAL can't be used with interfaces prior to Java 8");
  }

  // Calling super.visitMethodInsn requires to call the correct version depending on this.api
  // (otherwise infinite loops can occur). To simplify and to make it easier to automatically
  // remove the backward compatibility code, we inline the code of the overridden method here.
  if (mv != null) {
    mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
  }
  ++insnCount;
}
 
源代码12 项目: Concurnas   文件: CheckMethodAdapter.java

@Override
public void visitMethodInsn(
    final int opcodeAndSource,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
    // Redirect the call to the deprecated version of this method.
    super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
    return;
  }
  int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;

  checkVisitCodeCalled();
  checkVisitMaxsNotCalled();
  checkOpcodeMethod(opcode, Method.VISIT_METHOD_INSN);
  if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
    checkMethodIdentifier(version, name, "name");
  }
  checkInternalName(version, owner, "owner");
  checkMethodDescriptor(version, descriptor);
  if (opcode == Opcodes.INVOKEVIRTUAL && isInterface) {
    throw new IllegalArgumentException("INVOKEVIRTUAL can't be used with interfaces");
  }
  if (opcode == Opcodes.INVOKEINTERFACE && !isInterface) {
    throw new IllegalArgumentException("INVOKEINTERFACE can't be used with classes");
  }
  if (opcode == Opcodes.INVOKESPECIAL && isInterface && (version & 0xFFFF) < Opcodes.V1_8) {
    throw new IllegalArgumentException(
        "INVOKESPECIAL can't be used with interfaces prior to Java 8");
  }
  super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
  ++insnCount;
}
 

private boolean needsFrameGuard(int opcode, String owner, String name, String desc) {
    if (owner.startsWith("java/") || owner.startsWith("javax/")) {
        //System.out.println("SKIP:: " + owner + "." + name + desc);
        return false;
    }

    // Always create save-point before Continuation methods (like suspend)
    if (CONTINUATION_CLASS_INTERNAL_NAME.equals(owner)) {
        return CONTINUATION_CLASS_CONTINUABLE_METHODS.contains(name);
    }

    // No need to create save-point before constructors -- it's forbidden to suspend in constructors anyway
    if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
        return false;
    }

    if (opcode == Opcodes.INVOKEINTERFACE ||
        opcode == Opcodes.INVOKESPECIAL   ||
        opcode == Opcodes.INVOKESTATIC    ||
        opcode == Opcodes.INVOKEVIRTUAL) {
        ContinuableClassInfo classInfo;
        try {
            classInfo = cciResolver.resolve(owner);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        return null != classInfo && classInfo.isContinuableMethod(opcode, name, desc, desc);
    }
    return false;
}
 
源代码14 项目: Mixin   文件: Bytecode.java

/**
 * Find the call to <tt>super()</tt> or <tt>this()</tt> in a constructor.
 * This attempts to locate the first call to <tt>&lt;init&gt;</tt> which
 * isn't an inline call to another object ctor being passed into the super
 * invocation.
 * 
 * @param ctor ctor to scan
 * @param superName name of superclass
 * @param ownerName name of owning class
 * @return Call to <tt>super()</tt>, <tt>this()</tt> or
 *      <tt>DelegateInitialiser.NONE</tt> if not found
 */
public static DelegateInitialiser findDelegateInit(MethodNode ctor, String superName, String ownerName) {
    if (!Constants.CTOR.equals(ctor.name)) {
        return DelegateInitialiser.NONE;
    }
    
    int news = 0;
    for (Iterator<AbstractInsnNode> iter = ctor.instructions.iterator(); iter.hasNext();) {
        AbstractInsnNode insn = iter.next();
        if (insn instanceof TypeInsnNode && insn.getOpcode() == Opcodes.NEW) {
            news++;
        } else if (insn instanceof MethodInsnNode && insn.getOpcode() == Opcodes.INVOKESPECIAL) {
            MethodInsnNode methodNode = (MethodInsnNode)insn;
            if (Constants.CTOR.equals(methodNode.name)) {
                if (news > 0) {
                    news--;
                } else {
                    boolean isSuper = methodNode.owner.equals(superName);
                    if (isSuper || methodNode.owner.equals(ownerName)) {
                        return new DelegateInitialiser(methodNode, isSuper);
                    }
                }
            }
        }
    }
    return DelegateInitialiser.NONE;
}
 
源代码15 项目: JReFrameworker   文件: AnalyzerAdapter.java

private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  if (mv != null) {
    mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
  }
  if (this.locals == null) {
    labels = null;
    return;
  }
  pop(descriptor);
  if (opcode != Opcodes.INVOKESTATIC) {
    Object value = pop();
    if (opcode == Opcodes.INVOKESPECIAL && name.equals("<init>")) {
      Object initializedValue;
      if (value == Opcodes.UNINITIALIZED_THIS) {
        initializedValue = this.owner;
      } else {
        initializedValue = uninitializedTypes.get(value);
      }
      for (int i = 0; i < locals.size(); ++i) {
        if (locals.get(i) == value) {
          locals.set(i, initializedValue);
        }
      }
      for (int i = 0; i < stack.size(); ++i) {
        if (stack.get(i) == value) {
          stack.set(i, initializedValue);
        }
      }
    }
  }
  pushDescriptor(descriptor);
  labels = null;
}
 
源代码16 项目: bazel   文件: LambdaDesugaring.java

static int invokeOpcode(Handle invokedMethod) {
  switch (invokedMethod.getTag()) {
    case Opcodes.H_INVOKESTATIC:
      return Opcodes.INVOKESTATIC;
    case Opcodes.H_INVOKEVIRTUAL:
      return Opcodes.INVOKEVIRTUAL;
    case Opcodes.H_INVOKESPECIAL:
    case Opcodes.H_NEWINVOKESPECIAL: // Must be preceded by NEW
      return Opcodes.INVOKESPECIAL;
    case Opcodes.H_INVOKEINTERFACE:
      return Opcodes.INVOKEINTERFACE;
    default:
      throw new UnsupportedOperationException("Don't know how to call " + invokedMethod);
  }
}
 

@Override
public MethodNode generate() {
    int size = Bytecode.getArgsSize(this.argTypes) + this.returnType.getSize() + (this.targetIsStatic ? 0 : 1);
    MethodNode method = this.createMethod(size, size);
    if (!this.targetIsStatic) {
        method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    }
    Bytecode.loadArgs(this.argTypes, method.instructions, this.targetIsStatic ? 0 : 1);
    boolean isPrivate = Bytecode.hasFlag(this.targetMethod, Opcodes.ACC_PRIVATE);
    int opcode = this.targetIsStatic ? Opcodes.INVOKESTATIC : (isPrivate ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
    method.instructions.add(new MethodInsnNode(opcode, this.info.getClassNode().name, this.targetMethod.name, this.targetMethod.desc, false));
    method.instructions.add(new InsnNode(this.returnType.getOpcode(Opcodes.IRETURN)));
    return method;
}
 
源代码18 项目: TFC2   文件: ModuleVanillaReplacement.java

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) 
{
	if(basicClass == null)
		return null;

	ClassNode classNode = ASMHelper.readClassFromBytes(basicClass);

	if (transformedName.equals("net.minecraft.item.Item"))
	{
		String desc = ASMHelper.toMethodDescriptor("V");
		MethodNode methodNode = ASMHelper.findMethodNodeOfClass(classNode, "u", "registerItems", desc);

		if (methodNode != null)
		{
			InsnList list = new InsnList();
			AbstractInsnNode node0 = getLineNumber(methodNode.instructions, 1566);
			node0 = ASMHelper.find(methodNode.instructions, new IntInsnNode(Opcodes.SIPUSH, 337));
			node0 = node0.getNext().getNext();
			AbstractInsnNode newNode = new TypeInsnNode(Opcodes.NEW, gi("com/bioxx/tfc2/items/ItemClayBall"));
			methodNode.instructions.insert(node0, newNode);
			methodNode.instructions.remove(node0);

			node0 = newNode.getNext().getNext();
			MethodInsnNode method = new MethodInsnNode(Opcodes.INVOKESPECIAL, gi("com/bioxx/tfc2/items/ItemClayBall"), "<init>", ASMHelper.toMethodDescriptor("V"), false);
			methodNode.instructions.insert(node0, method);
			methodNode.instructions.remove(node0);
		}
		else
		{
			String msg = "Unable to replace vanilla clay_ball item";
			for(MethodNode m : classNode.methods)
			{
				msg += m.name+", ";
			}
			throw new RuntimeException(msg);
		}
	}
	/*else if (transformedName.equals("net.minecraft.world.gen.feature.WorldGenTallGrass") || 
			transformedName.equals("net.minecraft.world.gen.feature.WorldGenDoublePlant"))
	{
		String desc = ASMHelper.toMethodDescriptor("Z",ObfHelper.toObfClassName(ASMConstants.WORLD),ObfHelper.toObfClassName(ASMConstants.RANDOM),ObfHelper.toObfClassName(ASMConstants.BLOCK_POS));
		MethodNode methodNode = ASMHelper.findMethodNodeOfClass(classNode, "b", "generate", desc);

		if (methodNode != null)
		{
			InsnList list = new InsnList();
			methodNode.instructions.clear();
			list.add(new InsnNode(Opcodes.ICONST_1));
			list.add(new InsnNode(Opcodes.IRETURN));
			methodNode.instructions.insert(list);
		}
		else
			throw new RuntimeException("WorldGenTallGrass | WorldGenDoublePlant: generate (b) method not found");
	}*/

	return ASMHelper.writeClassToBytes(classNode);
}
 
源代码19 项目: bazel   文件: LambdaDesugaring.java

@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
  if (!"java/lang/invoke/LambdaMetafactory".equals(bsm.getOwner())) {
    // Not an invokedynamic for a lambda expression
    super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
    return;
  }

  try {
    Lookup lookup = createLookup(internalName);
    ArrayList<Object> args = new ArrayList<>(bsmArgs.length + 3);
    args.add(lookup);
    args.add(name);
    args.add(MethodType.fromMethodDescriptorString(desc, targetLoader));
    for (Object bsmArg : bsmArgs) {
      args.add(toJvmMetatype(lookup, bsmArg));
    }

    // Both bootstrap methods in LambdaMetafactory expect a MethodHandle as their 5th argument
    // so we can assume bsmArgs[1] (the 5th arg) to be a Handle.
    MethodReferenceBridgeInfo bridgeInfo = queueUpBridgeMethodIfNeeded((Handle) bsmArgs[1]);

    // Resolve the bootstrap method in "host configuration" (this tool's default classloader)
    // since targetLoader may only contain stubs that we can't actually execute.
    // generateLambdaClass() below will invoke the bootstrap method, so a stub isn't enough,
    // and ultimately we don't care if the bootstrap method was even on the bootclasspath
    // when this class was compiled (although it must've been since javac is unhappy otherwise).
    MethodHandle bsmMethod = toMethodHandle(publicLookup(), bsm, /*target*/ false);
    // Give generated classes to have more stable names (b/35643761).  Use BSM's naming scheme
    // but with separate counter for each surrounding class.
    String lambdaClassName = internalName + "$$Lambda$" + (lambdaCount++);
    Type[] capturedTypes = Type.getArgumentTypes(desc);
    boolean needFactory =
        capturedTypes.length != 0
            && !attemptAllocationBeforeArgumentLoads(lambdaClassName, capturedTypes);
    lambdas.generateLambdaClass(
        internalName,
        LambdaInfo.create(
            lambdaClassName,
            desc,
            needFactory,
            bridgeInfo.methodReference(),
            bridgeInfo.bridgeMethod()),
        bsmMethod,
        args);
    if (desc.startsWith("()")) {
      // For stateless lambda classes we'll generate a singleton instance that we can just load
      checkState(capturedTypes.length == 0);
      super.visitFieldInsn(
          Opcodes.GETSTATIC,
          lambdaClassName,
          LambdaClassFixer.SINGLETON_FIELD_NAME,
          desc.substring("()".length()));
    } else if (needFactory) {
      // If we were unable to inline the allocation of the generated lambda class then
      // invoke factory method of generated lambda class with the arguments on the stack
      super.visitMethodInsn(
          Opcodes.INVOKESTATIC,
          lambdaClassName,
          LambdaClassFixer.FACTORY_METHOD_NAME,
          desc,
          /*itf*/ false);
    } else {
      // Otherwise we inserted a new/dup pair of instructions above and now just need to invoke
      // the constructor of generated lambda class with the arguments on the stack
      super.visitMethodInsn(
          Opcodes.INVOKESPECIAL,
          lambdaClassName,
          "<init>",
          Type.getMethodDescriptor(Type.VOID_TYPE, capturedTypes),
          /*itf*/ false);
    }
  } catch (IOException | ReflectiveOperationException e) {
    throw new IllegalStateException(
        "Couldn't desugar invokedynamic for "
            + internalName
            + "."
            + name
            + " using "
            + bsm
            + " with arguments "
            + Arrays.toString(bsmArgs),
        e);
  }
}
 
源代码20 项目: bazel   文件: InterfaceDesugaring.java

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
  // Assume that any static interface methods on the classpath are moved
  if ((itf || owner.equals(interfaceName)) && !bootclasspath.isKnown(owner)) {
    if (name.startsWith("lambda$")) {
      // Redirect lambda invocations to completely remove all lambda methods from interfaces.
      checkArgument(
          !owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
          "shouldn't consider %s an interface",
          owner);
      if (opcode == Opcodes.INVOKEINTERFACE) {
        opcode = Opcodes.INVOKESTATIC;
        desc = companionDefaultMethodDescriptor(owner, desc);
      } else {
        checkArgument(
            opcode == Opcodes.INVOKESTATIC,
            "Unexpected opcode %s to invoke %s.%s",
            opcode,
            owner,
            name);
      }
      // Reflect that InterfaceDesugaring moves and renames the lambda body method
      name = normalizeInterfaceMethodName(name, /*isLambda=*/ true, opcode);
      owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
      itf = false;
      // Record dependency on companion class
      depsCollector.assumeCompanionClass(declaringClass, owner);

      String expectedLambdaMethodName = LambdaDesugaring.uniqueInPackage(owner, name);
      checkState(
          name.equals(expectedLambdaMethodName),
          "Unexpected lambda body method name for %s: real=%s, expected=%s",
          owner,
          name,
          expectedLambdaMethodName);
    } else if ((opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL)) {
      checkArgument(
          !owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
          "shouldn't consider %s an interface",
          owner);
      if (opcode == Opcodes.INVOKESPECIAL) {
        // Turn Interface.super.m() into DefiningInterface$$CC.m(receiver). Note that owner
        // always refers to the current type's immediate super-interface, but the default method
        // may be inherited by that interface, so we have to figure out where the method is
        // defined and invoke it in the corresponding companion class (b/73355452).  Note that
        // we're always dealing with interfaces here, and all interface methods are public,
        // so using Class.getMethods should suffice to find inherited methods.  Also note this
        // can only be a default method invocation, no abstract method invocation.
        owner =
            findDefaultMethod(owner, name, desc)
                .getDeclaringClass()
                .getName()
                .replace('.', '/');
        desc = companionDefaultMethodDescriptor(owner, desc);
      }
      name = normalizeInterfaceMethodName(name, /*isLambda=*/ false, opcode);
      owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
      opcode = Opcodes.INVOKESTATIC;
      itf = false;
      // Record dependency on companion class
      depsCollector.assumeCompanionClass(declaringClass, owner);
    } // else non-lambda INVOKEINTERFACE, which needs no rewriting
  }
  super.visitMethodInsn(opcode, owner, name, desc, itf);
}
 
 方法所在类
 同类方法