K2: implement correct check for ctors mapped from java

so the check is functionally the same as in K1.
#KT-57064 fixed
#KT-57065 fixed
One of the tests introduced here (javaMappedCtors) revealed an
additional issue, filed as KT-57368
This commit is contained in:
Ilya Chernikov
2023-03-09 11:05:22 +01:00
committed by Space Team
parent 730502638a
commit 0e77b67170
10 changed files with 165 additions and 57 deletions
@@ -198,6 +198,4 @@ open fun hashCode(): kotlin.Int
companion object
constructor(value: kotlin.Int)
private constructor()
@@ -3602,50 +3602,6 @@ KtNamedClassOrObjectSymbol:
annotationApplicableTargets: null
deprecationStatus: null
KtConstructorSymbol:
annotationsList: []
callableIdIfNonLocal: null
containingClassIdIfNonLocal: kotlin/Int
contextReceivers: []
hasStableParameterNames: false
isExtension: false
isPrimary: false
origin: JAVA
receiverParameter: null
returnType: KtUsualClassType:
annotationsList: []
ownTypeArguments: []
type: java/lang/Integer
symbolKind: CLASS_MEMBER
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SUBSTITUTION_OVERRIDE
receiverParameter: null
returnType: KtUsualClassType:
annotationsList: []
ownTypeArguments: []
type: kotlin/Int
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSdkModule "SDK jdk"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtConstructorSymbol:
annotationsList: []
callableIdIfNonLocal: null
@@ -24324,6 +24324,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/platformTypes/javaEmptyList.kt");
}
@Test
@TestMetadata("javaMappedCtors.kt")
public void testJavaMappedCtors() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/javaMappedCtors.kt");
}
@Test
@TestMetadata("kt50877.kt")
public void testKt50877() throws Exception {
@@ -33810,6 +33816,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/typealias/kt19601.kt");
}
@Test
@TestMetadata("kt57065.kt")
public void testKt57065() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/kt57065.kt");
}
@Test
@TestMetadata("localTypeAlias.kt")
public void testLocalTypeAlias() throws Exception {
@@ -24324,6 +24324,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/platformTypes/javaEmptyList.kt");
}
@Test
@TestMetadata("javaMappedCtors.kt")
public void testJavaMappedCtors() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/javaMappedCtors.kt");
}
@Test
@TestMetadata("kt50877.kt")
public void testKt50877() throws Exception {
@@ -33810,6 +33816,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/typealias/kt19601.kt");
}
@Test
@TestMetadata("kt57065.kt")
public void testKt57065() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/kt57065.kt");
}
@Test
@TestMetadata("localTypeAlias.kt")
public void testLocalTypeAlias() throws Exception {
@@ -24330,6 +24330,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/platformTypes/javaEmptyList.kt");
}
@Test
@TestMetadata("javaMappedCtors.kt")
public void testJavaMappedCtors() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/javaMappedCtors.kt");
}
@Test
@TestMetadata("kt50877.kt")
public void testKt50877() throws Exception {
@@ -33906,6 +33912,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/typealias/kt19601.kt");
}
@Test
@TestMetadata("kt57065.kt")
public void testKt57065() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/kt57065.kt");
}
@Test
@TestMetadata("localTypeAlias.kt")
public void testLocalTypeAlias() throws Exception {
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.fir.scopes.jvm
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSignatures
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.constructors
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
@@ -17,11 +19,12 @@ import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
import org.jetbrains.kotlin.fir.scopes.impl.buildSubstitutorForOverridesCheck
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents.inJavaLang
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name
@@ -37,6 +40,8 @@ class JvmMappedScope(
private val constructorsCache = mutableMapOf<FirConstructorSymbol, FirConstructorSymbol>()
private val overrideChecker = FirStandardOverrideChecker(session)
private val substitutor = ConeSubstitutorByMap(
firJavaClass.typeParameters.zip(firKotlinClass.typeParameters).associate { (javaParameter, kotlinParameter) ->
javaParameter.symbol to ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(kotlinParameter.symbol), isNullable = false)
@@ -96,19 +101,40 @@ class JvmMappedScope(
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction
) = ProcessorAction.NONE
private val firKotlinClassConstructors by lazy(LazyThreadSafetyMode.PUBLICATION) {
firKotlinClass.constructors(session)
}
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
val hiddenConstructors = signatures.hiddenConstructors
if (hiddenConstructors.isNotEmpty()) {
javaMappedClassUseSiteScope.processDeclaredConstructors { symbol ->
val jvmSignature = symbol.fir.computeJvmDescriptor()
if (jvmSignature !in hiddenConstructors) {
val newSymbol = getOrCreateCopy(symbol)
processor(newSymbol)
javaMappedClassUseSiteScope.processDeclaredConstructors { javaCtorSymbol ->
fun FirConstructor.isShadowedBy(ctorFromKotlin: FirConstructorSymbol): Boolean {
// assuming already checked for visibility
val valueParams = valueParameters
val valueParamsFromKotlin = ctorFromKotlin.fir.valueParameters
if (valueParams.size != valueParamsFromKotlin.size) return false
val substitutor = buildSubstitutorForOverridesCheck(ctorFromKotlin.fir, this@isShadowedBy, session) ?: return false
return valueParamsFromKotlin.zip(valueParams).all { (kotlinCtorParam, javaCtorParam) ->
overrideChecker.isEqualTypes(kotlinCtorParam.returnTypeRef, javaCtorParam.returnTypeRef, substitutor)
}
}
} else {
javaMappedClassUseSiteScope.processDeclaredConstructors { symbol ->
val newSymbol = getOrCreateCopy(symbol)
fun FirConstructor.isTrivialCopyConstructor(): Boolean =
valueParameters.singleOrNull()?.let {
val type = substitutor.substituteOrSelf(it.returnTypeRef.coneType)
type == firKotlinClass.defaultType()
} ?: false
// In K1 it is handled by JvmBuiltInsCustomizer.getConstructors
// Here the logic is generally the same, but simplified for performance by reordering checks and avoiding checking
// for the impossible combinations
val javaCtor = javaCtorSymbol.fir
if (javaCtor.status.visibility.isPublicAPI &&
javaCtor.computeJvmDescriptor() !in signatures.hiddenConstructors &&
!javaCtor.isTrivialCopyConstructor() &&
firKotlinClassConstructors.none { javaCtor.isShadowedBy(it) }
) {
val newSymbol = getOrCreateCopy(javaCtorSymbol)
processor(newSymbol)
}
}
@@ -0,0 +1,36 @@
// TARGET_BACKEND: JVM_IR
typealias ABoolean = Boolean
typealias AChar = Char
typealias AInt = Int
typealias ALong = Long
typealias AShort = Short
typealias AByte = Byte
typealias AFloat = Float
typealias ADouble = Double
fun main() {
<!INVISIBLE_REFERENCE!>ABoolean<!>(false)
Boolean(false)
<!INVISIBLE_REFERENCE!>AChar<!>('c')
<!INVISIBLE_REFERENCE!>Char<!>('c')
<!INVISIBLE_REFERENCE!>AInt<!>(42)
<!INVISIBLE_REFERENCE!>Int<!>(42)
<!INVISIBLE_REFERENCE!>ALong<!>(42)
Long(42)
<!INVISIBLE_REFERENCE!>AShort<!>(42)
Short(42)
<!INVISIBLE_REFERENCE!>AByte<!>(42)
Byte(42)
<!INVISIBLE_REFERENCE!>AFloat<!>(4.2f)
Float(4.2f)
<!INVISIBLE_REFERENCE!>ADouble<!>(4.2)
Double(4.2)
}
@@ -0,0 +1,36 @@
// TARGET_BACKEND: JVM_IR
typealias ABoolean = Boolean
typealias AChar = Char
typealias AInt = Int
typealias ALong = Long
typealias AShort = Short
typealias AByte = Byte
typealias AFloat = Float
typealias ADouble = Double
fun main() {
<!INVISIBLE_MEMBER!>ABoolean<!>(<!TOO_MANY_ARGUMENTS!>false<!>)
<!INVISIBLE_MEMBER!>Boolean<!>(<!TOO_MANY_ARGUMENTS!>false<!>)
<!INVISIBLE_MEMBER!>AChar<!>(<!TOO_MANY_ARGUMENTS!>'c'<!>)
<!INVISIBLE_MEMBER!>Char<!>(<!TOO_MANY_ARGUMENTS!>'c'<!>)
<!INVISIBLE_MEMBER!>AInt<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>Int<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>ALong<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>Long<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>AShort<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>Short<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>AByte<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>Byte<!>(<!TOO_MANY_ARGUMENTS!>42<!>)
<!INVISIBLE_MEMBER!>AFloat<!>(<!TOO_MANY_ARGUMENTS!>4.2f<!>)
<!INVISIBLE_MEMBER!>Float<!>(<!TOO_MANY_ARGUMENTS!>4.2f<!>)
<!INVISIBLE_MEMBER!>ADouble<!>(<!TOO_MANY_ARGUMENTS!>4.2<!>)
<!INVISIBLE_MEMBER!>Double<!>(<!TOO_MANY_ARGUMENTS!>4.2<!>)
}
@@ -0,0 +1,8 @@
// FIR_IDENTICAL
typealias GlobalUndoLogRef = Long
fun GlobalUndoLogRef(p: Long): GlobalUndoLogRef = p
fun main() {
GlobalUndoLogRef(42)
}
@@ -24330,6 +24330,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/platformTypes/javaEmptyList.kt");
}
@Test
@TestMetadata("javaMappedCtors.kt")
public void testJavaMappedCtors() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/javaMappedCtors.kt");
}
@Test
@TestMetadata("kt50877.kt")
public void testKt50877() throws Exception {
@@ -33906,6 +33912,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/typealias/kt19601.kt");
}
@Test
@TestMetadata("kt57065.kt")
public void testKt57065() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/kt57065.kt");
}
@Test
@TestMetadata("localTypeAlias.kt")
public void testLocalTypeAlias() throws Exception {