[JVM IR] Use error types in KAPT mode for unresolved delegate types.
^KT-57388 Fixed
This commit is contained in:
committed by
Alexander Udalov
parent
5a6e896b45
commit
a525983e38
+6
-1
@@ -43,6 +43,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
|||||||
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
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
|
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
|
||||||
|
|
||||||
internal class DelegatedPropertyGenerator(
|
internal class DelegatedPropertyGenerator(
|
||||||
@@ -323,8 +325,11 @@ internal class DelegatedPropertyGenerator(
|
|||||||
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, delegatedPropertyDescriptor)
|
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, delegatedPropertyDescriptor)
|
||||||
val delegateType = if (provideDelegateResolvedCall != null) {
|
val delegateType = if (provideDelegateResolvedCall != null) {
|
||||||
provideDelegateResolvedCall.resultingDescriptor.returnType!!
|
provideDelegateResolvedCall.resultingDescriptor.returnType!!
|
||||||
} else {
|
} else if (context.configuration.generateBodies) {
|
||||||
getTypeInferredByFrontendOrFail(ktDelegate.expression!!)
|
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.
|
// For KAPT stub generation, we approximate the type of the delegate.
|
||||||
// Since we are not generating bodies, we could end up with unbound
|
// Since we are not generating bodies, we could end up with unbound
|
||||||
|
|||||||
+15
@@ -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
|
||||||
|
}
|
||||||
@@ -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
@@ -1,4 +1,14 @@
|
|||||||
@Suppress("UNRESOLVED_REFERENCE")
|
@Suppress("UNRESOLVED_REFERENCE")
|
||||||
class A {
|
class A {
|
||||||
val a: ABC = null
|
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
@@ -6,3 +6,26 @@ public final class A {
|
|||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
public final @org.jetbrains.annotations.NotNull method getA(): error.NonExistentClass
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
+28
@@ -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
|
||||||
|
}
|
||||||
+4
-1
@@ -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.AnalysisHandlerExtension
|
||||||
import org.jetbrains.kotlin.resolve.jvm.extensions.PartialAnalysisHandlerExtension
|
import org.jetbrains.kotlin.resolve.jvm.extensions.PartialAnalysisHandlerExtension
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractKapt3BuilderModeBytecodeShapeTest : CodegenTestCase() {
|
abstract class AbstractKapt3BuilderModeBytecodeShapeTest : CodegenTestCase() {
|
||||||
@@ -31,7 +32,9 @@ abstract class AbstractKapt3BuilderModeBytecodeShapeTest : CodegenTestCase() {
|
|||||||
|
|
||||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||||
compile(files)
|
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))
|
KotlinTestUtils.assertEqualsToFile(txtFile, BytecodeListingTextCollectingVisitor.getText(classFileFactory))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -100,6 +100,10 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
|
|||||||
model("codegen/kapt", targetBackend = TargetBackend.JVM)
|
model("codegen/kapt", targetBackend = TargetBackend.JVM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrKapt3BuilderModeBytecodeShapeTest> {
|
||||||
|
model("codegen/kapt", targetBackend = TargetBackend.JVM_IR)
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractScriptCodegenTest> {
|
testClass<AbstractScriptCodegenTest> {
|
||||||
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM)
|
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM)
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+67
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user