예제 #1
0
 private void checkAccessors(
     @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) {
   for (JetPropertyAccessor accessor : property.getAccessors()) {
     PropertyAccessorDescriptor propertyAccessorDescriptor =
         accessor.isGetter() ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
     assert propertyAccessorDescriptor != null
         : "No property accessor descriptor for " + property.getText();
     modifiersChecker.checkModifiersForDeclaration(accessor, propertyAccessorDescriptor);
     modifiersChecker.reportIllegalModalityModifiers(accessor);
   }
   JetPropertyAccessor getter = property.getGetter();
   PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
   JetModifierList getterModifierList = getter != null ? getter.getModifierList() : null;
   if (getterModifierList != null && getterDescriptor != null) {
     Map<JetModifierKeywordToken, ASTNode> nodes =
         ModifiersChecker.getNodesCorrespondingToModifiers(
             getterModifierList,
             Sets.newHashSet(
                 JetTokens.PUBLIC_KEYWORD,
                 JetTokens.PROTECTED_KEYWORD,
                 JetTokens.PRIVATE_KEYWORD,
                 JetTokens.INTERNAL_KEYWORD));
     if (getterDescriptor.getVisibility() != propertyDescriptor.getVisibility()) {
       for (ASTNode node : nodes.values()) {
         trace.report(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.on(node.getPsi()));
       }
     } else {
       for (ASTNode node : nodes.values()) {
         trace.report(Errors.REDUNDANT_MODIFIER_IN_GETTER.on(node.getPsi()));
       }
     }
   }
 }
예제 #2
0
  private void checkClass(
      BodiesResolveContext c,
      JetClass aClass,
      ClassDescriptorWithResolutionScopes classDescriptor) {
    checkOpenMembers(classDescriptor);
    checkTypeParameters(aClass);

    if (aClass.isInterface()) {
      ASTNode traitKeyword = aClass.getNode().findChildByType(JetTokens.TRAIT_KEYWORD);
      if (traitKeyword != null) {
        trace.report(Errors.DEPRECATED_TRAIT_KEYWORD.on(traitKeyword.getPsi()));
      }

      checkTraitModifiers(aClass);
      checkConstructorInTrait(aClass);
    } else if (aClass.isAnnotation()) {
      checkAnnotationClassWithBody(aClass);
      checkValOnAnnotationParameter(aClass);
    } else if (aClass.isEnum()) {
      checkEnumModifiers(aClass);
      if (aClass.isLocal()) {
        trace.report(LOCAL_ENUM_NOT_ALLOWED.on(aClass, classDescriptor));
      }
    } else if (aClass.hasModifier(JetTokens.SEALED_KEYWORD)) {
      checkSealedModifiers(aClass);
    } else if (aClass instanceof JetEnumEntry) {
      checkEnumEntry((JetEnumEntry) aClass, classDescriptor);
    }
  }
예제 #3
0
 private void checkEnumModifiers(JetClass aClass) {
   if (aClass.hasModifier(JetTokens.OPEN_KEYWORD)) {
     trace.report(OPEN_MODIFIER_IN_ENUM.on(aClass));
   }
   if (aClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
     trace.report(ABSTRACT_MODIFIER_IN_ENUM.on(aClass));
   }
   if (aClass.hasModifier(JetTokens.SEALED_KEYWORD)) {
     trace.report(SEALED_MODIFIER_IN_ENUM.on(aClass));
   }
 }
예제 #4
0
 private void checkSealedModifiers(JetClass aClass) {
   if (aClass.hasModifier(JetTokens.OPEN_KEYWORD)) {
     trace.report(OPEN_MODIFIER_IN_SEALED.on(aClass));
   }
   if (aClass.hasModifier(JetTokens.FINAL_KEYWORD)) {
     trace.report(FINAL_MODIFIER_IN_SEALED.on(aClass));
   }
   if (aClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
     trace.report(ABSTRACT_MODIFIER_IN_SEALED.on(aClass));
   }
 }
예제 #5
0
  public static void reportCyclicInheritanceHierarchyError(
      @NotNull BindingTrace trace,
      @NotNull ClassDescriptor classDescriptor,
      @NotNull ClassDescriptor superclass) {
    PsiElement psiElement =
        BindingContextUtils.classDescriptorToDeclaration(
            trace.getBindingContext(), classDescriptor);

    PsiElement elementToMark = null;
    if (psiElement instanceof JetClassOrObject) {
      JetClassOrObject classOrObject = (JetClassOrObject) psiElement;
      for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
        JetTypeReference typeReference = delegationSpecifier.getTypeReference();
        if (typeReference == null) continue;
        JetType 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));
    }
  }
  @NotNull
  public Collection<? extends DeclarationDescriptor> lookupDescriptorsForUserType(
      @NotNull JetUserType userType, @NotNull JetScope outerScope, @NotNull BindingTrace trace) {

    if (userType.isAbsoluteInRootNamespace()) {
      trace.report(Errors.UNSUPPORTED.on(userType, "package"));
      return Collections.emptyList();
    }
    JetSimpleNameExpression referenceExpression = userType.getReferenceExpression();
    if (referenceExpression == null) {
      return Collections.emptyList();
    }
    JetUserType qualifier = userType.getQualifier();
    if (qualifier == null) {
      return lookupDescriptorsForSimpleNameReference(
          referenceExpression, outerScope, outerScope, trace, LookupMode.ONLY_CLASSES, false, true);
    }
    Collection<? extends DeclarationDescriptor> declarationDescriptors =
        lookupDescriptorsForUserType(qualifier, outerScope, trace);
    return lookupSelectorDescriptors(
        referenceExpression,
        declarationDescriptors,
        trace,
        outerScope,
        LookupMode.ONLY_CLASSES,
        true);
  }
예제 #7
0
 private void checkValOnAnnotationParameter(JetClass aClass) {
   for (JetParameter parameter : aClass.getPrimaryConstructorParameters()) {
     if (!parameter.hasValOrVar()) {
       trace.report(MISSING_VAL_ON_ANNOTATION_PARAMETER.on(parameter));
     }
   }
 }
예제 #8
0
  static void addOwnDataTo(
      @NotNull final BindingTrace trace,
      @Nullable final TraceEntryFilter filter,
      boolean commitDiagnostics,
      @NotNull MutableSlicedMap map,
      MutableDiagnosticsWithSuppression diagnostics) {
    map.forEach(
        new Function3<WritableSlice, Object, Object, Void>() {
          @Override
          public Void invoke(WritableSlice slice, Object key, Object value) {
            if (filter == null || filter.accept(slice, key)) {
              trace.record(slice, key, value);
            }

            return null;
          }
        });

    if (!commitDiagnostics) return;

    for (Diagnostic diagnostic : diagnostics.getOwnDiagnostics()) {
      if (filter == null || filter.accept(null, diagnostic.getPsiElement())) {
        trace.report(diagnostic);
      }
    }
  }
예제 #9
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));
      }
    }
예제 #10
0
 private void checkTraitModifiers(JetClass aClass) {
   reportErrorIfHasIllegalModifier(aClass);
   JetModifierList modifierList = aClass.getModifierList();
   if (modifierList == null) return;
   if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) {
     trace.report(Errors.TRAIT_CAN_NOT_BE_FINAL.on(aClass));
   }
   if (modifierList.hasModifier(JetTokens.SEALED_KEYWORD)) {
     trace.report(Errors.TRAIT_CAN_NOT_BE_SEALED.on(aClass));
   }
   if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
     trace.report(Errors.ABSTRACT_MODIFIER_IN_TRAIT.on(aClass));
   }
   if (modifierList.hasModifier(JetTokens.OPEN_KEYWORD)) {
     trace.report(Errors.OPEN_MODIFIER_IN_TRAIT.on(aClass));
   }
 }
예제 #11
0
 public void checkParameterHasNoValOrVar(
     @NotNull JetParameter parameter,
     @NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory) {
   PsiElement valOrVar = parameter.getValOrVarKeyword();
   if (valOrVar != null) {
     trace.report(
         diagnosticFactory.on(
             valOrVar, ((JetKeywordToken) valOrVar.getNode().getElementType())));
   }
 }
예제 #12
0
  private void checkEnumEntry(
      @NotNull JetEnumEntry enumEntry, @NotNull ClassDescriptor classDescriptor) {
    DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
    assert DescriptorUtils.isEnumClass(declaration)
        : "Enum entry should be declared in enum class: " + classDescriptor;
    ClassDescriptor enumClass = (ClassDescriptor) declaration;

    if (enumEntryUsesDeprecatedSuperConstructor(enumEntry)) {
      trace.report(
          Errors.ENUM_ENTRY_USES_DEPRECATED_SUPER_CONSTRUCTOR.on(enumEntry, classDescriptor));
    }
    String neededDelimiter = enumEntryExpectedDelimiter(enumEntry);
    if (!neededDelimiter.isEmpty()) {
      trace.report(
          Errors.ENUM_ENTRY_USES_DEPRECATED_OR_NO_DELIMITER.on(
              enumEntry, classDescriptor, neededDelimiter));
    }
    if (enumEntryAfterEnumMember(enumEntry)) {
      trace.report(Errors.ENUM_ENTRY_AFTER_ENUM_MEMBER.on(enumEntry, classDescriptor));
    }

    List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
    ConstructorDescriptor constructor = enumClass.getUnsubstitutedPrimaryConstructor();
    if ((constructor == null || !constructor.getValueParameters().isEmpty())
        && delegationSpecifiers.isEmpty()) {
      trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(enumEntry, enumClass));
    }

    for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
      JetTypeReference typeReference = delegationSpecifier.getTypeReference();
      if (typeReference != null) {
        JetType type = trace.getBindingContext().get(TYPE, typeReference);
        if (type != null) {
          JetType enumType = enumClass.getDefaultType();
          if (!type.getConstructor().equals(enumType.getConstructor())) {
            trace.report(ENUM_ENTRY_ILLEGAL_TYPE.on(typeReference, enumClass));
          }
        }
      }
    }
  }
예제 #13
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));
      }
    }
  }
예제 #14
0
 private void checkNestedClassAllowed(
     @NotNull JetModifierListOwner modifierListOwner,
     @NotNull DeclarationDescriptor descriptor) {
   if (modifierListOwner.hasModifier(INNER_KEYWORD)) return;
   if (modifierListOwner instanceof JetClass && !(modifierListOwner instanceof JetEnumEntry)) {
     JetClass aClass = (JetClass) modifierListOwner;
     boolean localEnumError = aClass.isLocal() && aClass.isEnum();
     if (!localEnumError && isIllegalNestedClass(descriptor)) {
       trace.report(NESTED_CLASS_NOT_ALLOWED.on(aClass));
     }
   }
 }
예제 #15
0
 protected void checkFunction(
     JetNamedFunction function, SimpleFunctionDescriptor functionDescriptor) {
   reportErrorIfHasIllegalModifier(function);
   DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
   boolean hasAbstractModifier = function.hasModifier(JetTokens.ABSTRACT_KEYWORD);
   checkDeclaredTypeInPublicMember(function, functionDescriptor);
   if (containingDescriptor instanceof ClassDescriptor) {
     ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
     boolean inTrait = classDescriptor.getKind() == ClassKind.INTERFACE;
     if (hasAbstractModifier && !classCanHaveAbstractMembers(classDescriptor)) {
       trace.report(
           ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(
               function, functionDescriptor.getName().asString(), classDescriptor));
     }
     if (hasAbstractModifier && inTrait) {
       trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(function));
     }
     boolean hasBody = function.hasBody();
     if (hasBody && hasAbstractModifier) {
       trace.report(ABSTRACT_FUNCTION_WITH_BODY.on(function, functionDescriptor));
     }
     if (!hasBody && function.hasModifier(JetTokens.FINAL_KEYWORD) && inTrait) {
       trace.report(FINAL_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
     }
     if (!hasBody && !hasAbstractModifier && !inTrait) {
       trace.report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
     }
     return;
   }
   modifiersChecker.reportIllegalModalityModifiers(function);
   if (!function.hasBody() && !hasAbstractModifier) {
     trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
   }
 }
예제 #16
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));
 }
예제 #17
0
 private static boolean canImportMembersFrom(
     @NotNull DeclarationDescriptor descriptor,
     @NotNull JetSimpleNameExpression reference,
     @NotNull BindingTrace trace,
     @NotNull LookupMode lookupMode) {
   assert lookupMode == LookupMode.EVERYTHING;
   if (descriptor instanceof PackageViewDescriptor) {
     return true;
   }
   if (descriptor instanceof ClassDescriptor) {
     return true;
   }
   trace.report(CANNOT_IMPORT_FROM_ELEMENT.on(reference, descriptor));
   return false;
 }
  private void checkVisibility(
      @NotNull DeclarationDescriptorWithVisibility descriptor,
      @NotNull BindingTrace trace,
      @NotNull JetSimpleNameExpression referenceExpression,
      @NotNull JetScope scopeToCheckVisibility) {

    if (!Visibilities.isVisible(descriptor, scopeToCheckVisibility.getContainingDeclaration())) {
      trace.report(
          INVISIBLE_REFERENCE.on(
              referenceExpression,
              descriptor,
              descriptor.getVisibility(),
              descriptor.getContainingDeclaration()));
    }
  }
예제 #19
0
  private void checkPrimaryConstructor(
      JetClassOrObject classOrObject, ClassDescriptor classDescriptor) {
    ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
    JetPrimaryConstructor declaration = classOrObject.getPrimaryConstructor();
    if (primaryConstructor == null || declaration == null) return;

    for (JetParameter parameter : declaration.getValueParameters()) {
      PropertyDescriptor propertyDescriptor =
          trace.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
      if (propertyDescriptor != null) {
        modifiersChecker.checkModifiersForDeclaration(parameter, propertyDescriptor);
      }
    }

    if (declaration.getModifierList() != null && !declaration.hasConstructorKeyword()) {
      trace.report(MISSING_CONSTRUCTOR_KEYWORD.on(declaration.getModifierList()));
    }

    if (!(classOrObject instanceof JetClass)) {
      trace.report(CONSTRUCTOR_IN_OBJECT.on(declaration));
    }

    checkConstructorDeclaration(primaryConstructor, declaration);
  }
예제 #20
0
 private static void checkVisibility(
     @NotNull DeclarationDescriptorWithVisibility descriptor,
     @NotNull BindingTrace trace,
     @NotNull JetSimpleNameExpression referenceExpression,
     @NotNull JetScope scopeToCheckVisibility) {
   if (!Visibilities.isVisible(
       ReceiverValue.IRRELEVANT_RECEIVER,
       descriptor,
       scopeToCheckVisibility.getContainingDeclaration())) {
     Visibility visibility = descriptor.getVisibility();
     if (PsiTreeUtil.getParentOfType(referenceExpression, JetImportDirective.class) != null
         && !visibility.mustCheckInImports()) return;
     //noinspection ConstantConditions
     trace.report(
         INVISIBLE_REFERENCE.on(
             referenceExpression, descriptor, visibility, descriptor.getContainingDeclaration()));
   }
 }
예제 #21
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));
        }
      }
    }
  }
예제 #22
0
 private void checkDeclaredTypeInPublicMember(
     JetNamedDeclaration member, CallableMemberDescriptor memberDescriptor) {
   boolean hasDeferredType;
   if (member instanceof JetProperty) {
     hasDeferredType =
         ((JetProperty) member).getTypeReference() == null
             && DescriptorResolver.hasBody((JetProperty) member);
   } else {
     assert member instanceof JetFunction;
     JetFunction function = (JetFunction) member;
     hasDeferredType =
         function.getTypeReference() == null && function.hasBody() && !function.hasBlockBody();
   }
   if ((memberDescriptor.getVisibility().isPublicAPI())
       && memberDescriptor.getOverriddenDescriptors().size() == 0
       && hasDeferredType) {
     trace.report(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE.on(member));
   }
 }
예제 #23
0
  private void checkRedeclarationsInPackages(@NotNull TopDownAnalysisContext c) {
    for (MutablePackageFragmentDescriptor packageFragment :
        Sets.newHashSet(c.getPackageFragments().values())) {
      PackageViewDescriptor packageView =
          packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName());
      JetScope packageViewScope = packageView.getMemberScope();
      Multimap<Name, DeclarationDescriptor> simpleNameDescriptors =
          packageFragment.getMemberScope().getDeclaredDescriptorsAccessibleBySimpleName();
      for (Name name : simpleNameDescriptors.keySet()) {
        // Keep only properties with no receiver
        Collection<DeclarationDescriptor> descriptors =
            Collections2.filter(
                simpleNameDescriptors.get(name),
                new Predicate<DeclarationDescriptor>() {
                  @Override
                  public boolean apply(@Nullable DeclarationDescriptor descriptor) {
                    if (descriptor instanceof PropertyDescriptor) {
                      PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
                      return propertyDescriptor.getReceiverParameter() == null;
                    }
                    return true;
                  }
                });
        ContainerUtil.addIfNotNull(descriptors, packageViewScope.getPackage(name));

        if (descriptors.size() > 1) {
          for (DeclarationDescriptor declarationDescriptor : descriptors) {
            for (PsiElement declaration : getDeclarationsByDescriptor(declarationDescriptor)) {
              assert declaration != null
                  : "Null declaration for descriptor: "
                      + declarationDescriptor
                      + " "
                      + (declarationDescriptor != null
                          ? DescriptorRenderer.FQ_NAMES_IN_TYPES.render(declarationDescriptor)
                          : "");
              trace.report(
                  REDECLARATION.on(declaration, declarationDescriptor.getName().asString()));
            }
          }
        }
      }
    }
  }
예제 #24
0
  @NotNull
  public Collection<DeclarationDescriptor> lookupDescriptorsForUserType(
      @NotNull JetUserType userType,
      @NotNull JetScope outerScope,
      @NotNull BindingTrace trace,
      boolean onlyClassifiers) {

    if (userType.isAbsoluteInRootPackage()) {
      trace.report(Errors.UNSUPPORTED.on(userType, "package"));
      return Collections.emptyList();
    }

    JetSimpleNameExpression referenceExpression = userType.getReferenceExpression();
    if (referenceExpression == null) {
      return Collections.emptyList();
    }
    JetUserType qualifier = userType.getQualifier();

    // We do not want to resolve the last segment of a user type to a package
    JetScope filteredScope = filterOutPackagesIfNeeded(outerScope, onlyClassifiers);

    if (qualifier == null) {
      return lookupDescriptorsForSimpleNameReference(
          referenceExpression,
          filteredScope,
          outerScope,
          trace,
          LookupMode.ONLY_CLASSES_AND_PACKAGES,
          false,
          true);
    }
    Collection<DeclarationDescriptor> declarationDescriptors =
        lookupDescriptorsForUserType(qualifier, outerScope, trace, false);
    return lookupSelectorDescriptors(
        referenceExpression,
        declarationDescriptors,
        trace,
        filteredScope,
        LookupMode.ONLY_CLASSES_AND_PACKAGES,
        true);
  }
예제 #25
0
  private void checkModifiersAndAnnotationsInPackageDirective(JetFile file) {
    JetPackageDirective packageDirective = file.getPackageDirective();
    if (packageDirective == null) return;

    JetModifierList modifierList = packageDirective.getModifierList();
    if (modifierList == null) return;

    for (JetAnnotationEntry annotationEntry : modifierList.getAnnotationEntries()) {
      JetConstructorCalleeExpression calleeExpression = annotationEntry.getCalleeExpression();
      if (calleeExpression != null) {
        JetReferenceExpression reference = calleeExpression.getConstructorReferenceExpression();
        if (reference != null) {
          trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
        }
      }
    }
    AnnotationTargetChecker.INSTANCE$.check(packageDirective, trace);

    ModifiersChecker.reportIllegalModifiers(
        modifierList, Arrays.asList(JetTokens.MODIFIER_KEYWORDS_ARRAY), trace);
  }
예제 #26
0
  public void checkRedeclarationsInPackages(
      @NotNull KotlinCodeAnalyzer resolveSession,
      @NotNull Multimap<FqName, JetElement> topLevelFqNames) {
    for (Map.Entry<FqName, Collection<JetElement>> entry : topLevelFqNames.asMap().entrySet()) {
      FqName fqName = entry.getKey();
      Collection<JetElement> declarationsOrPackageDirectives = entry.getValue();

      if (fqName.isRoot()) continue;

      Set<DeclarationDescriptor> descriptors =
          getTopLevelDescriptorsByFqName(resolveSession, fqName);

      if (descriptors.size() > 1) {
        for (JetElement declarationOrPackageDirective : declarationsOrPackageDirectives) {
          PsiElement reportAt =
              declarationOrPackageDirective instanceof JetNamedDeclaration
                  ? declarationOrPackageDirective
                  : ((JetPackageDirective) declarationOrPackageDirective).getNameIdentifier();
          trace.report(Errors.REDECLARATION.on(reportAt, fqName.shortName().asString()));
        }
      }
    }
  }
예제 #27
0
  private void reportRedeclarations(@NotNull Multimap<Name, DeclarationDescriptor> descriptorMap) {
    Set<Pair<PsiElement, Name>> redeclarations = Sets.newHashSet();
    for (Name name : descriptorMap.keySet()) {
      Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name);
      if (descriptors.size() > 1) {
        // We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at
        // OverloadResolver
        for (DeclarationDescriptor descriptor : descriptors) {
          if (descriptor instanceof ClassDescriptor) {
            for (DeclarationDescriptor descriptor2 : descriptors) {
              if (descriptor == descriptor2) {
                continue;
              }

              redeclarations.add(
                  Pair.create(
                      BindingContextUtils.classDescriptorToDeclaration(
                          trace.getBindingContext(), (ClassDescriptor) descriptor),
                      descriptor.getName()));
              if (descriptor2 instanceof PropertyDescriptor) {
                redeclarations.add(
                    Pair.create(
                        BindingContextUtils.descriptorToDeclaration(
                            trace.getBindingContext(), descriptor2),
                        descriptor2.getName()));
              }
            }
          }
        }
      }
    }
    for (Pair<PsiElement, Name> redeclaration : redeclarations) {
      trace.report(
          REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString()));
    }
  }
예제 #28
0
  private void checkPropertyAbstractness(
      @NotNull JetProperty property,
      @NotNull PropertyDescriptor propertyDescriptor,
      @NotNull ClassDescriptor classDescriptor) {
    JetPropertyAccessor getter = property.getGetter();
    JetPropertyAccessor setter = property.getSetter();
    JetModifierList modifierList = property.getModifierList();
    ASTNode abstractNode =
        modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;

    if (abstractNode != null) { // has abstract modifier
      if (!classCanHaveAbstractMembers(classDescriptor)) {
        String name = property.getName();
        trace.report(
            ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(
                property, name != null ? name : "", classDescriptor));
        return;
      }
      if (classDescriptor.getKind() == ClassKind.INTERFACE) {
        trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(property));
      }
    }

    if (propertyDescriptor.getModality() == Modality.ABSTRACT) {
      JetExpression initializer = property.getInitializer();
      if (initializer != null) {
        trace.report(ABSTRACT_PROPERTY_WITH_INITIALIZER.on(initializer));
      }
      JetPropertyDelegate delegate = property.getDelegate();
      if (delegate != null) {
        trace.report(ABSTRACT_DELEGATED_PROPERTY.on(delegate));
      }
      if (getter != null && getter.hasBody()) {
        trace.report(ABSTRACT_PROPERTY_WITH_GETTER.on(getter));
      }
      if (setter != null && setter.hasBody()) {
        trace.report(ABSTRACT_PROPERTY_WITH_SETTER.on(setter));
      }
    }
  }
예제 #29
0
  @NotNull
  public Collection<DeclarationDescriptor> processImportReference(
      @NotNull JetImportDirective importDirective,
      @NotNull JetScope scope,
      @NotNull JetScope scopeToCheckVisibility,
      @Nullable Importer importer,
      @NotNull BindingTrace trace,
      @NotNull LookupMode lookupMode) {
    if (importDirective.isAbsoluteInRootPackage()) {
      trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
      return Collections.emptyList();
    }
    JetExpression importedReference = importDirective.getImportedReference();
    if (importedReference == null) {
      return Collections.emptyList();
    }

    Collection<DeclarationDescriptor> descriptors;
    if (importedReference instanceof JetQualifiedExpression) {
      // store result only when we find all descriptors, not only classes on the second phase
      descriptors =
          lookupDescriptorsForQualifiedExpression(
              (JetQualifiedExpression) importedReference,
              scope,
              scopeToCheckVisibility,
              trace,
              lookupMode,
              lookupMode == LookupMode.EVERYTHING);
    } else {
      assert importedReference instanceof JetSimpleNameExpression;
      descriptors =
          lookupDescriptorsForSimpleNameReference(
              (JetSimpleNameExpression) importedReference,
              scope,
              scopeToCheckVisibility,
              trace,
              lookupMode,
              true,
              lookupMode == LookupMode.EVERYTHING);
    }

    JetSimpleNameExpression referenceExpression = JetPsiUtil.getLastReference(importedReference);
    if (importDirective.isAllUnder()) {
      if (!canAllUnderImportFrom(descriptors) && referenceExpression != null) {
        ClassDescriptor toReportOn =
            KotlinPackage.filterIsInstance(descriptors, ClassDescriptor.class).iterator().next();
        trace.report(CANNOT_IMPORT_ON_DEMAND_FROM_SINGLETON.on(referenceExpression, toReportOn));
      }

      if (referenceExpression == null
          || !canImportMembersFrom(descriptors, referenceExpression, trace, lookupMode)) {
        return Collections.emptyList();
      }

      if (importer != null) {
        for (DeclarationDescriptor descriptor : descriptors) {
          importer.addAllUnderImport(descriptor);
        }
      }
      return Collections.emptyList();
    }

    Name aliasName = JetPsiUtil.getAliasName(importDirective);
    if (aliasName == null) {
      return Collections.emptyList();
    }

    if (importer != null) {
      for (DeclarationDescriptor descriptor : descriptors) {
        importer.addAliasImport(descriptor, aliasName);
      }
    }

    return descriptors;
  }
예제 #30
0
  private static void storeResolutionResult(
      @NotNull Collection<DeclarationDescriptor> descriptors,
      @NotNull Collection<DeclarationDescriptor> canBeImportedDescriptors,
      @NotNull JetSimpleNameExpression referenceExpression,
      @NotNull Collection<JetScope> possibleResolutionScopes,
      @NotNull BindingTrace trace,
      @NotNull JetScope scopeToCheckVisibility) {
    assert canBeImportedDescriptors.size() <= descriptors.size();
    assert !possibleResolutionScopes.isEmpty();
    // todo completion here needs all possible resolution scopes, if there are many
    JetScope resolutionScope = possibleResolutionScopes.iterator().next();

    // A special case - will fill all trace information
    if (resolveClassPackageAmbiguity(
        canBeImportedDescriptors,
        referenceExpression,
        resolutionScope,
        trace,
        scopeToCheckVisibility)) {
      return;
    }

    // Simple case of no descriptors
    if (descriptors.isEmpty()) {
      trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);
      trace.report(UNRESOLVED_REFERENCE.on(referenceExpression, referenceExpression));
      return;
    }

    // Decide if expression has resolved reference
    DeclarationDescriptor descriptor = null;
    if (descriptors.size() == 1) {
      descriptor = descriptors.iterator().next();
      assert canBeImportedDescriptors.size() <= 1;
    } else if (canBeImportedDescriptors.size() == 1) {
      descriptor = canBeImportedDescriptors.iterator().next();
    }
    if (descriptor != null) {
      trace.record(
          BindingContext.REFERENCE_TARGET, referenceExpression, descriptors.iterator().next());
      trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, resolutionScope);

      if (descriptor instanceof DeclarationDescriptorWithVisibility) {
        checkVisibility(
            (DeclarationDescriptorWithVisibility) descriptor,
            trace,
            referenceExpression,
            scopeToCheckVisibility);
      }
    }

    // Check for more information and additional errors
    if (canBeImportedDescriptors.isEmpty()) {
      assert descriptors.size() >= 1;
      trace.report(CANNOT_BE_IMPORTED.on(referenceExpression, descriptors.iterator().next()));
      return;
    }
    if (canBeImportedDescriptors.size() > 1) {
      trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, descriptors);
    }
  }