private void resolvePropertyDeclarationBodies(@NotNull BodiesResolveContext c) { // Member properties Set<JetProperty> processed = Sets.newHashSet(); for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) { if (!(entry.getKey() instanceof JetClass)) continue; JetClass jetClass = (JetClass) entry.getKey(); ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue(); for (JetProperty property : jetClass.getProperties()) { PropertyDescriptor propertyDescriptor = c.getProperties().get(property); assert propertyDescriptor != null; resolveProperty( c, classDescriptor.getScopeForMemberDeclarationResolution(), property, propertyDescriptor); processed.add(property); } } // Top-level properties & properties of objects for (Map.Entry<JetProperty, PropertyDescriptor> entry : c.getProperties().entrySet()) { JetProperty property = entry.getKey(); if (processed.contains(property)) continue; PropertyDescriptor propertyDescriptor = entry.getValue(); resolveProperty(c, null, property, propertyDescriptor); } }
@NotNull private MutableClassDescriptor createClassDescriptorForClass( @NotNull JetClass klass, @NotNull DeclarationDescriptor containingDeclaration) { ClassKind kind = getClassKind(klass); // Kind check is needed in order to not consider enums as inner in any case // (otherwise it would be impossible to create a class object in the enum) boolean isInner = kind == ClassKind.CLASS && klass.isInner(); MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( containingDeclaration, outerScope, kind, isInner, JetPsiUtil.safeName(klass.getName())); c.getClasses().put(klass, mutableClassDescriptor); trace.record( FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getUnsafeFQName(klass), mutableClassDescriptor); createClassObjectForEnumClass(mutableClassDescriptor); JetScope classScope = mutableClassDescriptor.getScopeForMemberDeclarationResolution(); prepareForDeferredCall(classScope, mutableClassDescriptor, klass); return mutableClassDescriptor; }
private void resolveUpperBoundsFromWhereClause(Set<JetType> upperBounds) { JetClassOrObject classOrObject = JetStubbedPsiUtil.getPsiOrStubParent(jetTypeParameter, JetClassOrObject.class, true); if (classOrObject instanceof JetClass) { JetClass jetClass = (JetClass) classOrObject; for (JetTypeConstraint jetTypeConstraint : jetClass.getTypeConstraints()) { DescriptorResolver.reportUnsupportedClassObjectConstraint( resolveSession.getTrace(), jetTypeConstraint); JetSimpleNameExpression constrainedParameterName = jetTypeConstraint.getSubjectTypeParameterName(); if (constrainedParameterName != null) { if (getName().equals(constrainedParameterName.getReferencedNameAsName())) { resolveSession .getTrace() .record(BindingContext.REFERENCE_TARGET, constrainedParameterName, this); JetTypeReference boundTypeReference = jetTypeConstraint.getBoundTypeReference(); if (boundTypeReference != null) { JetType boundType = resolveBoundType(boundTypeReference); if (!jetTypeConstraint.isClassObjectConstraint()) { upperBounds.add(boundType); } } } } } } }
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) { if (classDescriptor.getKind() == ClassKind.TRAIT) { JetParameterList primaryConstructorParameterList = klass.getPrimaryConstructorParameterList(); if (primaryConstructorParameterList != null) { context.getTrace().report(CONSTRUCTOR_IN_TRAIT.on(primaryConstructorParameterList)); } if (!klass.hasPrimaryConstructor()) return; } // TODO : not all the parameters are real properties JetScope memberScope = classDescriptor.getScopeForSupertypeResolution(); ConstructorDescriptor constructorDescriptor = context .getDescriptorResolver() .resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass); for (JetParameter parameter : klass.getPrimaryConstructorParameters()) { if (parameter.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = context .getDescriptorResolver() .resolvePrimaryConstructorParameterToAProperty( classDescriptor, memberScope, parameter); classDescriptor.addPropertyDescriptor(propertyDescriptor); context.getPrimaryConstructorParameterProperties().add(propertyDescriptor); } } if (constructorDescriptor != null) { classDescriptor.setPrimaryConstructor(constructorDescriptor, context.getTrace()); } }
@NotNull private static ClassKind getClassKind(@NotNull JetClass jetClass) { if (jetClass.isTrait()) return ClassKind.TRAIT; if (jetClass.isAnnotation()) return ClassKind.ANNOTATION_CLASS; if (jetClass.isEnum()) return ClassKind.ENUM_CLASS; return ClassKind.CLASS; }
private void resolveConstructorHeaders() { for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); processPrimaryConstructor(classDescriptor, jetClass); for (JetSecondaryConstructor jetConstructor : jetClass.getSecondaryConstructors()) { processSecondaryConstructor(classDescriptor, jetConstructor); } } }
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)); } }
private void resolvePropertyDeclarationBodies() { // Member properties Set<JetProperty> processed = Sets.newHashSet(); for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); if (!context.completeAnalysisNeeded(jetClass)) continue; MutableClassDescriptor classDescriptor = entry.getValue(); for (JetProperty property : jetClass.getProperties()) { final PropertyDescriptor propertyDescriptor = this.context.getProperties().get(property); assert propertyDescriptor != null; computeDeferredType(propertyDescriptor.getReturnType()); JetExpression initializer = property.getInitializer(); if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (primaryConstructor != null) { JetScope declaringScopeForPropertyInitializer = this.context.getDeclaringScopes().get(property); resolvePropertyInitializer( property, propertyDescriptor, initializer, declaringScopeForPropertyInitializer); } } resolvePropertyAccessors(property, propertyDescriptor); processed.add(property); } } // Top-level properties & properties of objects for (Map.Entry<JetProperty, PropertyDescriptor> entry : this.context.getProperties().entrySet()) { JetProperty property = entry.getKey(); if (!context.completeAnalysisNeeded(property)) continue; if (processed.contains(property)) continue; final PropertyDescriptor propertyDescriptor = entry.getValue(); computeDeferredType(propertyDescriptor.getReturnType()); JetScope declaringScope = this.context.getDeclaringScopes().get(property); JetExpression initializer = property.getInitializer(); if (initializer != null) { resolvePropertyInitializer(property, propertyDescriptor, initializer, declaringScope); } resolvePropertyAccessors(property, propertyDescriptor); } }
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)); } } }
@Override public Icon getIcon(@NotNull PsiElement psiElement, int flags) { if (psiElement instanceof JetFile) { JetFile file = (JetFile) psiElement; JetClassOrObject mainClass = getMainClass(file); return mainClass != null ? getIcon(mainClass, flags) : JetIcons.FILE; } if (psiElement instanceof JetNamespaceHeader) { return (flags & Iconable.ICON_FLAG_OPEN) != 0 ? PlatformIcons.PACKAGE_OPEN_ICON : PlatformIcons.PACKAGE_ICON; } if (psiElement instanceof JetNamedFunction) { return PsiTreeUtil.getParentOfType(psiElement, JetNamedDeclaration.class) instanceof JetClass ? PlatformIcons.METHOD_ICON : JetIcons.FUNCTION; } if (psiElement instanceof JetClass) { JetClass jetClass = (JetClass) psiElement; if (jetClass.isTrait()) { return JetIcons.TRAIT; } Icon icon = jetClass.hasModifier(JetTokens.ENUM_KEYWORD) ? PlatformIcons.ENUM_ICON : JetIcons.CLASS; if (jetClass instanceof JetEnumEntry) { JetEnumEntry enumEntry = (JetEnumEntry) jetClass; if (enumEntry.getPrimaryConstructorParameterList() == null) { icon = PlatformIcons.ENUM_ICON; } } return icon; } if (psiElement instanceof JetObjectDeclaration || psiElement instanceof JetClassObject) { return JetIcons.OBJECT; } if (psiElement instanceof JetParameter) { JetParameter parameter = (JetParameter) psiElement; if (parameter.getValOrVarNode() != null) { JetParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, JetParameterList.class); if (parameterList != null && parameterList.getParent() instanceof JetClass) { return parameter.isMutable() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } } return JetIcons.PARAMETER; } if (psiElement instanceof JetProperty) { JetProperty property = (JetProperty) psiElement; return property.isVar() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } return null; }
private void resolvePrimaryConstructorParameters() { for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass klass = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); ConstructorDescriptor unsubstitutedPrimaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (unsubstitutedPrimaryConstructor != null) { checkDefaultParameterValues( klass.getPrimaryConstructorParameters(), unsubstitutedPrimaryConstructor.getValueParameters(), classDescriptor.getScopeForInitializers()); } } }
private void checkValOnAnnotationParameter(JetClass aClass) { for (JetParameter parameter : aClass.getPrimaryConstructorParameters()) { if (!parameter.hasValOrVar()) { trace.report(MISSING_VAL_ON_ANNOTATION_PARAMETER.on(parameter)); } } }
private void processPrimaryConstructor( @NotNull TopDownAnalysisContext c, @NotNull MutableClassDescriptor classDescriptor, @NotNull JetClass klass) { // TODO : not all the parameters are real properties JetScope memberScope = classDescriptor.getScopeForClassHeaderResolution(); ConstructorDescriptor constructorDescriptor = descriptorResolver.resolvePrimaryConstructorDescriptor( memberScope, classDescriptor, klass, trace); if (constructorDescriptor != null) { List<ValueParameterDescriptor> valueParameterDescriptors = constructorDescriptor.getValueParameters(); List<JetParameter> primaryConstructorParameters = klass.getPrimaryConstructorParameters(); assert valueParameterDescriptors.size() == primaryConstructorParameters.size(); List<ValueParameterDescriptor> notProperties = new ArrayList<ValueParameterDescriptor>(); for (ValueParameterDescriptor valueParameterDescriptor : valueParameterDescriptors) { JetParameter parameter = primaryConstructorParameters.get(valueParameterDescriptor.getIndex()); if (parameter.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = descriptorResolver.resolvePrimaryConstructorParameterToAProperty( classDescriptor, valueParameterDescriptor, memberScope, parameter, trace); classDescriptor.getBuilder().addPropertyDescriptor(propertyDescriptor); c.getPrimaryConstructorParameterProperties().put(parameter, propertyDescriptor); } else { notProperties.add(valueParameterDescriptor); } } if (classDescriptor.getKind() != ClassKind.TRAIT) { classDescriptor.setPrimaryConstructor(constructorDescriptor); classDescriptor.addConstructorParametersToInitializersScope(notProperties); } } }
@Override public void invoke(@NotNull Project project, Editor editor, @NotNull JetFile file) throws IncorrectOperationException { JetPsiFactory factory = new JetPsiFactory(annotationClass.getProject()); JetModifierList list = annotationClass.getModifierList(); String annotation = KotlinBuiltIns.FQ_NAMES.annotation.shortName().asString(); PsiElement added; if (list == null) { JetModifierList newModifierList = factory.createModifierList(annotation); added = annotationClass.addBefore(newModifierList, annotationClass.getClassOrInterfaceKeyword()); } else { JetAnnotationEntry entry = factory.createAnnotationEntry(annotation); added = list.addBefore(entry, list.getFirstChild()); } annotationClass.addAfter(factory.createWhiteSpace(), added); }
private void checkTypesInClassHeader(@NotNull JetClassOrObject classOrObject) { for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) { checkBoundsForTypeInClassHeader(delegationSpecifier.getTypeReference()); } if (!(classOrObject instanceof JetClass)) return; JetClass jetClass = (JetClass) classOrObject; for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) { checkBoundsForTypeInClassHeader(jetTypeParameter.getExtendsBound()); checkFinalUpperBounds(jetTypeParameter.getExtendsBound()); } for (JetTypeConstraint constraint : jetClass.getTypeConstraints()) { checkBoundsForTypeInClassHeader(constraint.getBoundTypeReference()); checkFinalUpperBounds(constraint.getBoundTypeReference()); } }
private void resolveFunctionAndPropertyHeaders() { for (Map.Entry<JetFile, WritableScope> entry : context.getNamespaceScopes().entrySet()) { JetFile namespace = entry.getKey(); WritableScope namespaceScope = entry.getValue(); NamespaceLike namespaceDescriptor = context.getNamespaceDescriptors().get(namespace); resolveFunctionAndPropertyHeaders( namespace.getDeclarations(), namespaceScope, namespaceScope, namespaceScope, namespaceDescriptor); } for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); resolveFunctionAndPropertyHeaders( jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(), classDescriptor); // processPrimaryConstructor(classDescriptor, jetClass); // for (JetSecondaryConstructor jetConstructor : // jetClass.getSecondaryConstructors()) { // processSecondaryConstructor(classDescriptor, jetConstructor); // } } for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) { JetObjectDeclaration object = entry.getKey(); MutableClassDescriptor classDescriptor = entry.getValue(); resolveFunctionAndPropertyHeaders( object.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor.getScopeForInitializers(), classDescriptor.getScopeForMemberResolution(), classDescriptor); } // TODO : Extensions }
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); } }
public void resolveConstructorParameterDefaultValuesAndAnnotations( @NotNull DataFlowInfo outerDataFlowInfo, @NotNull BindingTrace trace, @NotNull JetClass klass, @NotNull ConstructorDescriptor constructorDescriptor, @NotNull LexicalScope declaringScope) { List<JetParameter> valueParameters = klass.getPrimaryConstructorParameters(); List<ValueParameterDescriptor> valueParameterDescriptors = constructorDescriptor.getValueParameters(); LexicalScope scope = getPrimaryConstructorParametersScope(declaringScope, constructorDescriptor); valueParameterResolver.resolveValueParameters( valueParameters, valueParameterDescriptors, scope, outerDataFlowInfo, trace); }
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 static Icon getBaseIcon(PsiElement psiElement) { if (psiElement instanceof JetNamespaceHeader) { return PlatformIcons.PACKAGE_ICON; } if (psiElement instanceof KotlinLightClassForPackage) { return JetIcons.FILE; } if (psiElement instanceof KotlinLightClassForExplicitDeclaration) { psiElement = psiElement.getNavigationElement(); } if (psiElement instanceof JetNamedFunction) { if (((JetFunction) psiElement).getReceiverTypeRef() != null) { return JetIcons.EXTENSION_FUNCTION; } if (PsiTreeUtil.getParentOfType(psiElement, JetNamedDeclaration.class) instanceof JetClass) { if (JetPsiUtil.isAbstract((JetFunction) psiElement)) { return PlatformIcons.ABSTRACT_METHOD_ICON; } else { return PlatformIcons.METHOD_ICON; } } else { return JetIcons.FUNCTION; } } if (psiElement instanceof JetClass) { JetClass jetClass = (JetClass) psiElement; if (jetClass.isTrait()) { return JetIcons.TRAIT; } Icon icon = jetClass.isEnum() ? PlatformIcons.ENUM_ICON : JetIcons.CLASS; if (jetClass instanceof JetEnumEntry) { JetEnumEntry enumEntry = (JetEnumEntry) jetClass; if (enumEntry.getPrimaryConstructorParameterList() == null) { icon = PlatformIcons.ENUM_ICON; } } return icon; } if (psiElement instanceof JetObjectDeclaration || psiElement instanceof JetClassObject) { return JetIcons.OBJECT; } if (psiElement instanceof JetParameter) { JetParameter parameter = (JetParameter) psiElement; if (parameter.getValOrVarNode() != null) { JetParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, JetParameterList.class); if (parameterList != null && parameterList.getParent() instanceof JetClass) { return parameter.isMutable() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } } return JetIcons.PARAMETER; } if (psiElement instanceof JetProperty) { JetProperty property = (JetProperty) psiElement; return property.isVar() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } return null; }
private void checkConstructorInTrait(JetClass klass) { JetPrimaryConstructor primaryConstructor = klass.getPrimaryConstructor(); if (primaryConstructor != null) { trace.report(CONSTRUCTOR_IN_TRAIT.on(primaryConstructor)); } }
@NotNull @Override public String getText() { return JetBundle.message("make.class.annotation.class", annotationClass.getName()); }