[NI] Move abstract class instantiation check to call checkers

This way the check works for callable reference arguments.
Also candidate applicability during resolution does not change compared to the old inference.
^KT-37530 Fixed
This commit is contained in:
Pavel Kirpichenkov
2020-03-17 11:46:26 +03:00
parent 3f00de5d7b
commit a416fde814
13 changed files with 195 additions and 17 deletions
@@ -1884,6 +1884,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/callableReference/kt35959.kt");
}
@TestMetadata("kt37530.kt")
public void testKt37530() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt37530.kt");
}
@TestMetadata("kt7430_wrongClassOnLHS.kt")
public void testKt7430_wrongClassOnLHS() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt7430_wrongClassOnLHS.kt");
@@ -15860,6 +15865,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/overload/defaultParameters.kt");
}
@TestMetadata("disambiguateByFailedAbstractClassCheck.kt")
public void testDisambiguateByFailedAbstractClassCheck() throws Exception {
runTest("compiler/testData/diagnostics/tests/overload/disambiguateByFailedAbstractClassCheck.kt");
}
@TestMetadata("EmptyArgumentListInLambda.kt")
public void testEmptyArgumentListInLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt");
@@ -49,7 +49,7 @@ private val DEFAULT_CALL_CHECKERS = listOf(
PrimitiveNumericComparisonCallChecker, LambdaWithSuspendModifierCallChecker,
UselessElvisCallChecker(), ResultTypeWithNullableOperatorsChecker(), NullableVarargArgumentCallChecker,
NamedFunAsExpressionChecker, ContractNotAllowedCallChecker, ReifiedTypeParameterSubstitutionChecker(), TypeOfChecker,
MissingDependencySupertypeChecker.ForCalls
MissingDependencySupertypeChecker.ForCalls, AbstractClassInstantiationChecker,
)
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.Errors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
object AbstractClassInstantiationChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val candidateDescriptor = resolvedCall.candidateDescriptor
val call = resolvedCall.call
if (candidateDescriptor is ConstructorDescriptor &&
!isSuperOrDelegatingConstructorCall(call)
) {
if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) {
context.trace.reportDiagnosticOnce(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS.on(call.callElement))
}
}
}
}
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.resolve.calls.components.CollectionTypeVariableUsagesInfo.getTypeParameterByVariable
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
@@ -36,20 +35,6 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) {
val candidateDescriptor = resolvedCall.candidateDescriptor
if (candidateDescriptor is ConstructorDescriptor &&
!callComponents.statelessCallbacks.isSuperOrDelegatingConstructorCall(resolvedCall.atom)
) {
if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) {
addDiagnostic(InstantiationOfAbstractClass)
}
}
}
}
internal object CheckVisibility : ResolutionPart() {
override fun KotlinResolutionCandidate.process(workIndex: Int) {
val containingDescriptor = scopeTower.lexicalScope.ownerDescriptor
@@ -212,7 +212,6 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
PostponedVariablesInitializerResolutionPart
),
FUNCTION(
CheckInstantiationOfAbstractClass,
CheckVisibility,
CheckInfixResolutionPart,
CheckOperatorResolutionPart,
@@ -0,0 +1,11 @@
// !WITH_NEW_INFERENCE
abstract class Abstract
fun <D> create(fn: () -> D): D {
return fn()
}
fun main() {
create(::Abstract)
}
@@ -0,0 +1,11 @@
// !WITH_NEW_INFERENCE
abstract class Abstract
fun <D> create(fn: () -> D): D {
return fn()
}
fun main() {
create(::<!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, OI;CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, OI;CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>Abstract<!>)
}
@@ -0,0 +1,11 @@
package
public fun </*0*/ D> create(/*0*/ fn: () -> D): D
public fun main(): kotlin.Unit
public abstract class Abstract {
public constructor Abstract()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,34 @@
// !WITH_NEW_IFERENCE
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: packageA.kt
package a
abstract class Cls
abstract class Cls2
// FILE: packageB.kt
package b
fun Cls() {}
class Cls2
// FILE: test.kt
package c
import a.*
import b.*
fun take(arg: Any) {}
fun test() {
<!AMBIGUITY!>Cls<!>()
take(<!AMBIGUITY!>Cls<!>())
Cls2()
take(Cls2())
}
@@ -0,0 +1,34 @@
// !WITH_NEW_IFERENCE
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: packageA.kt
package a
abstract class Cls
abstract class Cls2
// FILE: packageB.kt
package b
fun Cls() {}
class Cls2
// FILE: test.kt
package c
import a.*
import b.*
fun take(arg: Any) {}
fun test() {
<!OVERLOAD_RESOLUTION_AMBIGUITY!>Cls<!>()
take(<!OVERLOAD_RESOLUTION_AMBIGUITY!>Cls<!>())
<!UNRESOLVED_REFERENCE!>Cls2<!>()
take(<!UNRESOLVED_REFERENCE!>Cls2<!>())
}
@@ -0,0 +1,34 @@
package
package a {
public abstract class Cls {
public constructor Cls()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class Cls2 {
public constructor Cls2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package b {
public fun Cls(): kotlin.Unit
public final class Cls2 {
public constructor Cls2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package c {
public fun take(/*0*/ arg: kotlin.Any): kotlin.Unit
public fun test(): kotlin.Unit
}
@@ -1891,6 +1891,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/callableReference/kt35959.kt");
}
@TestMetadata("kt37530.kt")
public void testKt37530() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt37530.kt");
}
@TestMetadata("kt7430_wrongClassOnLHS.kt")
public void testKt7430_wrongClassOnLHS() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt7430_wrongClassOnLHS.kt");
@@ -15867,6 +15872,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/overload/defaultParameters.kt");
}
@TestMetadata("disambiguateByFailedAbstractClassCheck.kt")
public void testDisambiguateByFailedAbstractClassCheck() throws Exception {
runTest("compiler/testData/diagnostics/tests/overload/disambiguateByFailedAbstractClassCheck.kt");
}
@TestMetadata("EmptyArgumentListInLambda.kt")
public void testEmptyArgumentListInLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt");
@@ -1886,6 +1886,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/callableReference/kt35959.kt");
}
@TestMetadata("kt37530.kt")
public void testKt37530() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt37530.kt");
}
@TestMetadata("kt7430_wrongClassOnLHS.kt")
public void testKt7430_wrongClassOnLHS() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt7430_wrongClassOnLHS.kt");
@@ -15862,6 +15867,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/overload/defaultParameters.kt");
}
@TestMetadata("disambiguateByFailedAbstractClassCheck.kt")
public void testDisambiguateByFailedAbstractClassCheck() throws Exception {
runTest("compiler/testData/diagnostics/tests/overload/disambiguateByFailedAbstractClassCheck.kt");
}
@TestMetadata("EmptyArgumentListInLambda.kt")
public void testEmptyArgumentListInLambda() throws Exception {
runTest("compiler/testData/diagnostics/tests/overload/EmptyArgumentListInLambda.kt");