Ejemplo n.º 1
0
    private void reportCyclicInheritanceHierarchyError(
        @NotNull BindingTrace trace,
        @NotNull ClassDescriptor classDescriptor,
        @NotNull ClassDescriptor superclass) {
      PsiElement psiElement = DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);

      PsiElement elementToMark = null;
      if (psiElement instanceof KtClassOrObject) {
        KtClassOrObject classOrObject = (KtClassOrObject) psiElement;
        for (KtSuperTypeListEntry delegationSpecifier : classOrObject.getSuperTypeListEntries()) {
          KtTypeReference typeReference = delegationSpecifier.getTypeReference();
          if (typeReference == null) continue;
          KotlinType supertype = trace.get(TYPE, typeReference);
          if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
            elementToMark = typeReference;
          }
        }
      }
      if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
        PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
        PsiElement nameIdentifier = namedElement.getNameIdentifier();
        if (nameIdentifier != null) {
          elementToMark = nameIdentifier;
        }
      }
      if (elementToMark != null) {
        trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
      }
    }
Ejemplo n.º 2
0
  @Override
  protected void generateBody() {
    List<KtObjectDeclaration> companions = new ArrayList<KtObjectDeclaration>();
    if (kind != OwnerKind.DEFAULT_IMPLS) {
      // generate nested classes first and only then generate class body. It necessary to access to
      // nested CodegenContexts
      for (KtDeclaration declaration : myClass.getDeclarations()) {
        if (shouldProcessFirst(declaration)) {
          // Generate companions after class body generation (need to record all synthetic
          // accessors)
          if (declaration instanceof KtObjectDeclaration
              && ((KtObjectDeclaration) declaration).isCompanion()) {
            companions.add((KtObjectDeclaration) declaration);
            CodegenUtilKt.populateCompanionBackingFieldNamesToOuterContextIfNeeded(
                (KtObjectDeclaration) declaration, context, state);
          } else {
            generateDeclaration(declaration);
          }
        }
      }
    }

    for (KtDeclaration declaration : myClass.getDeclarations()) {
      if (!shouldProcessFirst(declaration)) {
        generateDeclaration(declaration);
      }
    }

    generatePrimaryConstructorProperties();
    generateConstructors();
    generateDefaultImplsIfNeeded();

    for (KtObjectDeclaration companion : companions) {
      generateDeclaration(companion);
    }

    if (!DescriptorUtils.isInterface(descriptor)) {
      for (DeclarationDescriptor memberDescriptor :
          DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
        if (memberDescriptor instanceof CallableMemberDescriptor) {
          CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
          if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) {
            if (member instanceof FunctionDescriptor) {
              functionCodegen.generateBridges((FunctionDescriptor) member);
            } else if (member instanceof PropertyDescriptor) {
              PropertyGetterDescriptor getter = ((PropertyDescriptor) member).getGetter();
              if (getter != null) {
                functionCodegen.generateBridges(getter);
              }
              PropertySetterDescriptor setter = ((PropertyDescriptor) member).getSetter();
              if (setter != null) {
                functionCodegen.generateBridges(setter);
              }
            }
          }
        }
      }
    }
  }
Ejemplo n.º 3
0
  public LazyClassDescriptor(
      @NotNull final LazyClassContext c,
      @NotNull DeclarationDescriptor containingDeclaration,
      @NotNull Name name,
      @NotNull final KtClassLikeInfo classLikeInfo) {
    super(
        c.getStorageManager(),
        containingDeclaration,
        name,
        KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject()));
    this.c = c;

    KtClassOrObject classOrObject = classLikeInfo.getCorrespondingClassOrObject();
    if (classOrObject != null) {
      this.c.getTrace().record(BindingContext.CLASS, classOrObject, this);
    }
    this.c
        .getTrace()
        .record(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, DescriptorUtils.getFqName(this), this);

    this.declarationProvider =
        c.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfo);

    StorageManager storageManager = c.getStorageManager();

    this.unsubstitutedMemberScope = createMemberScope(c, this.declarationProvider);
    this.kind = classLikeInfo.getClassKind();
    this.staticScope =
        kind == ClassKind.ENUM_CLASS
            ? new StaticScopeForKotlinEnum(storageManager, this)
            : MemberScope.Empty.INSTANCE;

    this.typeConstructor = new LazyClassTypeConstructor();

    this.isCompanionObject =
        classLikeInfo instanceof KtObjectInfo && ((KtObjectInfo) classLikeInfo).isCompanionObject();

    KtModifierList modifierList = classLikeInfo.getModifierList();
    if (kind.isSingleton()) {
      this.modality = Modality.FINAL;
    } else {
      Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL;
      this.modality =
          resolveModalityFromModifiers(modifierList, defaultModality, /* allowSealed = */ true);
    }

    boolean isLocal = classOrObject != null && KtPsiUtil.isLocal(classOrObject);
    Visibility defaultVisibility;
    if (kind == ClassKind.ENUM_ENTRY || (kind == ClassKind.OBJECT && isCompanionObject)) {
      defaultVisibility = Visibilities.PUBLIC;
    } else {
      defaultVisibility = Visibilities.DEFAULT_VISIBILITY;
    }
    this.visibility =
        isLocal
            ? Visibilities.LOCAL
            : resolveVisibilityFromModifiers(modifierList, defaultVisibility);

    this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this);
    this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD);

    // Annotation entries are taken from both own annotations (if any) and object literal
    // annotations (if any)
    List<KtAnnotationEntry> annotationEntries = new ArrayList<KtAnnotationEntry>();
    if (classOrObject != null && classOrObject.getParent() instanceof KtObjectLiteralExpression) {
      // TODO: it would be better to have separate ObjectLiteralDescriptor without so much magic
      annotationEntries.addAll(
          KtPsiUtilKt.getAnnotationEntries((KtObjectLiteralExpression) classOrObject.getParent()));
    }
    if (modifierList != null) {
      annotationEntries.addAll(modifierList.getAnnotationEntries());
    }
    if (!annotationEntries.isEmpty()) {
      this.annotations =
          new LazyAnnotations(
              new LazyAnnotationsContext(c.getAnnotationResolver(), storageManager, c.getTrace()) {
                @NotNull
                @Override
                public LexicalScope getScope() {
                  return getOuterScope();
                }
              },
              annotationEntries);
    } else {
      this.annotations = Annotations.Companion.getEMPTY();
    }

    List<KtAnnotationEntry> jetDanglingAnnotations = classLikeInfo.getDanglingAnnotations();
    if (jetDanglingAnnotations.isEmpty()) {
      this.danglingAnnotations = Annotations.Companion.getEMPTY();
    } else {
      this.danglingAnnotations =
          new LazyAnnotations(
              new LazyAnnotationsContext(c.getAnnotationResolver(), storageManager, c.getTrace()) {
                @NotNull
                @Override
                public LexicalScope getScope() {
                  return getScopeForMemberDeclarationResolution();
                }
              },
              jetDanglingAnnotations);
    }

    this.companionObjectDescriptor =
        storageManager.createNullableLazyValue(
            new Function0<LazyClassDescriptor>() {
              @Override
              public LazyClassDescriptor invoke() {
                return computeCompanionObjectDescriptor(getCompanionObjectIfAllowed());
              }
            });
    this.extraCompanionObjectDescriptors =
        storageManager.createMemoizedFunction(
            new Function1<KtObjectDeclaration, ClassDescriptor>() {
              @Override
              public ClassDescriptor invoke(KtObjectDeclaration companionObject) {
                return computeCompanionObjectDescriptor(companionObject);
              }
            });
    this.forceResolveAllContents =
        storageManager.createRecursionTolerantNullableLazyValue(
            new Function0<Void>() {
              @Override
              public Void invoke() {
                doForceResolveAllContents();
                return null;
              }
            },
            null);

    this.resolutionScopesSupport =
        new ClassResolutionScopesSupport(
            this,
            storageManager,
            new Function0<LexicalScope>() {
              @Override
              public LexicalScope invoke() {
                return getOuterScope();
              }
            });

    this.parameters =
        c.getStorageManager()
            .createLazyValue(
                new Function0<List<TypeParameterDescriptor>>() {
                  @Override
                  public List<TypeParameterDescriptor> invoke() {
                    KtClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
                    KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
                    if (typeParameterList == null) return Collections.emptyList();

                    if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
                      c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
                    }

                    List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
                    if (typeParameters.isEmpty()) return Collections.emptyList();

                    List<TypeParameterDescriptor> parameters =
                        new ArrayList<TypeParameterDescriptor>(typeParameters.size());

                    for (int i = 0; i < typeParameters.size(); i++) {
                      parameters.add(
                          new LazyTypeParameterDescriptor(
                              c, LazyClassDescriptor.this, typeParameters.get(i), i));
                    }

                    return parameters;
                  }
                });

    this.scopeForInitializerResolution =
        storageManager.createLazyValue(
            new Function0<LexicalScope>() {
              @Override
              public LexicalScope invoke() {
                return ClassResolutionScopesSupportKt.scopeForInitializerResolution(
                    LazyClassDescriptor.this,
                    createInitializerScopeParent(),
                    classLikeInfo.getPrimaryConstructorParameters());
              }
            });
  }