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())); } } } }
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); } }
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)); } }
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)); } }
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); }
private void checkValOnAnnotationParameter(JetClass aClass) { for (JetParameter parameter : aClass.getPrimaryConstructorParameters()) { if (!parameter.hasValOrVar()) { trace.report(MISSING_VAL_ON_ANNOTATION_PARAMETER.on(parameter)); } } }
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); } } }
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)); } }
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)); } }
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()))); } }
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)); } } } } }
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)); } } }
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)); } } }
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)); } }
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)); }
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())); } }
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); }
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())); } }
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)); } } } }
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)); } }
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())); } } } } } }
@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); }
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); }
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())); } } } }
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())); } }
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)); } } }
@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; }
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); } }