[NI] Report diagnostic on abstract class instantiation.
This commit is contained in:
committed by
Stanislav Erokhin
parent
b012681a53
commit
5afd3e72d6
@@ -157,6 +157,9 @@ fun isInfixCall(call: Call): Boolean {
|
|||||||
return binaryExpression.operationReference === operationRefExpression && operationRefExpression.operationSignTokenType == null
|
return binaryExpression.operationReference === operationRefExpression && operationRefExpression.operationSignTokenType == null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isSupertypeConstructorCall(call: Call): Boolean =
|
||||||
|
call.calleeExpression is KtConstructorCalleeExpression
|
||||||
|
|
||||||
fun isInvokeCallOnVariable(call: Call): Boolean {
|
fun isInvokeCallOnVariable(call: Call): Boolean {
|
||||||
if (call.callType !== Call.CallType.INVOKE) return false
|
if (call.callType !== Call.CallType.INVOKE) return false
|
||||||
val dispatchReceiver = call.dispatchReceiver
|
val dispatchReceiver = call.dispatchReceiver
|
||||||
|
|||||||
+1
@@ -50,6 +50,7 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
when (diagnostic.javaClass) {
|
when (diagnostic.javaClass) {
|
||||||
VisibilityError::class.java -> tracingStrategy.invisibleMember(trace, (diagnostic as VisibilityError).invisibleMember)
|
VisibilityError::class.java -> tracingStrategy.invisibleMember(trace, (diagnostic as VisibilityError).invisibleMember)
|
||||||
NoValueForParameter::class.java -> tracingStrategy.noValueForParameter(trace, (diagnostic as NoValueForParameter).parameterDescriptor)
|
NoValueForParameter::class.java -> tracingStrategy.noValueForParameter(trace, (diagnostic as NoValueForParameter).parameterDescriptor)
|
||||||
|
InstantiationOfAbstractClass::class.java -> tracingStrategy.instantiationOfAbstractClass(trace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.model.KotlinCallKind
|
|||||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSupertypeConstructorCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
@@ -59,6 +60,7 @@ class PSIKotlinCallImpl(
|
|||||||
) : PSIKotlinCall() {
|
) : PSIKotlinCall() {
|
||||||
override val isInfixCall: Boolean get() = isInfixCall(psiCall)
|
override val isInfixCall: Boolean get() = isInfixCall(psiCall)
|
||||||
override val isOperatorCall: Boolean get() = isConventionCall(psiCall)
|
override val isOperatorCall: Boolean get() = isConventionCall(psiCall)
|
||||||
|
override val isSupertypeConstructorCall: Boolean get() = isSupertypeConstructorCall(psiCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PSIKotlinCallForVariable(
|
class PSIKotlinCallForVariable(
|
||||||
@@ -81,6 +83,7 @@ class PSIKotlinCallForVariable(
|
|||||||
|
|
||||||
override val isInfixCall: Boolean get() = false
|
override val isInfixCall: Boolean get() = false
|
||||||
override val isOperatorCall: Boolean get() = false
|
override val isOperatorCall: Boolean get() = false
|
||||||
|
override val isSupertypeConstructorCall: Boolean get() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
class PSIKotlinCallForInvoke(
|
class PSIKotlinCallForInvoke(
|
||||||
@@ -101,6 +104,7 @@ class PSIKotlinCallForInvoke(
|
|||||||
|
|
||||||
override val isInfixCall: Boolean get() = false
|
override val isInfixCall: Boolean get() = false
|
||||||
override val isOperatorCall: Boolean get() = true
|
override val isOperatorCall: Boolean get() = true
|
||||||
|
override val isSupertypeConstructorCall: Boolean get() = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val variableReceiver = dispatchReceiverForInvokeExtension ?: explicitReceiver
|
val variableReceiver = dispatchReceiverForInvokeExtension ?: explicitReceiver
|
||||||
|
|||||||
+17
-4
@@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ExplicitTypeParameterConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ExplicitTypeParameterConstraintPosition
|
||||||
@@ -29,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCa
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE
|
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.RUNTIME_ERROR
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
||||||
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
@@ -36,6 +34,17 @@ import org.jetbrains.kotlin.types.UnwrappedType
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||||
|
|
||||||
|
internal object CheckInstantiationOfAbstractClass : ResolutionPart {
|
||||||
|
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
|
||||||
|
if (candidateDescriptor is ConstructorDescriptor && !kotlinCall.isSupertypeConstructorCall) {
|
||||||
|
if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) {
|
||||||
|
return listOf(InstantiationOfAbstractClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal object CheckVisibility : ResolutionPart {
|
internal object CheckVisibility : ResolutionPart {
|
||||||
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
|
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
|
||||||
@@ -213,6 +222,10 @@ fun <D : CallableDescriptor> D.safeSubstitute(substitutor: TypeSubstitutor): D =
|
|||||||
fun UnwrappedType.substitute(substitutor: TypeSubstitutor): UnwrappedType = substitutor.substitute(this, Variance.INVARIANT)!!.unwrap()
|
fun UnwrappedType.substitute(substitutor: TypeSubstitutor): UnwrappedType = substitutor.substitute(this, Variance.INVARIANT)!!.unwrap()
|
||||||
|
|
||||||
|
|
||||||
|
object InstantiationOfAbstractClass : KotlinCallDiagnostic(RUNTIME_ERROR) {
|
||||||
|
override fun report(reporter: DiagnosticReporter) = reporter.onCall(this)
|
||||||
|
}
|
||||||
|
|
||||||
class UnstableSmartCast(val expressionArgument: ExpressionKotlinCallArgument, val targetType: UnwrappedType) :
|
class UnstableSmartCast(val expressionArgument: ExpressionKotlinCallArgument, val targetType: UnwrappedType) :
|
||||||
KotlinCallDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR) {
|
KotlinCallDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR) {
|
||||||
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(expressionArgument, this)
|
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(expressionArgument, this)
|
||||||
|
|||||||
+1
@@ -63,5 +63,6 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, resultT
|
|||||||
override val externalArgument: KotlinCallArgument? get() = throw UnsupportedOperationException()
|
override val externalArgument: KotlinCallArgument? get() = throw UnsupportedOperationException()
|
||||||
override val isInfixCall: Boolean get() = throw UnsupportedOperationException()
|
override val isInfixCall: Boolean get() = throw UnsupportedOperationException()
|
||||||
override val isOperatorCall: Boolean get() = throw UnsupportedOperationException()
|
override val isOperatorCall: Boolean get() = throw UnsupportedOperationException()
|
||||||
|
override val isSupertypeConstructorCall: Boolean get() = throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,7 @@ interface KotlinCall {
|
|||||||
|
|
||||||
val isInfixCall: Boolean
|
val isInfixCall: Boolean
|
||||||
val isOperatorCall: Boolean
|
val isOperatorCall: Boolean
|
||||||
|
val isSupertypeConstructorCall: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SimpleKotlinCallArgument.checkReceiverInvariants() {
|
private fun SimpleKotlinCallArgument.checkReceiverInvariants() {
|
||||||
|
|||||||
+1
@@ -81,6 +81,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
|
|||||||
CheckReceivers
|
CheckReceivers
|
||||||
),
|
),
|
||||||
FUNCTION(
|
FUNCTION(
|
||||||
|
CheckInstantiationOfAbstractClass,
|
||||||
CheckVisibility,
|
CheckVisibility,
|
||||||
MapTypeArguments,
|
MapTypeArguments,
|
||||||
MapArguments,
|
MapArguments,
|
||||||
|
|||||||
Reference in New Issue
Block a user