예제 #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));
      }
    }
예제 #2
0
 @NotNull
 private static PsiClass findClass(
     String qualifiedName, Project project, KotlinCoreEnvironment environment) {
   ModuleDescriptor module = LazyResolveTestUtil.resolveProject(project, environment);
   ClassDescriptor classDescriptor =
       DescriptorUtilsKt.resolveTopLevelClass(
           module, new FqName(qualifiedName), NoLookupLocation.FROM_TEST);
   assertNotNull("Class descriptor wasn't resolved: " + qualifiedName, classDescriptor);
   PsiClass psiClass = (PsiClass) DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);
   assertNotNull("Class declaration wasn't found: " + classDescriptor, psiClass);
   return psiClass;
 }
예제 #3
0
  @NotNull
  public static Pair<FunctionDescriptor, PsiElement> getContainingFunctionSkipFunctionLiterals(
      @Nullable DeclarationDescriptor startDescriptor, boolean strict) {
    FunctionDescriptor containingFunctionDescriptor =
        DescriptorUtils.getParentOfType(startDescriptor, FunctionDescriptor.class, strict);
    PsiElement containingFunction =
        containingFunctionDescriptor != null
            ? DescriptorToSourceUtils.getSourceFromDescriptor(containingFunctionDescriptor)
            : null;
    while (containingFunction instanceof JetFunctionLiteral) {
      containingFunctionDescriptor =
          DescriptorUtils.getParentOfType(containingFunctionDescriptor, FunctionDescriptor.class);
      containingFunction =
          containingFunctionDescriptor != null
              ? DescriptorToSourceUtils.getSourceFromDescriptor(containingFunctionDescriptor)
              : null;
    }

    return new Pair<FunctionDescriptor, PsiElement>(
        containingFunctionDescriptor, containingFunction);
  }
예제 #4
0
  private void checkOpenMembers(ClassDescriptorWithResolutionScopes classDescriptor) {
    if (classCanHaveOpenMembers(classDescriptor)) return;

    for (CallableMemberDescriptor memberDescriptor : classDescriptor.getDeclaredCallableMembers()) {
      if (memberDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) continue;
      JetNamedDeclaration member =
          (JetNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(memberDescriptor);
      if (member != null && member.hasModifier(JetTokens.OPEN_KEYWORD)) {
        trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member));
      }
    }
  }
예제 #5
0
 public static void reportAmbiguousLabel(
     @NotNull BindingTrace trace,
     @NotNull JetSimpleNameExpression targetLabel,
     @NotNull Collection<DeclarationDescriptor> declarationsByLabel) {
   Collection<PsiElement> targets = Lists.newArrayList();
   for (DeclarationDescriptor descriptor : declarationsByLabel) {
     PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
     assert element != null : "Label can only point to something in the same lexical scope";
     targets.add(element);
   }
   if (!targets.isEmpty()) {
     trace.record(AMBIGUOUS_LABEL_TARGET, targetLabel, targets);
   }
   trace.report(AMBIGUOUS_LABEL.on(targetLabel));
 }
예제 #6
0
  private void reportEachConstructorOnCycle(@NotNull ConstructorDescriptor startConstructor) {
    ConstructorDescriptor currentConstructor = startConstructor;
    do {
      PsiElement constructorToReport =
          DescriptorToSourceUtils.descriptorToDeclaration(currentConstructor);
      if (constructorToReport != null) {
        JetConstructorDelegationCall call =
            ((JetSecondaryConstructor) constructorToReport).getDelegationCall();
        assert call.getCalleeExpression() != null
            : "Callee expression of delegation call should not be null on cycle as there should be explicit 'this' calls";
        trace.report(CYCLIC_CONSTRUCTOR_DELEGATION_CALL.on(call.getCalleeExpression()));
      }

      currentConstructor = getDelegatedConstructor(currentConstructor);
      assert currentConstructor != null : "Delegated constructor should not be null in cycle";
    } while (startConstructor != currentConstructor);
  }
예제 #7
0
  private void checkSupertypesForConsistency(@NotNull ClassDescriptor classDescriptor) {
    Multimap<TypeConstructor, TypeProjection> multimap =
        SubstitutionUtils.buildDeepSubstitutionMultimap(classDescriptor.getDefaultType());
    for (Map.Entry<TypeConstructor, Collection<TypeProjection>> entry :
        multimap.asMap().entrySet()) {
      Collection<TypeProjection> projections = entry.getValue();
      if (projections.size() > 1) {
        TypeConstructor typeConstructor = entry.getKey();
        DeclarationDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor();
        assert declarationDescriptor instanceof TypeParameterDescriptor : declarationDescriptor;
        TypeParameterDescriptor typeParameterDescriptor =
            (TypeParameterDescriptor) declarationDescriptor;

        // Immediate arguments of supertypes cannot be projected
        Set<JetType> conflictingTypes = Sets.newLinkedHashSet();
        for (TypeProjection projection : projections) {
          conflictingTypes.add(projection.getType());
        }
        removeDuplicateTypes(conflictingTypes);
        if (conflictingTypes.size() > 1) {
          DeclarationDescriptor containingDeclaration =
              typeParameterDescriptor.getContainingDeclaration();
          assert containingDeclaration instanceof ClassDescriptor : containingDeclaration;
          JetClassOrObject psiElement =
              (JetClassOrObject) DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);
          assert psiElement != null;
          JetDelegationSpecifierList delegationSpecifierList =
              psiElement.getDelegationSpecifierList();
          assert delegationSpecifierList != null;
          //
          // trace.getErrorHandler().genericError(delegationSpecifierList.getNode(), "Type parameter
          // " + typeParameterDescriptor.getName() + " of " + containingDeclaration.getName() + "
          // has inconsistent values: " + conflictingTypes);
          trace.report(
              INCONSISTENT_TYPE_PARAMETER_VALUES.on(
                  delegationSpecifierList,
                  typeParameterDescriptor,
                  (ClassDescriptor) containingDeclaration,
                  conflictingTypes));
        }
      }
    }
  }