private void resolveAnnotationConstructors(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) { JetClassOrObject classOrObject = entry.getKey(); MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue(); if (classOrObject instanceof JetClass && DescriptorUtils.isAnnotationClass(classDescriptor)) { processPrimaryConstructor(c, classDescriptor, (JetClass) classOrObject); } } }
@NotNull private static InnerModifierCheckResult checkIllegalInner( @NotNull DeclarationDescriptor descriptor) { if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION; ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION; DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration(); if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION; if (DescriptorUtils.isTrait(containingDeclaration)) { return InnerModifierCheckResult.IN_TRAIT; } else if (DescriptorUtils.isObject(containingDeclaration)) { return InnerModifierCheckResult.IN_OBJECT; } else { return InnerModifierCheckResult.ALLOWED; } }
private void createFunctionsForDataClasses(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) { JetClassOrObject klass = entry.getKey(); MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue(); if (klass instanceof JetClass && klass.hasPrimaryConstructor() && KotlinBuiltIns.getInstance().isData(classDescriptor)) { ConstructorDescriptor constructor = DescriptorUtils.getConstructorOfDataClass(classDescriptor); createComponentFunctions(classDescriptor, constructor); createCopyFunction(classDescriptor, constructor); } } }
/** @return whether f overrides g */ public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) { // In a multi-module project different "copies" of the same class may be present in different // libraries, // that's why we use structural equivalence for members (DescriptorEquivalenceForOverrides). // This first check cover the case of duplicate classes in different modules: // when B is defined in modules m1 and m2, and C (indirectly) inherits from both versions, // we'll be getting sets of members that do not override each other, but are structurally // equivalent. // As other code relies on no equal descriptors passed here, we guard against f == g, but this // may not be necessary // Note that this is needed for the usage of this function in the IDE code if (!f.equals(g) && DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent( f.getOriginal(), g.getOriginal())) return true; CallableDescriptor originalG = g.getOriginal(); for (D overriddenFunction : DescriptorUtils.getAllOverriddenDescriptors(f)) { if (DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(originalG, overriddenFunction)) return true; } return false; }
private void checkSupertypeList( @NotNull ClassDescriptor supertypeOwner, @NotNull Map<JetTypeReference, JetType> supertypes, @NotNull JetClassOrObject jetClass) { Set<TypeConstructor> allowedFinalSupertypes = getAllowedFinalSupertypes(supertypeOwner, jetClass); Set<TypeConstructor> typeConstructors = Sets.newHashSet(); boolean classAppeared = false; for (Map.Entry<JetTypeReference, JetType> entry : supertypes.entrySet()) { JetTypeReference typeReference = entry.getKey(); JetType supertype = entry.getValue(); boolean addSupertype = true; ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { if (ErrorUtils.isError(classDescriptor)) continue; if (classDescriptor.getKind() != ClassKind.INTERFACE) { if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) { trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference)); addSupertype = false; } else if (supertypeOwner.getKind() == ClassKind.INTERFACE && !classAppeared && !TypesPackage.isDynamic(supertype) /* avoid duplicate diagnostics */) { trace.report(TRAIT_WITH_SUPERCLASS.on(typeReference)); addSupertype = false; } if (classAppeared) { trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference)); } else { classAppeared = true; } } } else { trace.report(SUPERTYPE_NOT_A_CLASS_OR_TRAIT.on(typeReference)); } TypeConstructor constructor = supertype.getConstructor(); if (addSupertype && !typeConstructors.add(constructor)) { trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference)); } if (DescriptorUtils.isSingleton(classDescriptor)) { trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference)); } else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) { if (classDescriptor.getModality() == Modality.SEALED) { DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration(); while (containingDescriptor != null && containingDescriptor != classDescriptor) { containingDescriptor = containingDescriptor.getContainingDeclaration(); } if (containingDescriptor == null) { trace.report(SEALED_SUPERTYPE.on(typeReference)); } else { trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference)); } } else { trace.report(FINAL_SUPERTYPE.on(typeReference)); } } } }
public void resolveDelegationSpecifierList( @NotNull final DataFlowInfo outerDataFlowInfo, @NotNull JetClassOrObject jetClass, @NotNull final ClassDescriptor descriptor, @Nullable final ConstructorDescriptor primaryConstructor, @NotNull LexicalScope scopeForSupertypeResolution, @NotNull final LexicalScope scopeForMemberResolution) { final LexicalScope scopeForConstructor = primaryConstructor == null ? null : FunctionDescriptorUtil.getFunctionInnerScope( scopeForSupertypeResolution, primaryConstructor, trace); final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap(); final ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1]; JetVisitorVoid visitor = new JetVisitorVoid() { private void recordSupertype(JetTypeReference typeReference, JetType supertype) { if (supertype == null) return; supertypes.put(typeReference, supertype); } @Override public void visitDelegationByExpressionSpecifier( @NotNull JetDelegatorByExpressionSpecifier specifier) { if (descriptor.getKind() == ClassKind.INTERFACE) { trace.report(DELEGATION_IN_TRAIT.on(specifier)); } JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); recordSupertype(specifier.getTypeReference(), supertype); if (supertype != null) { DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; if (classDescriptor.getKind() != ClassKind.INTERFACE) { trace.report(DELEGATION_NOT_TO_TRAIT.on(specifier.getTypeReference())); } } } JetExpression delegateExpression = specifier.getDelegateExpression(); if (delegateExpression != null) { LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor; JetType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE; typeInferrer.getType( scope, delegateExpression, expectedType, outerDataFlowInfo, trace); } if (primaryConstructor == null) { trace.report( UNSUPPORTED.on( specifier, "Delegation without primary constructor is not supported")); } } @Override public void visitDelegationToSuperCallSpecifier(@NotNull JetDelegatorToSuperCall call) { JetValueArgumentList valueArgumentList = call.getValueArgumentList(); PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList; if (descriptor.getKind() == ClassKind.INTERFACE) { trace.report(SUPERTYPE_INITIALIZED_IN_TRAIT.on(elementToMark)); } JetTypeReference typeReference = call.getTypeReference(); if (typeReference == null) return; if (primaryConstructor == null) { if (descriptor.getKind() != ClassKind.INTERFACE) { trace.report(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR.on(call)); } recordSupertype( typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference)); return; } OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall( trace, scopeForConstructor, CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, outerDataFlowInfo, false); if (results.isSuccess()) { JetType supertype = results.getResultingDescriptor().getReturnType(); recordSupertype(typeReference, supertype); ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { // allow only one delegating constructor if (primaryConstructorDelegationCall[0] == null) { primaryConstructorDelegationCall[0] = results.getResultingCall(); } else { primaryConstructorDelegationCall[0] = null; } } // Recording type info for callee to use later in JetObjectLiteralExpression trace.record(PROCESSED, call.getCalleeExpression(), true); trace.record( EXPRESSION_TYPE_INFO, call.getCalleeExpression(), TypeInfoFactoryPackage.noTypeInfo( results.getResultingCall().getDataFlowInfoForArguments().getResultInfo())); } else { recordSupertype( typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference)); } } @Override public void visitDelegationToSuperClassSpecifier( @NotNull JetDelegatorToSuperClass specifier) { JetTypeReference typeReference = specifier.getTypeReference(); JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference); recordSupertype(typeReference, supertype); if (supertype == null) return; ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype); if (superClass == null) return; if (superClass.getKind().isSingleton()) { // A "singleton in supertype" diagnostic will be reported later return; } if (descriptor.getKind() != ClassKind.INTERFACE && descriptor.getUnsubstitutedPrimaryConstructor() != null && superClass.getKind() != ClassKind.INTERFACE && !superClass.getConstructors().isEmpty() && !ErrorUtils.isError(superClass)) { trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier)); } } @Override public void visitJetElement(@NotNull JetElement element) { throw new UnsupportedOperationException(element.getText() + " : " + element); } }; for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) { delegationSpecifier.accept(visitor); } if (DescriptorUtils.isAnnotationClass(descriptor) && jetClass.getDelegationSpecifierList() != null) { trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(jetClass.getDelegationSpecifierList())); } if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) { recordConstructorDelegationCall( trace, primaryConstructor, primaryConstructorDelegationCall[0]); } checkSupertypeList(descriptor, supertypes, jetClass); }