[JVM IR] Use error types in KAPT mode for unresolved delegate types.

^KT-57388 Fixed
This commit is contained in:
Mads Ager
2023-03-21 15:28:00 +01:00
committed by Alexander Udalov
parent 5a6e896b45
commit a525983e38
11 changed files with 259 additions and 3 deletions
@@ -43,6 +43,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
import org.jetbrains.kotlin.psi2ir.intermediate.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.error.ErrorTypeKind
import org.jetbrains.kotlin.types.error.ErrorUtils.createErrorType
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
internal class DelegatedPropertyGenerator(
@@ -323,8 +325,11 @@ internal class DelegatedPropertyGenerator(
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, delegatedPropertyDescriptor)
val delegateType = if (provideDelegateResolvedCall != null) {
provideDelegateResolvedCall.resultingDescriptor.returnType!!
} else {
} else if (context.configuration.generateBodies) {
getTypeInferredByFrontendOrFail(ktDelegate.expression!!)
} else {
getTypeInferredByFrontend(ktDelegate.expression!!)
?: createErrorType(ErrorTypeKind.UNRESOLVED_TYPE, ktDelegate.expression!!.text)
}
// For KAPT stub generation, we approximate the type of the delegate.
// Since we are not generating bodies, we could end up with unbound
+15
View File
@@ -0,0 +1,15 @@
@kotlin.Metadata
public final class User {
// source: 'dataClass.kt'
private final field age: int
private final @org.jetbrains.annotations.NotNull field name: java.lang.String
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: int): void
public final @org.jetbrains.annotations.NotNull method component1(): java.lang.String
public final method component2(): int
public final @org.jetbrains.annotations.NotNull method copy(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: int): User
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public final method getAge(): int
public final @org.jetbrains.annotations.NotNull method getName(): java.lang.String
public method hashCode(): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
}
+30
View File
@@ -0,0 +1,30 @@
@kotlin.Metadata
@kotlin.Suppress(names=["UNRESOLVED_REFERENCE"])
public final class A {
// source: 'errorTypes.kt'
private final @org.jetbrains.annotations.NotNull field a: error.NonExistentClass
public method <init>(): void
public final @org.jetbrains.annotations.NotNull method getA(): error.NonExistentClass
}
@kotlin.Metadata
@kotlin.Suppress(names=["UNRESOLVED_REFERENCE"])
public final class B {
// source: 'errorTypes.kt'
private final @org.jetbrains.annotations.NotNull field a$delegate: error.NonExistentClass
public method <init>(): void
public synthetic deprecated static @kotlin.Suppress(names=["UNRESOLVED_REFERENCE_WRONG_RECEIVER"]) method getA$annotations(): void
public final @org.jetbrains.annotations.NotNull method getA(): java.lang.String
}
@kotlin.Metadata
public class C {
// source: 'errorTypes.kt'
public method <init>(): void
}
@kotlin.Metadata
public final class ErrorTypesKt {
// source: 'errorTypes.kt'
public final static @org.jetbrains.annotations.NotNull method flaf(@org.jetbrains.annotations.NotNull p0: C): java.lang.String
}
+11 -1
View File
@@ -1,4 +1,14 @@
@Suppress("UNRESOLVED_REFERENCE")
class A {
val a: ABC = null
}
}
open class C
@Suppress("UNRESOLVED_REFERENCE")
class B : NonExisting {
@Suppress("UNRESOLVED_REFERENCE_WRONG_RECEIVER")
val a: String by flaf()
}
fun C.flaf() = "OK"
+23
View File
@@ -6,3 +6,26 @@ public final class A {
public method <init>(): void
public final @org.jetbrains.annotations.NotNull method getA(): error.NonExistentClass
}
@kotlin.Metadata
@kotlin.Suppress(names=["UNRESOLVED_REFERENCE"])
public final class B {
// source: 'errorTypes.kt'
synthetic final static field $$delegatedProperties: kotlin.reflect.KProperty[]
private final @org.jetbrains.annotations.NotNull field a$delegate: error.NonExistentClass
public method <init>(): void
public synthetic deprecated static @kotlin.Suppress(names=["UNRESOLVED_REFERENCE_WRONG_RECEIVER"]) method getA$annotations(): void
public final @org.jetbrains.annotations.NotNull method getA(): java.lang.String
}
@kotlin.Metadata
public class C {
// source: 'errorTypes.kt'
public method <init>(): void
}
@kotlin.Metadata
public final class ErrorTypesKt {
// source: 'errorTypes.kt'
public final static @org.jetbrains.annotations.NotNull method flaf(@org.jetbrains.annotations.NotNull p0: C): java.lang.String
}
+61
View File
@@ -0,0 +1,61 @@
@kotlin.Metadata
public final class test/TopLevel$Companion {
// source: 'innerClasses.kt'
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
public final method a(): void
public synthetic deprecated static @kotlin.jvm.JvmStatic method getQ$annotations(): void
public final @org.jetbrains.annotations.NotNull method getQ(): java.lang.String
public final inner class test/TopLevel$Companion
}
@kotlin.Metadata
public interface test/TopLevel$InnerInterface {
// source: 'innerClasses.kt'
public inner class test/TopLevel$InnerInterface
}
@kotlin.Metadata
public final class test/TopLevel$InnerObject {
// source: 'innerClasses.kt'
public final static @org.jetbrains.annotations.NotNull field INSTANCE: test.TopLevel$InnerObject
static method <clinit>(): void
private method <init>(): void
public final inner class test/TopLevel$InnerObject
}
@kotlin.Metadata
public final class test/TopLevel$NestedClass$NestedInnerClass {
// source: 'innerClasses.kt'
synthetic final field this$0: test.TopLevel$NestedClass
public method <init>(p0: test.TopLevel$NestedClass): void
public final inner class test/TopLevel$NestedClass
public final inner class test/TopLevel$NestedClass$NestedInnerClass
}
@kotlin.Metadata
public final class test/TopLevel$NestedClass {
// source: 'innerClasses.kt'
public method <init>(): void
public final inner class test/TopLevel$NestedClass
public final inner class test/TopLevel$NestedClass$NestedInnerClass
}
@kotlin.Metadata
public final class test/TopLevel {
// source: 'innerClasses.kt'
public final static @org.jetbrains.annotations.NotNull field Companion: test.TopLevel$Companion
private final static @org.jetbrains.annotations.NotNull field q: java.lang.String
private final @org.jetbrains.annotations.NotNull field x: java.lang.String
private final field y: int
static method <clinit>(): void
public method <init>(): void
public final method b(): void
public final static @org.jetbrains.annotations.NotNull method getQ(): java.lang.String
public final @org.jetbrains.annotations.NotNull method getX(): java.lang.String
public final method getY(): int
public final inner class test/TopLevel$Companion
public final inner class test/TopLevel$InnerObject
public final inner class test/TopLevel$NestedClass
public inner class test/TopLevel$InnerInterface
}
+10
View File
@@ -0,0 +1,10 @@
@kotlin.Metadata
public final class Test {
// source: 'jvmOverloads.kt'
public method <init>(): void
public synthetic static method b$default(p0: Test, p1: java.lang.String, p2: int, p3: char, p4: int, p5: java.lang.Object): void
public final @kotlin.jvm.JvmOverloads method b(): void
public final @kotlin.jvm.JvmOverloads method b(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
public final @kotlin.jvm.JvmOverloads method b(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: int): void
public final @kotlin.jvm.JvmOverloads method b(@org.jetbrains.annotations.NotNull p0: java.lang.String, p1: int, p2: char): void
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2023 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
import org.jetbrains.kotlin.resolve.jvm.extensions.PartialAnalysisHandlerExtension
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TargetBackend
import java.io.File
abstract class AbstractIrKapt3BuilderModeBytecodeShapeTest : AbstractKapt3BuilderModeBytecodeShapeTest() {
override val backend: TargetBackend = TargetBackend.JVM_IR
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
import org.jetbrains.kotlin.resolve.jvm.extensions.PartialAnalysisHandlerExtension
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TargetBackend
import java.io.File
abstract class AbstractKapt3BuilderModeBytecodeShapeTest : CodegenTestCase() {
@@ -31,7 +32,9 @@ abstract class AbstractKapt3BuilderModeBytecodeShapeTest : CodegenTestCase() {
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
compile(files)
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
val irFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".ir.txt")
val nonIrFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
val txtFile = if (backend == TargetBackend.JVM_IR && irFile.exists()) irFile else nonIrFile
KotlinTestUtils.assertEqualsToFile(txtFile, BytecodeListingTextCollectingVisitor.getText(classFileFactory))
}
@@ -100,6 +100,10 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
model("codegen/kapt", targetBackend = TargetBackend.JVM)
}
testClass<AbstractIrKapt3BuilderModeBytecodeShapeTest> {
model("codegen/kapt", targetBackend = TargetBackend.JVM_IR)
}
testClass<AbstractScriptCodegenTest> {
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM)
}
@@ -0,0 +1,67 @@
/*
* Copyright 2010-2023 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.codegen;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.test.generators.GenerateCompilerTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/kapt")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class IrKapt3BuilderModeBytecodeShapeTestGenerated extends AbstractIrKapt3BuilderModeBytecodeShapeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
public void testAllFilesPresentInKapt() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/kapt"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@TestMetadata("dataClass.kt")
public void testDataClass() throws Exception {
runTest("compiler/testData/codegen/kapt/dataClass.kt");
}
@TestMetadata("errorTypes.kt")
public void testErrorTypes() throws Exception {
runTest("compiler/testData/codegen/kapt/errorTypes.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/kapt/innerClasses.kt");
}
@TestMetadata("interfaceImpls.kt")
public void testInterfaceImpls() throws Exception {
runTest("compiler/testData/codegen/kapt/interfaceImpls.kt");
}
@TestMetadata("jvmOverloads.kt")
public void testJvmOverloads() throws Exception {
runTest("compiler/testData/codegen/kapt/jvmOverloads.kt");
}
@TestMetadata("lambdas.kt")
public void testLambdas() throws Exception {
runTest("compiler/testData/codegen/kapt/lambdas.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/codegen/kapt/simple.kt");
}
}