KT-14274: resolve type alias constructors calls in supertypes list as type alias constructors.
Support @Deprecated for type aliases, including type alias constructors.
This commit is contained in:
@@ -222,7 +222,7 @@ public interface BindingContext {
|
||||
*/
|
||||
WritableSlice<PsiElement, SimpleFunctionDescriptor> FUNCTION = Slices.createSimpleSlice();
|
||||
WritableSlice<PsiElement, ConstructorDescriptor> CONSTRUCTOR = Slices.createSimpleSlice();
|
||||
WritableSlice<ConstructorDescriptor, ResolvedCall<ClassConstructorDescriptor>> CONSTRUCTOR_RESOLVED_DELEGATION_CALL =
|
||||
WritableSlice<ConstructorDescriptor, ResolvedCall<ConstructorDescriptor>> CONSTRUCTOR_RESOLVED_DELEGATION_CALL =
|
||||
Slices.createSimpleSlice();
|
||||
WritableSlice<PsiElement, VariableDescriptor> VARIABLE = Slices.createSimpleSlice();
|
||||
WritableSlice<KtParameter, VariableDescriptor> VALUE_PARAMETER = Slices.createSimpleSlice();
|
||||
|
||||
@@ -222,7 +222,7 @@ public class BindingContextUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResolvedCall<ClassConstructorDescriptor> getDelegationConstructorCall(
|
||||
public static ResolvedCall<ConstructorDescriptor> getDelegationConstructorCall(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull ConstructorDescriptor constructorDescriptor
|
||||
) {
|
||||
|
||||
@@ -231,7 +231,7 @@ public class BodyResolver {
|
||||
|
||||
@Nullable
|
||||
private ConstructorDescriptor getDelegatedConstructor(@NotNull ConstructorDescriptor constructor) {
|
||||
ResolvedCall<ClassConstructorDescriptor> call = trace.get(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor);
|
||||
ResolvedCall<ConstructorDescriptor> call = trace.get(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor);
|
||||
return call == null || !call.getStatus().isSuccess() ? null : call.getResultingDescriptor().getOriginal();
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ public class BodyResolver {
|
||||
@NotNull ResolvedCall<?> call
|
||||
) {
|
||||
//noinspection unchecked
|
||||
trace.record(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor, (ResolvedCall<ClassConstructorDescriptor>) call);
|
||||
trace.record(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor, (ResolvedCall<ConstructorDescriptor>) call);
|
||||
}
|
||||
|
||||
private void checkSupertypeList(
|
||||
|
||||
@@ -307,7 +307,7 @@ public class CallResolver {
|
||||
return resolveCallForInvoke(context.replaceCall(call), tracingForInvoke);
|
||||
}
|
||||
|
||||
private OverloadResolutionResults<ClassConstructorDescriptor> resolveCallForConstructor(
|
||||
private OverloadResolutionResults<ConstructorDescriptor> resolveCallForConstructor(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull KtConstructorCalleeExpression expression
|
||||
) {
|
||||
@@ -340,17 +340,17 @@ public class CallResolver {
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
|
||||
Pair<Collection<ResolutionCandidate<ClassConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
|
||||
Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
|
||||
prepareCandidatesAndContextForConstructorCall(constructedType, context);
|
||||
|
||||
Collection<ResolutionCandidate<ClassConstructorDescriptor>> candidates = candidatesAndContext.getFirst();
|
||||
Collection<ResolutionCandidate<ConstructorDescriptor>> candidates = candidatesAndContext.getFirst();
|
||||
context = candidatesAndContext.getSecond();
|
||||
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OverloadResolutionResults<ClassConstructorDescriptor> resolveConstructorDelegationCall(
|
||||
public OverloadResolutionResults<ConstructorDescriptor> resolveConstructorDelegationCall(
|
||||
@NotNull BindingTrace trace, @NotNull LexicalScope scope, @NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull ClassConstructorDescriptor constructorDescriptor,
|
||||
@NotNull KtConstructorDelegationCall call
|
||||
@@ -380,7 +380,7 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private OverloadResolutionResults<ClassConstructorDescriptor> resolveConstructorDelegationCall(
|
||||
private OverloadResolutionResults<ConstructorDescriptor> resolveConstructorDelegationCall(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull KtConstructorDelegationCall call,
|
||||
@NotNull KtConstructorDelegationReferenceExpression calleeExpression,
|
||||
@@ -420,9 +420,9 @@ public class CallResolver {
|
||||
calleeConstructor.getContainingDeclaration().getDefaultType() :
|
||||
DescriptorUtils.getSuperClassType(currentClassDescriptor);
|
||||
|
||||
Pair<Collection<ResolutionCandidate<ClassConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
|
||||
Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
|
||||
prepareCandidatesAndContextForConstructorCall(superType, context);
|
||||
Collection<ResolutionCandidate<ClassConstructorDescriptor>> candidates = candidatesAndContext.getFirst();
|
||||
Collection<ResolutionCandidate<ConstructorDescriptor>> candidates = candidatesAndContext.getFirst();
|
||||
context = candidatesAndContext.getSecond();
|
||||
|
||||
TracingStrategy tracing = call.isImplicit() ?
|
||||
@@ -441,17 +441,15 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Pair<Collection<ResolutionCandidate<ClassConstructorDescriptor>>, BasicCallResolutionContext> prepareCandidatesAndContextForConstructorCall(
|
||||
private static Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> prepareCandidatesAndContextForConstructorCall(
|
||||
@NotNull KotlinType superType,
|
||||
@NotNull BasicCallResolutionContext context
|
||||
) {
|
||||
if (!(superType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
|
||||
return new Pair<Collection<ResolutionCandidate<ClassConstructorDescriptor>>, BasicCallResolutionContext>(
|
||||
Collections.<ResolutionCandidate<ClassConstructorDescriptor>>emptyList(), context);
|
||||
return new Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext>(
|
||||
Collections.<ResolutionCandidate<ConstructorDescriptor>>emptyList(), context);
|
||||
}
|
||||
|
||||
ClassDescriptor superClass = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
// If any constructor has type parameter (currently it only can be true for ones from Java), try to infer arguments for them
|
||||
// Otherwise use NO_EXPECTED_TYPE and knownTypeParametersSubstitutor
|
||||
boolean anyConstructorHasDeclaredTypeParameters =
|
||||
@@ -462,10 +460,10 @@ public class CallResolver {
|
||||
context = context.replaceExpectedType(superType);
|
||||
}
|
||||
|
||||
Collection<ResolutionCandidate<ClassConstructorDescriptor>> candidates =
|
||||
CallResolverUtilKt.createResolutionCandidatesForConstructors(context.scope, context.call, superClass, knownTypeParametersSubstitutor);
|
||||
Collection<ResolutionCandidate<ConstructorDescriptor>> candidates =
|
||||
CallResolverUtilKt.createResolutionCandidatesForConstructors(context.scope, context.call, superType, knownTypeParametersSubstitutor);
|
||||
|
||||
return new Pair<Collection<ResolutionCandidate<ClassConstructorDescriptor>>, BasicCallResolutionContext>(candidates, context);
|
||||
return new Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext>(candidates, context);
|
||||
}
|
||||
|
||||
private static boolean anyConstructorHasDeclaredTypeParameters(@Nullable ClassifierDescriptor classDescriptor) {
|
||||
|
||||
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.coroutines.getExpectedTypeForCoroutineControllerHandleResult
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -200,9 +202,18 @@ fun getEffectiveExpectedType(parameterDescriptor: ValueParameterDescriptor, argu
|
||||
fun createResolutionCandidatesForConstructors(
|
||||
lexicalScope: LexicalScope,
|
||||
call: Call,
|
||||
classWithConstructors: ClassDescriptor,
|
||||
typeWithConstructors: KotlinType,
|
||||
knownSubstitutor: TypeSubstitutor? = null
|
||||
): Collection<ResolutionCandidate<ClassConstructorDescriptor>> {
|
||||
): Collection<ResolutionCandidate<ConstructorDescriptor>> {
|
||||
val classWithConstructors = typeWithConstructors.constructor.declarationDescriptor as ClassDescriptor
|
||||
|
||||
val unwrappedType = typeWithConstructors.unwrap()
|
||||
val typeAliasDescriptor =
|
||||
if (unwrappedType is AbbreviatedType)
|
||||
unwrappedType.abbreviation.constructor.declarationDescriptor as? TypeAliasDescriptor
|
||||
else
|
||||
null
|
||||
|
||||
val constructors = classWithConstructors.constructors
|
||||
|
||||
if (constructors.isEmpty()) return emptyList()
|
||||
@@ -212,7 +223,7 @@ fun createResolutionCandidatesForConstructors(
|
||||
|
||||
if (classWithConstructors.isInner) {
|
||||
val outerClassType = (classWithConstructors.containingDeclaration as? ClassDescriptor)?.defaultType ?: return emptyList()
|
||||
val substitutedOuterClassType = knownSubstitutor?.let { it.substitute(outerClassType, Variance.INVARIANT) } ?: outerClassType
|
||||
val substitutedOuterClassType = knownSubstitutor?.substitute(outerClassType, Variance.INVARIANT) ?: outerClassType
|
||||
|
||||
val receiver = lexicalScope.getImplicitReceiversHierarchy().firstOrNull {
|
||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(it.type, substitutedOuterClassType)
|
||||
@@ -226,9 +237,22 @@ fun createResolutionCandidatesForConstructors(
|
||||
dispatchReceiver = null
|
||||
}
|
||||
|
||||
return constructors.map { ResolutionCandidate.create(call, it, dispatchReceiver, receiverKind, knownSubstitutor) }
|
||||
return constructors.map {
|
||||
val constructorDescriptor = it.getConstructorDescriptorForResolution(knownSubstitutor, typeAliasDescriptor)
|
||||
ResolutionCandidate.create(call, constructorDescriptor, dispatchReceiver, receiverKind, knownSubstitutor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassConstructorDescriptor.getConstructorDescriptorForResolution(
|
||||
knownSubstitutor: TypeSubstitutor?,
|
||||
typeAliasDescriptor: TypeAliasDescriptor?
|
||||
): ConstructorDescriptor =
|
||||
if (typeAliasDescriptor != null)
|
||||
TypeAliasConstructorDescriptorImpl.create(typeAliasDescriptor, this, knownSubstitutor ?: TypeSubstitutor.EMPTY)
|
||||
?: throw AssertionError("Failed to create type alias constructor with substitutor: $knownSubstitutor")
|
||||
else
|
||||
this
|
||||
|
||||
fun KtLambdaExpression.getCorrespondingParameterForFunctionArgument(
|
||||
bindingContext: BindingContext
|
||||
): ValueParameterDescriptor? {
|
||||
|
||||
+9
-2
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
|
||||
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
|
||||
@@ -32,7 +33,13 @@ object ProtectedConstructorCallChecker : CallChecker {
|
||||
val constructorOwner = descriptor.containingDeclaration.original
|
||||
val scopeOwner = context.scope.ownerDescriptor
|
||||
|
||||
if (descriptor.visibility.normalize() != Visibilities.PROTECTED) return
|
||||
val actualConstructor =
|
||||
if (descriptor is TypeAliasConstructorDescriptor)
|
||||
descriptor.underlyingConstructorDescriptor
|
||||
else
|
||||
descriptor
|
||||
|
||||
if (actualConstructor.visibility.normalize() != Visibilities.PROTECTED) return
|
||||
// Error already reported
|
||||
if (!Visibilities.isVisibleWithAnyReceiver(descriptor, scopeOwner)) return
|
||||
|
||||
@@ -52,7 +59,7 @@ object ProtectedConstructorCallChecker : CallChecker {
|
||||
// And without ProtectedConstructorCallChecker such calls would be allowed only because they are performed within subclass
|
||||
// of constructor owner
|
||||
@Suppress("DEPRECATION")
|
||||
if (Visibilities.findInvisibleMember(Visibilities.FALSE_IF_PROTECTED, descriptor, scopeOwner) == descriptor) {
|
||||
if (Visibilities.findInvisibleMember(Visibilities.FALSE_IF_PROTECTED, descriptor, scopeOwner) == actualConstructor) {
|
||||
context.trace.report(Errors.PROTECTED_CONSTRUCTOR_NOT_IN_SUPER_CALL.on(reportOn, descriptor))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -137,6 +138,11 @@ private fun DeclarationDescriptor.getDeprecationByAnnotation(): DeprecatedByAnno
|
||||
val classAnnotation = classDescriptor.getDeclaredDeprecatedAnnotation()
|
||||
if (classAnnotation != null)
|
||||
return DeprecatedByAnnotation(classAnnotation, classDescriptor)
|
||||
if (this is TypeAliasConstructorDescriptor) {
|
||||
val underlyingConstructorDeprecation = underlyingConstructorDescriptor.getDeprecationByAnnotation()
|
||||
if (underlyingConstructorDeprecation != null)
|
||||
return underlyingConstructorDeprecation
|
||||
}
|
||||
}
|
||||
is PropertyAccessorDescriptor -> {
|
||||
val propertyDescriptor = correspondingProperty
|
||||
|
||||
Reference in New Issue
Block a user