Skip to content

Commit

Permalink
[JVM IR] Use error types in KAPT mode for unresolved delegate types.
Browse files Browse the repository at this point in the history
^KT-57388 Fixed

(cherry picked from commit a525983)
  • Loading branch information
madsager authored and udalov committed Mar 21, 2023
1 parent 1b7a243 commit 0848340
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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

class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
Expand Down Expand Up @@ -321,8 +323,11 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
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
Expand Down
15 changes: 15 additions & 0 deletions compiler/testData/codegen/kapt/dataClass.ir.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions compiler/testData/codegen/kapt/errorTypes.ir.txt
Original file line number Diff line number Diff line change
@@ -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
}
12 changes: 11 additions & 1 deletion compiler/testData/codegen/kapt/errorTypes.kt
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions compiler/testData/codegen/kapt/errorTypes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 61 additions & 0 deletions compiler/testData/codegen/kapt/innerClasses.ir.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions compiler/testData/codegen/kapt/jvmOverloads.ir.txt
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0848340

Please sign in to comment.