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())); } } } }
public void process(@NotNull BodiesResolveContext bodiesResolveContext) { for (JetFile file : bodiesResolveContext.getFiles()) { checkModifiersAndAnnotationsInPackageDirective(file); AnnotationTargetChecker.INSTANCE$.check(file, trace); } Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> classes = bodiesResolveContext.getDeclaredClasses(); for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : classes.entrySet()) { JetClassOrObject classOrObject = entry.getKey(); ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue(); checkSupertypesForConsistency(classDescriptor); checkTypesInClassHeader(classOrObject); if (classOrObject instanceof JetClass) { JetClass jetClass = (JetClass) classOrObject; checkClass(bodiesResolveContext, jetClass, classDescriptor); descriptorResolver.checkNamesInConstraints( jetClass, classDescriptor, classDescriptor.getScopeForClassHeaderResolution(), trace); } else if (classOrObject instanceof JetObjectDeclaration) { checkObject((JetObjectDeclaration) classOrObject, classDescriptor); } checkPrimaryConstructor(classOrObject, classDescriptor); modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor); } Map<JetNamedFunction, SimpleFunctionDescriptor> functions = bodiesResolveContext.getFunctions(); for (Map.Entry<JetNamedFunction, SimpleFunctionDescriptor> entry : functions.entrySet()) { JetNamedFunction function = entry.getKey(); SimpleFunctionDescriptor functionDescriptor = entry.getValue(); checkFunction(function, functionDescriptor); modifiersChecker.checkModifiersForDeclaration(function, functionDescriptor); } Map<JetProperty, PropertyDescriptor> properties = bodiesResolveContext.getProperties(); for (Map.Entry<JetProperty, PropertyDescriptor> entry : properties.entrySet()) { JetProperty property = entry.getKey(); PropertyDescriptor propertyDescriptor = entry.getValue(); checkProperty(property, propertyDescriptor); modifiersChecker.checkModifiersForDeclaration(property, propertyDescriptor); } for (Map.Entry<JetSecondaryConstructor, ConstructorDescriptor> entry : bodiesResolveContext.getSecondaryConstructors().entrySet()) { ConstructorDescriptor constructorDescriptor = entry.getValue(); JetSecondaryConstructor declaration = entry.getKey(); checkConstructorDeclaration(constructorDescriptor, declaration); } }
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)); } }
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) { reportErrorIfHasIllegalModifier(property); DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); if (containingDeclaration instanceof ClassDescriptor) { checkPropertyAbstractness( property, propertyDescriptor, (ClassDescriptor) containingDeclaration); } else { modifiersChecker.reportIllegalModalityModifiers(property); } checkPropertyInitializer(property, propertyDescriptor); checkAccessors(property, propertyDescriptor); checkDeclaredTypeInPublicMember(property, propertyDescriptor); }
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); }
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 void checkConstructorDeclaration( ConstructorDescriptor constructorDescriptor, JetDeclaration declaration) { modifiersChecker.reportIllegalModalityModifiers(declaration); reportErrorIfHasIllegalModifier(declaration); modifiersChecker.checkModifiersForDeclaration(declaration, constructorDescriptor); }
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()); } }); }