@NotNull
  private static Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>>
      getSuperclassToFunctionsMultimap(
          @NotNull PsiMethodWrapper method,
          @NotNull BindingContext bindingContext,
          @NotNull ClassDescriptor containingClass) {
    Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>> result = HashMultimap.create();

    Name functionName = Name.identifier(method.getName());
    int parameterCount = method.getParameters().size();

    for (JetType supertype : TypeUtils.getAllSupertypes(containingClass.getDefaultType())) {
      ClassifierDescriptor klass = supertype.getConstructor().getDeclarationDescriptor();
      assert klass != null;
      FqName fqName = DescriptorUtils.getFQName(klass).toSafe();

      for (FunctionDescriptor fun :
          klass.getDefaultType().getMemberScope().getFunctions(functionName)) {
        if (fun.getKind().isReal() && fun.getValueParameters().size() == parameterCount) {
          PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, fun);
          if (declaration instanceof PsiMethod) {
            result.put(fqName, Pair.create(fun, (PsiMethod) declaration));
          } // else declaration is null or JetNamedFunction: both cases are processed later
        }
      }
    }
    return result;
  }
  /** @return true if the member is an inherited implementation of a method from Any */
  private boolean isTrivial(@NotNull FunctionDescriptor function) {
    if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
      return false;
    }

    for (CallableDescriptor overridden : OverrideResolver.getOverriddenDeclarations(function)) {
      if (overridden instanceof CallableMemberDescriptor
          && ((CallableMemberDescriptor) overridden).getKind()
              == CallableMemberDescriptor.Kind.DECLARATION
          && !overridden.getContainingDeclaration().equals(builtIns.getAny())) {
        return false;
      }
    }

    return true;
  }
Example #3
0
  public void generateBridges(@NotNull FunctionDescriptor descriptor) {
    if (descriptor instanceof ConstructorDescriptor) return;
    if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
    if (isInterface(descriptor.getContainingDeclaration())) return;

    // equals(Any?), hashCode(), toString() never need bridges
    if (isMethodOfAny(descriptor)) return;

    // If the function doesn't have a physical declaration among super-functions, it's a SAM adapter
    // or alike and doesn't need bridges
    if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return;

    boolean isSpecial =
        SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;

    Set<Bridge<Method>> bridgesToGenerate;
    if (!isSpecial) {
      bridgesToGenerate =
          ImplKt.generateBridgesForFunctionDescriptor(descriptor, getSignatureMapper(typeMapper));
      if (!bridgesToGenerate.isEmpty()) {
        PsiElement origin =
            descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
        boolean isSpecialBridge =
            BuiltinMethodsWithSpecialGenericSignature
                    .getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor)
                != null;

        for (Bridge<Method> bridge : bridgesToGenerate) {
          generateBridge(
              origin, descriptor, bridge.getFrom(), bridge.getTo(), isSpecialBridge, false);
        }
      }
    } else {
      Set<BridgeForBuiltinSpecial<Method>> specials =
          BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
              descriptor, getSignatureMapper(typeMapper));

      if (!specials.isEmpty()) {
        PsiElement origin =
            descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
        for (BridgeForBuiltinSpecial<Method> bridge : specials) {
          generateBridge(
              origin,
              descriptor,
              bridge.getFrom(),
              bridge.getTo(),
              bridge.isSpecial(),
              bridge.isDelegateToSuper());
        }
      }

      if (!descriptor.getKind().isReal()
          && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
        CallableDescriptor overridden =
            SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
        assert overridden != null;

        Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
        int flags = ACC_ABSTRACT | getVisibilityAccessFlag(descriptor);
        v.newMethod(
            JvmDeclarationOriginKt.OtherOrigin(overridden),
            flags,
            method.getName(),
            method.getDescriptor(),
            null,
            null);
      }
    }
  }