private static String getInlineName(
      @NotNull CodegenContext codegenContext,
      @NotNull DeclarationDescriptor currentDescriptor,
      @NotNull JetTypeMapper typeMapper,
      @NotNull JvmFileClassesProvider fileClassesProvider) {
    if (currentDescriptor instanceof PackageFragmentDescriptor) {
      PsiFile file = getContainingFile(codegenContext);

      Type implementationOwnerType;
      if (file == null) {
        implementationOwnerType =
            CodegenContextUtil.getImplementationOwnerClassType(codegenContext);
      } else {
        implementationOwnerType =
            FileClassesPackage.getFileClassType(fileClassesProvider, (JetFile) file);
      }

      if (implementationOwnerType == null) {
        DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
        //noinspection ConstantConditions
        throw new RuntimeException(
            "Couldn't find declaration for "
                + contextDescriptor.getContainingDeclaration().getName()
                + "."
                + contextDescriptor.getName()
                + "; context: "
                + codegenContext);
      }

      return implementationOwnerType.getInternalName();
    } else if (currentDescriptor instanceof ClassifierDescriptor) {
      Type type = typeMapper.mapType((ClassifierDescriptor) currentDescriptor);
      return type.getInternalName();
    } else if (currentDescriptor instanceof FunctionDescriptor) {
      ClassDescriptor descriptor =
          typeMapper
              .getBindingContext()
              .get(CodegenBinding.CLASS_FOR_CALLABLE, (FunctionDescriptor) currentDescriptor);
      if (descriptor != null) {
        Type type = typeMapper.mapType(descriptor);
        return type.getInternalName();
      }
    }

    // TODO: add suffix for special case
    String suffix =
        currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString();

    //noinspection ConstantConditions
    return getInlineName(
            codegenContext,
            currentDescriptor.getContainingDeclaration(),
            typeMapper,
            fileClassesProvider)
        + "$"
        + suffix;
  }
Beispiel #2
0
 @Nullable
 public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) {
   DeclarationDescriptor containing = descriptor.getContainingDeclaration();
   while (containing != null) {
     if (containing instanceof ClassDescriptor && !isCompanionObject(containing)) {
       return (ClassDescriptor) containing;
     }
     containing = containing.getContainingDeclaration();
   }
   return null;
 }
Beispiel #3
0
 public static boolean isAncestor(
     @Nullable DeclarationDescriptor ancestor,
     @NotNull DeclarationDescriptor declarationDescriptor,
     boolean strict) {
   if (ancestor == null) return false;
   DeclarationDescriptor descriptor =
       strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor;
   while (descriptor != null) {
     if (ancestor == descriptor) return true;
     descriptor = descriptor.getContainingDeclaration();
   }
   return false;
 }
Beispiel #4
0
 @Nullable
 @SuppressWarnings("unchecked")
 public static <D extends DeclarationDescriptor> D getParentOfType(
     @Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass, boolean strict) {
   if (descriptor == null) return null;
   if (strict) {
     descriptor = descriptor.getContainingDeclaration();
   }
   while (descriptor != null) {
     if (aClass.isInstance(descriptor)) {
       return (D) descriptor;
     }
     descriptor = descriptor.getContainingDeclaration();
   }
   return null;
 }
Beispiel #5
0
  public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) {
    if (descriptor instanceof PackageFragmentDescriptor) {
      return new PackageContext(
          (PackageFragmentDescriptor) descriptor, state.getRootContext(), null);
    }

    CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state);

    if (descriptor instanceof ClassDescriptor) {
      OwnerKind kind =
          DescriptorUtils.isInterface(descriptor)
              ? OwnerKind.DEFAULT_IMPLS
              : OwnerKind.IMPLEMENTATION;
      return parent.intoClass((ClassDescriptor) descriptor, kind, state);
    } else if (descriptor instanceof ScriptDescriptor) {
      ClassDescriptor classDescriptorForScript =
          state.getBindingContext().get(CLASS_FOR_SCRIPT, (ScriptDescriptor) descriptor);
      assert classDescriptorForScript != null : "Can't find class for script: " + descriptor;
      List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
      return parent.intoScript(
          (ScriptDescriptor) descriptor,
          earlierScripts == null ? Collections.emptyList() : earlierScripts,
          classDescriptorForScript);
    } else if (descriptor instanceof FunctionDescriptor) {
      return parent.intoFunction((FunctionDescriptor) descriptor);
    }

    throw new IllegalStateException("Couldn't build context for " + descriptorName(descriptor));
  }
Beispiel #6
0
 @NotNull
 private static FqNameUnsafe getFqNameUnsafe(@NotNull DeclarationDescriptor descriptor) {
   DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
   assert containingDeclaration != null
       : "Not package/module descriptor doesn't have containing declaration: " + descriptor;
   return getFqName(containingDeclaration).child(descriptor.getName());
 }
Beispiel #7
0
 private static boolean isIllegalNestedClass(@NotNull DeclarationDescriptor descriptor) {
   if (!(descriptor instanceof ClassDescriptor)) return false;
   DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
   if (!(containingDeclaration instanceof ClassDescriptor)) return false;
   ClassDescriptor containingClass = (ClassDescriptor) containingDeclaration;
   return containingClass.isInner()
       || containingClass.getContainingDeclaration() instanceof FunctionDescriptor;
 }
Beispiel #8
0
 @NotNull
 public static FqName getFqNameFromTopLevelClass(@NotNull DeclarationDescriptor descriptor) {
   DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
   Name name = descriptor.getName();
   if (!(containingDeclaration instanceof ClassDescriptor)) {
     return FqName.topLevel(name);
   }
   return getFqNameFromTopLevelClass(containingDeclaration).child(name);
 }
Beispiel #9
0
 /** Descriptor may be local itself or have a local ancestor */
 public static boolean isLocal(@NotNull DeclarationDescriptor descriptor) {
   DeclarationDescriptor current = descriptor;
   while (current != null) {
     if (isAnonymousObject(current) || isDescriptorWithLocalVisibility(current)) {
       return true;
     }
     current = current.getContainingDeclaration();
   }
   return false;
 }
Beispiel #10
0
 @Nullable
 public static ModuleDescriptor getContainingModuleOrNull(
     @NotNull DeclarationDescriptor descriptor) {
   while (descriptor != null) {
     if (descriptor instanceof ModuleDescriptor) {
       return (ModuleDescriptor) descriptor;
     }
     if (descriptor instanceof PackageViewDescriptor) {
       return ((PackageViewDescriptor) descriptor).getModule();
     }
     //noinspection ConstantConditions
     descriptor = descriptor.getContainingDeclaration();
   }
   return null;
 }
Beispiel #11
0
 @Override
 public MemberChooserObject getParentNodeDelegate() {
   DeclarationDescriptor parent = myDescriptor.getContainingDeclaration();
   PsiElement declaration;
   if (myPsiElement instanceof JetDeclaration) {
     // kotlin
     declaration = PsiTreeUtil.getStubOrPsiParentOfType(myPsiElement, JetNamedDeclaration.class);
   } else {
     // java or bytecode
     declaration = ((PsiMember) myPsiElement).getContainingClass();
   }
   assert parent != null : NO_PARENT_FOR + myDescriptor;
   assert declaration != null : NO_PARENT_FOR + myPsiElement;
   return new DescriptorClassMember(declaration, parent);
 }
  @Nullable
  public TypeSubstitutor getOrCreateTypeSubstitutor() {
    if (!isInherited()) return null;

    if (typeSubstitutor == null) {
      if (samCallType == null) {
        typeSubstitutor = ChangeSignaturePackage.getFunctionSubstitutor(baseFunction, this);
      } else {
        DeclarationDescriptor currentBaseDescriptor = baseFunction.getCurrentFunctionDescriptor();
        DeclarationDescriptor classDescriptor =
            currentBaseDescriptor != null ? currentBaseDescriptor.getContainingDeclaration() : null;

        if (!(classDescriptor instanceof ClassDescriptor)) return null;

        typeSubstitutor =
            ChangeSignaturePackage.getTypeSubstitutor(
                ((ClassDescriptor) classDescriptor).getDefaultType(), samCallType);
      }
    }
    return typeSubstitutor;
  }
Beispiel #13
0
  /*descriptor is null for captured vars*/
  public boolean shouldPutValue(
      @NotNull Type type,
      @Nullable StackValue stackValue,
      @Nullable ValueParameterDescriptor descriptor) {

    if (stackValue == null) {
      // default or vararg
      return true;
    }

    // remap only inline functions (and maybe non primitives)
    // TODO - clean asserion and remapping logic
    if (isPrimitive(type) != isPrimitive(stackValue.type)) {
      // don't remap boxing/unboxing primitives - lost identity and perfomance
      return true;
    }

    if (stackValue instanceof StackValue.Local) {
      return false;
    }

    StackValue field = stackValue;
    if (stackValue instanceof StackValue.FieldForSharedVar) {
      field = ((StackValue.FieldForSharedVar) stackValue).receiver;
    }

    // check that value corresponds to captured inlining parameter
    if (field instanceof StackValue.Field) {
      DeclarationDescriptor varDescriptor = ((StackValue.Field) field).descriptor;
      // check that variable is inline function parameter
      return !(varDescriptor instanceof ParameterDescriptor
          && InlineUtil.isInlineLambdaParameter((ParameterDescriptor) varDescriptor)
          && InlineUtil.isInline(varDescriptor.getContainingDeclaration()));
    }

    return true;
  }
Beispiel #14
0
 public boolean isMemberOfAny(@NotNull DeclarationDescriptor descriptor) {
   return descriptor.getContainingDeclaration() == getAny();
 }
Beispiel #15
0
 /**
  * @return true if descriptor is a class inside another class and does not have access to the
  *     outer class
  */
 public static boolean isStaticNestedClass(@NotNull DeclarationDescriptor descriptor) {
   DeclarationDescriptor containing = descriptor.getContainingDeclaration();
   return descriptor instanceof ClassDescriptor
       && containing instanceof ClassDescriptor
       && !((ClassDescriptor) descriptor).isInner();
 }
Beispiel #16
0
  private void checkSupertypeList(
      @NotNull ClassDescriptor supertypeOwner,
      @NotNull Map<JetTypeReference, JetType> supertypes,
      @NotNull JetClassOrObject jetClass) {
    Set<TypeConstructor> allowedFinalSupertypes =
        getAllowedFinalSupertypes(supertypeOwner, jetClass);
    Set<TypeConstructor> typeConstructors = Sets.newHashSet();
    boolean classAppeared = false;
    for (Map.Entry<JetTypeReference, JetType> entry : supertypes.entrySet()) {
      JetTypeReference typeReference = entry.getKey();
      JetType supertype = entry.getValue();

      boolean addSupertype = true;

      ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
      if (classDescriptor != null) {
        if (ErrorUtils.isError(classDescriptor)) continue;

        if (classDescriptor.getKind() != ClassKind.INTERFACE) {
          if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) {
            trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference));
            addSupertype = false;
          } else if (supertypeOwner.getKind() == ClassKind.INTERFACE
              && !classAppeared
              && !TypesPackage.isDynamic(supertype) /* avoid duplicate diagnostics */) {
            trace.report(TRAIT_WITH_SUPERCLASS.on(typeReference));
            addSupertype = false;
          }

          if (classAppeared) {
            trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference));
          } else {
            classAppeared = true;
          }
        }
      } else {
        trace.report(SUPERTYPE_NOT_A_CLASS_OR_TRAIT.on(typeReference));
      }

      TypeConstructor constructor = supertype.getConstructor();
      if (addSupertype && !typeConstructors.add(constructor)) {
        trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
      }

      if (DescriptorUtils.isSingleton(classDescriptor)) {
        trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
      } else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) {
        if (classDescriptor.getModality() == Modality.SEALED) {
          DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration();
          while (containingDescriptor != null && containingDescriptor != classDescriptor) {
            containingDescriptor = containingDescriptor.getContainingDeclaration();
          }
          if (containingDescriptor == null) {
            trace.report(SEALED_SUPERTYPE.on(typeReference));
          } else {
            trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference));
          }
        } else {
          trace.report(FINAL_SUPERTYPE.on(typeReference));
        }
      }
    }
  }
Beispiel #17
0
 public static boolean isTopLevelDeclaration(@Nullable DeclarationDescriptor descriptor) {
   return descriptor != null
       && descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor;
 }