[FIR] Support deserialization of value parameter annotations

There are still some problems, see KT-39837
This commit is contained in:
Dmitriy Novozhilov
2020-06-25 18:26:01 +03:00
parent 2b2f9b3386
commit 7834284bec
22 changed files with 191 additions and 96 deletions
@@ -7,7 +7,7 @@ public sealed class Sealed : R|kotlin/Any| {
public final val z: R|test/Z| public final val z: R|test/Z|
public get(): R|test/Z| public get(): R|test/Z|
@R|test/Ann|() private constructor(z: R|test/Z|): R|test/Sealed| @R|test/Ann|() private constructor(@R|test/Ann|() z: R|test/Z|): R|test/Sealed|
public final class Derived : R|test/Sealed| { public final class Derived : R|test/Sealed| {
public constructor(z: R|test/Z|): R|test/Sealed.Derived| public constructor(z: R|test/Z|): R|test/Sealed.Derived|
@@ -20,11 +20,11 @@ public final class Test : R|kotlin/Any| {
public final val z: R|test/Z| public final val z: R|test/Z|
public get(): R|test/Z| public get(): R|test/Z|
@R|test/Ann|() public constructor(z: R|test/Z|, a: R|kotlin/Int|): R|test/Test| @R|test/Ann|() public constructor(z: R|test/Z|, @R|test/Ann|() a: R|kotlin/Int|): R|test/Test|
@R|test/Ann|() private constructor(z: R|test/Z|, s: R|kotlin/String|): R|test/Test| @R|test/Ann|() private constructor(z: R|test/Z|, @R|test/Ann|() s: R|kotlin/String|): R|test/Test|
@R|test/Ann|() public constructor(z: R|test/Z|): R|test/Test| @R|test/Ann|() public constructor(@R|test/Ann|() z: R|test/Z|): R|test/Test|
} }
@@ -12,6 +12,6 @@ public final class Class : R|kotlin/Any| {
public final val x: R|kotlin/Int| public final val x: R|kotlin/Int|
public get(): R|kotlin/Int| public get(): R|kotlin/Int|
public constructor(x: R|kotlin/Int|, y: R|kotlin/String|): R|test/Class| public constructor(@R|test/A|() x: R|kotlin/Int|, @R|test/B|() y: R|kotlin/String|): R|test/Class|
} }
@@ -1,4 +1,4 @@
public final fun R|kotlin/Int|.foo(x: R|kotlin/Int|): R|kotlin/Unit| public final fun R|kotlin/Int|.foo(@R|test/A|() x: R|kotlin/Int|): R|kotlin/Unit|
public final annotation class A : R|kotlin/Annotation| { public final annotation class A : R|kotlin/Annotation| {
public constructor(): R|test/A| public constructor(): R|test/A|
@@ -4,7 +4,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
} }
public final class Class : R|kotlin/Any| { public final class Class : R|kotlin/Any| {
public final fun R|kotlin/String|.foo(x: R|kotlin/Int|): R|kotlin/Int| public final fun R|kotlin/String|.foo(@R|test/Anno|() x: R|kotlin/Int|): R|kotlin/Int|
public constructor(): R|test/Class| public constructor(): R|test/Class|
@@ -4,7 +4,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
} }
public final class Class : R|kotlin/Any| { public final class Class : R|kotlin/Any| {
public final fun foo(x: R|kotlin/String|): R|kotlin/Unit| public final fun foo(@R|test/Anno|() x: R|kotlin/String|): R|kotlin/Unit|
public constructor(): R|test/Class| public constructor(): R|test/Class|
@@ -4,6 +4,6 @@ public final annotation class Anno : R|kotlin/Annotation| {
} }
public abstract interface Trait : R|kotlin/Any| { public abstract interface Trait : R|kotlin/Any| {
public open fun foo(x: R|kotlin/String|): R|kotlin/Int| public open fun foo(@R|test/Anno|() x: R|kotlin/String|): R|kotlin/Int|
} }
@@ -1,6 +1,6 @@
public final fun bar(x: R|kotlin/Int|): R|kotlin/Unit| public final fun bar(@R|test/A|() @R|test/B|() @R|test/C|() @R|test/D|() x: R|kotlin/Int|): R|kotlin/Unit|
public final fun foo(x: R|kotlin/Int|, y: R|kotlin/Double|, z: R|kotlin/String|): R|kotlin/Unit| public final fun foo(@R|test/A|() @R|test/B|() x: R|kotlin/Int|, @R|test/A|() @R|test/C|() y: R|kotlin/Double|, @R|test/B|() @R|test/C|() @R|test/D|() z: R|kotlin/String|): R|kotlin/Unit|
public final annotation class A : R|kotlin/Annotation| { public final annotation class A : R|kotlin/Annotation| {
public constructor(): R|test/A| public constructor(): R|test/A|
@@ -1,4 +1,4 @@
public final fun foo(x: R|kotlin/Int|): R|kotlin/Unit| public final fun foo(@R|test/Anno|() x: R|kotlin/Int|): R|kotlin/Unit|
public final annotation class Anno : R|kotlin/Annotation| { public final annotation class Anno : R|kotlin/Annotation| {
public constructor(): R|test/Anno| public constructor(): R|test/Anno|
@@ -1,5 +1,5 @@
public final class A : R|kotlin/Any| { public final class A : R|kotlin/Any| {
public final fun R|kotlin/String|.myLength(q: R|kotlin/String|): R|kotlin/Int| public final fun R|kotlin/String|.myLength(@R|test/Ann|() q: R|kotlin/String|): R|kotlin/Int|
public final val R|kotlin/String|.myLength2: R|kotlin/Int| public final val R|kotlin/String|.myLength2: R|kotlin/Int|
public get(): R|kotlin/Int| public get(): R|kotlin/Int|
@@ -29,115 +29,110 @@ digraph complexPostponedCfg_kt {
9 [label="Postponed enter to lambda"]; 9 [label="Postponed enter to lambda"];
subgraph cluster_4 { subgraph cluster_4 {
color=blue color=blue
21 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 19 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_5 { subgraph cluster_5 {
color=blue color=blue
22 [label="Enter block"]; 20 [label="Enter block"];
23 [label="Postponed enter to lambda"]; 21 [label="Postponed enter to lambda"];
subgraph cluster_6 { subgraph cluster_6 {
color=blue color=blue
28 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 26 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_7 { subgraph cluster_7 {
color=blue color=blue
29 [label="Enter block"]; 27 [label="Enter block"];
30 [label="Access variable this@R|special/anonymous|"]; 28 [label="Access variable this@R|special/anonymous|"];
31 [label="Function call: this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(...)"]; 29 [label="Function call: this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(...)"];
32 [label="Access variable R|<local>/arguments|"]; 30 [label="Access variable R|<local>/arguments|"];
33 [label="Function call: R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>()"]; 31 [label="Function call: R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>()"];
34 [label="Type operator: (R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|)"]; 32 [label="Type operator: (R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|)"];
35 [label="Postponed enter to lambda"]; 33 [label="Postponed enter to lambda"];
subgraph cluster_8 { subgraph cluster_8 {
color=blue color=blue
41 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; 39 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_9 { subgraph cluster_9 {
color=blue color=blue
42 [label="Enter block"]; 40 [label="Enter block"];
43 [label="Access variable this@R|special/anonymous|"]; 41 [label="Access variable this@R|special/anonymous|"];
44 [label="Function call: this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(...)"]; 42 [label="Function call: this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(...)"];
45 [label="Access variable R|<local>/explicitReceiver|"]; 43 [label="Access variable R|<local>/explicitReceiver|"];
46 [label="Type operator: (R|<local>/explicitReceiver| as R|FirFunctionCall|)"]; 44 [label="Type operator: (R|<local>/explicitReceiver| as R|FirFunctionCall|)"];
47 [label="Function call: this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(...)"]; 45 [label="Function call: this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(...)"];
48 [label="Exit block"]; 46 [label="Exit block"];
} }
49 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; 47 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
} }
36 [label="Call arguments union" style="filled" fillcolor=yellow]; 34 [label="Call arguments union" style="filled" fillcolor=yellow];
37 [label="Postponed exit from lambda"]; 35 [label="Postponed exit from lambda"];
38 [label="Function call: R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Boolean|>(...)"]; 36 [label="Function call: R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Boolean|>(...)"];
39 [label="Exit block"]; 37 [label="Exit block"];
} }
40 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; 38 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
} }
24 [label="Postponed exit from lambda"]; 22 [label="Postponed exit from lambda"];
25 [label="Function call: R|kotlin/collections/buildList|<R|kotlin/Any?|>(...)"]; 23 [label="Function call: R|kotlin/collections/buildList|<R|FirFunctionCall|>(...)"];
26 [label="Exit block"]; 24 [label="Exit block"];
} }
27 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; 25 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
} }
10 [label="Call arguments union" style="filled" fillcolor=yellow]; 10 [label="Call arguments union" style="filled" fillcolor=yellow];
11 [label="Postponed exit from lambda"]; 11 [label="Postponed exit from lambda"];
12 [label="Function call: R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Nothing|>(...)"]; 12 [label="Function call: R|kotlin/with|<R|FirFunctionCall|, R|kotlin/collections/List<FirFunctionCall>|>(...)"];
13 [label="Stub" style="filled" fillcolor=gray]; 13 [label="Variable declaration: lval firstCalls: R|kotlin/collections/List<FirFunctionCall>|"];
14 [label="Variable declaration: lval firstCalls: R|kotlin/Nothing|" style="filled" fillcolor=gray]; 14 [label="Access variable R|<local>/firstCalls|"];
15 [label="Access variable R|<local>/firstCalls|" style="filled" fillcolor=gray]; 15 [label="Jump: ^foo R|<local>/firstCalls|"];
16 [label="Stub" style="filled" fillcolor=gray]; 16 [label="Stub" style="filled" fillcolor=gray];
17 [label="Jump: ^foo R|<local>/firstCalls|" style="filled" fillcolor=gray]; 17 [label="Exit block" style="filled" fillcolor=gray];
18 [label="Stub" style="filled" fillcolor=gray];
19 [label="Exit block" style="filled" fillcolor=gray];
} }
20 [label="Exit function foo" style="filled" fillcolor=red]; 18 [label="Exit function foo" style="filled" fillcolor=red];
} }
4 -> {5}; 4 -> {5};
5 -> {6}; 5 -> {6};
6 -> {7}; 6 -> {7};
7 -> {8}; 7 -> {8};
8 -> {9}; 8 -> {9};
9 -> {21}; 9 -> {19};
9 -> {11} [color=red]; 9 -> {11} [color=red];
10 -> {12} [color=red]; 10 -> {12} [color=red];
11 -> {12} [color=green]; 11 -> {12} [color=green];
12 -> {20}; 12 -> {13};
12 -> {13} [style=dotted]; 13 -> {14};
13 -> {14} [style=dotted]; 14 -> {15};
14 -> {15} [style=dotted]; 15 -> {18};
15 -> {20 16} [style=dotted]; 15 -> {16} [style=dotted];
16 -> {17} [style=dotted]; 16 -> {17} [style=dotted];
17 -> {20 18} [style=dotted]; 17 -> {18} [style=dotted];
18 -> {19} [style=dotted]; 19 -> {20};
19 -> {20} [style=dotted]; 20 -> {21};
21 -> {22}; 21 -> {26};
21 -> {22} [color=red];
22 -> {23}; 22 -> {23};
23 -> {28}; 23 -> {24};
23 -> {24} [color=red];
24 -> {25}; 24 -> {25};
25 -> {26}; 25 -> {10} [color=red];
25 -> {11} [color=green];
26 -> {27}; 26 -> {27};
27 -> {10} [color=red]; 27 -> {28};
27 -> {11} [color=green];
28 -> {29}; 28 -> {29};
29 -> {30}; 29 -> {30};
30 -> {31}; 30 -> {31};
31 -> {32}; 31 -> {32};
32 -> {33}; 32 -> {33};
33 -> {34}; 33 -> {39};
34 -> {35}; 33 -> {35} [color=red];
35 -> {41}; 34 -> {36} [color=red];
35 -> {37} [color=red]; 35 -> {36} [color=green];
36 -> {38} [color=red]; 36 -> {37};
37 -> {38} [color=green]; 37 -> {38};
38 -> {39}; 38 -> {22} [color=green];
39 -> {40}; 39 -> {40};
40 -> {10} [color=red]; 40 -> {41};
40 -> {24} [color=green];
41 -> {42}; 41 -> {42};
42 -> {43}; 42 -> {43};
43 -> {44}; 43 -> {44};
44 -> {45}; 44 -> {45};
45 -> {46}; 45 -> {46};
46 -> {47}; 46 -> {47};
47 -> {48}; 47 -> {34} [color=red];
48 -> {49}; 47 -> {35} [color=green];
49 -> {36} [color=red];
49 -> {37} [color=green];
} }
@@ -4,8 +4,8 @@ FILE: complexPostponedCfg.kt
public abstract interface FirFunctionCall : R|FirBase| { public abstract interface FirFunctionCall : R|FirBase| {
} }
public final fun foo(statements: R|kotlin/collections/List<FirBase>|, arguments: R|kotlin/collections/List<FirBase>|, explicitReceiver: R|FirBase|): R|kotlin/collections/List<FirFunctionCall>| { public final fun foo(statements: R|kotlin/collections/List<FirBase>|, arguments: R|kotlin/collections/List<FirBase>|, explicitReceiver: R|FirBase|): R|kotlin/collections/List<FirFunctionCall>| {
lval firstCalls: R|kotlin/Nothing| = R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Nothing|>((R|<local>/statements|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = setCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/Nothing| <kind=EXACTLY_ONCE> { lval firstCalls: R|kotlin/collections/List<FirFunctionCall>| = R|kotlin/with|<R|FirFunctionCall|, R|kotlin/collections/List<FirFunctionCall>|>((R|<local>/statements|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = setCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/collections/List<FirFunctionCall>| <kind=EXACTLY_ONCE> {
^ R|kotlin/collections/buildList|<R|kotlin/Any?|>(<L> = buildList@fun R|kotlin/collections/MutableList<kotlin/Any?>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> { ^ R|kotlin/collections/buildList|<R|FirFunctionCall|>(<L> = buildList@fun R|kotlin/collections/MutableList<FirFunctionCall>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|)
^ R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Boolean|>((R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = plusCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/Boolean| <kind=EXACTLY_ONCE> { ^ R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Boolean|>((R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = plusCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|)
@@ -0,0 +1,19 @@
fun test_1() {
val list = buildList {
add("")
}
takeList(list)
}
fun test_2() {
val list = myBuildList {
add("")
}
takeList(list)
}
fun <E> myBuildList(@BuilderInference builderAction: MutableList<E>.() -> Unit): List<E> {
return ArrayList<E>().apply(builderAction)
}
fun takeList(list: List<String>) {}
@@ -0,0 +1,20 @@
FILE: builderInferenceFromStdlib.kt
public final fun test_1(): R|kotlin/Unit| {
lval list: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/buildList|<R|kotlin/String|>(<L> = buildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
}
)
R|/takeList|(R|<local>/list|)
}
public final fun test_2(): R|kotlin/Unit| {
lval list: R|kotlin/collections/List<kotlin/String>| = R|/myBuildList|<R|kotlin/String|>(<L> = myBuildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
}
)
R|/takeList|(R|<local>/list|)
}
public final fun <E> myBuildList(@R|kotlin/BuilderInference|() builderAction: R|kotlin/collections/MutableList<E>.() -> kotlin/Unit|): R|kotlin/collections/List<E>| {
^myBuildList R|java/util/ArrayList.ArrayList|<R|E|>().R|kotlin/apply|<R|java/util/ArrayList<E>|>(R|<local>/builderAction|)
}
public final fun takeList(list: R|kotlin/collections/List<kotlin/String>|): R|kotlin/Unit| {
}
@@ -692,6 +692,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.kt"); runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.kt");
} }
@TestMetadata("builderInferenceFromStdlib.kt")
public void testBuilderInferenceFromStdlib() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInferenceFromStdlib.kt");
}
@TestMetadata("complexConstraintSystem.kt") @TestMetadata("complexConstraintSystem.kt")
public void testComplexConstraintSystem() throws Exception { public void testComplexConstraintSystem() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/complexConstraintSystem.kt"); runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/complexConstraintSystem.kt");
@@ -17,11 +17,13 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolver import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.TypeTable import org.jetbrains.kotlin.metadata.deserialization.TypeTable
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
import org.jetbrains.kotlin.metadata.deserialization.hasReceiver
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
class JvmBinaryAnnotationDeserializer( class JvmBinaryAnnotationDeserializer(
@@ -33,12 +35,6 @@ class JvmBinaryAnnotationDeserializer(
session.loadMemberAnnotations(kotlinBinaryClass, byteContent) session.loadMemberAnnotations(kotlinBinaryClass, byteContent)
} }
private enum class CallableKind {
PROPERTY_GETTER,
PROPERTY_SETTER,
OTHERS
}
override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List<FirAnnotationCall> { override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List<FirAnnotationCall> {
val annotations = typeProto.getExtension(JvmProtoBuf.typeAnnotation).orEmpty() val annotations = typeProto.getExtension(JvmProtoBuf.typeAnnotation).orEmpty()
return annotations.map { deserializeAnnotation(it, nameResolver) } return annotations.map { deserializeAnnotation(it, nameResolver) }
@@ -86,6 +82,36 @@ class JvmBinaryAnnotationDeserializer(
return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, signature) return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, signature)
} }
override fun loadValueParameterAnnotations(
containerSource: DeserializedContainerSource?,
callableProto: MessageLite,
valueParameterProto: ProtoBuf.ValueParameter,
nameResolver: NameResolver,
typeTable: TypeTable,
kind: CallableKind,
parameterIndex: Int,
): List<FirAnnotationCall> {
val methodSignature = getCallableSignature(callableProto, nameResolver, typeTable, kind) ?: return emptyList()
val index = parameterIndex + computeJvmParameterIndexShift(callableProto)
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index)
return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, paramSignature)
}
/*
* TODO: Support container proto and fix index shift for
* constructors of inner classes and enums
*
* See [AbstractBinaryClassAnnotationAndConstantLoader]
*/
private fun computeJvmParameterIndexShift(message: MessageLite): Int {
return when (message) {
is ProtoBuf.Function -> if (message.hasReceiver()) 1 else 0
is ProtoBuf.Property -> if (message.hasReceiver()) 1 else 0
is ProtoBuf.Constructor -> 0
else -> throw UnsupportedOperationException("Unsupported message: ${message::class.java}")
}
}
private fun getCallableSignature( private fun getCallableSignature(
proto: MessageLite, proto: MessageLite,
nameResolver: NameResolver, nameResolver: NameResolver,
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.metadata.ProtoBuf.Annotation.Argument.Value.Type.*
import org.jetbrains.kotlin.metadata.deserialization.Flags import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.NameResolver import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.TypeTable import org.jetbrains.kotlin.metadata.deserialization.TypeTable
import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getClassId
@@ -40,6 +42,12 @@ abstract class AbstractAnnotationDeserializer(
) { ) {
protected val protocol = BuiltInSerializerProtocol protected val protocol = BuiltInSerializerProtocol
enum class CallableKind {
PROPERTY_GETTER,
PROPERTY_SETTER,
OTHERS
}
fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<FirAnnotationCall> { fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<FirAnnotationCall> {
if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) return emptyList() if (!Flags.HAS_ANNOTATIONS.get(classProto.flags)) return emptyList()
val annotations = classProto.getExtension(protocol.classAnnotation).orEmpty() val annotations = classProto.getExtension(protocol.classAnnotation).orEmpty()
@@ -98,7 +106,15 @@ abstract class AbstractAnnotationDeserializer(
return annotations.map { deserializeAnnotation(it, nameResolver) } return annotations.map { deserializeAnnotation(it, nameResolver) }
} }
fun loadValueParameterAnnotations(valueParameterProto: ProtoBuf.ValueParameter, nameResolver: NameResolver): List<FirAnnotationCall> { open fun loadValueParameterAnnotations(
containerSource: DeserializedContainerSource?,
callableProto: MessageLite,
valueParameterProto: ProtoBuf.ValueParameter,
nameResolver: NameResolver,
typeTable: TypeTable,
kind: CallableKind,
parameterIndex: Int
): List<FirAnnotationCall> {
if (!Flags.HAS_ANNOTATIONS.get(valueParameterProto.flags)) return emptyList() if (!Flags.HAS_ANNOTATIONS.get(valueParameterProto.flags)) return emptyList()
val annotations = valueParameterProto.getExtension(protocol.parameterAnnotation).orEmpty() val annotations = valueParameterProto.getExtension(protocol.parameterAnnotation).orEmpty()
return annotations.map { deserializeAnnotation(it, nameResolver) } return annotations.map { deserializeAnnotation(it, nameResolver) }
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@@ -323,7 +324,11 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
this.symbol = symbol this.symbol = symbol
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList) valueParameters += local.memberDeserializer.valueParameters(
proto.valueParameterList,
proto,
AbstractAnnotationDeserializer.CallableKind.OTHERS
)
annotations += annotations +=
c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
this.containerSource = c.containerSource this.containerSource = c.containerSource
@@ -373,7 +378,10 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
typeParameters.filterIsInstance<FirTypeParameter>() typeParameters.filterIsInstance<FirTypeParameter>()
.map { buildConstructedClassTypeParameterRef { this.symbol = it.symbol } } .map { buildConstructedClassTypeParameterRef { this.symbol = it.symbol } }
valueParameters += local.memberDeserializer.valueParameters( valueParameters += local.memberDeserializer.valueParameters(
proto.valueParameterList, addDefaultValue = classBuilder.symbol.classId == StandardClassIds.Enum proto.valueParameterList,
proto,
AbstractAnnotationDeserializer.CallableKind.OTHERS,
addDefaultValue = classBuilder.symbol.classId == StandardClassIds.Enum
) )
annotations += annotations +=
c.annotationDeserializer.loadConstructorAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) c.annotationDeserializer.loadConstructorAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
@@ -389,9 +397,11 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
private fun valueParameters( private fun valueParameters(
valueParameters: List<ProtoBuf.ValueParameter>, valueParameters: List<ProtoBuf.ValueParameter>,
callableProto: MessageLite,
callableKind: AbstractAnnotationDeserializer.CallableKind,
addDefaultValue: Boolean = false addDefaultValue: Boolean = false
): List<FirValueParameter> { ): List<FirValueParameter> {
return valueParameters.map { proto -> return valueParameters.mapIndexed { index, proto ->
val flags = if (proto.hasFlags()) proto.flags else 0 val flags = if (proto.hasFlags()) proto.flags else 0
val name = c.nameResolver.getName(proto.name) val name = c.nameResolver.getName(proto.name)
buildValueParameter { buildValueParameter {
@@ -407,7 +417,15 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
isCrossinline = Flags.IS_CROSSINLINE.get(flags) isCrossinline = Flags.IS_CROSSINLINE.get(flags)
isNoinline = Flags.IS_NOINLINE.get(flags) isNoinline = Flags.IS_NOINLINE.get(flags)
isVararg = proto.varargElementType(c.typeTable) != null isVararg = proto.varargElementType(c.typeTable) != null
annotations += c.annotationDeserializer.loadValueParameterAnnotations(proto, c.nameResolver) annotations += c.annotationDeserializer.loadValueParameterAnnotations(
c.containerSource,
callableProto,
proto,
c.nameResolver,
c.typeTable,
callableKind,
index,
)
} }
}.toList() }.toList()
} }
@@ -1,7 +1,6 @@
// WITH_RUNTIME // WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME // KJS_WITH_FULL_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// IGNORE_BACKEND_FIR: JVM_IR
import helpers.* import helpers.*
import kotlin.coroutines.* import kotlin.coroutines.*
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME // KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
-1
View File
@@ -1,5 +1,4 @@
// !LANGUAGE: +NewInference // !LANGUAGE: +NewInference
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME // KJS_WITH_FULL_RUNTIME
// FULL_JDK // FULL_JDK
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME // KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
@@ -1,5 +1,5 @@
val foo = iterator { val foo = iterator {
<!INAPPLICABLE_CANDIDATE!>yield<!>(0) yield(0)
val nullable: String? = null val nullable: String? = null
nullable.<!INAPPLICABLE_CANDIDATE!>length<!> nullable.<!INAPPLICABLE_CANDIDATE!>length<!>
nullable.<!INAPPLICABLE_CANDIDATE!>get<!>(2) nullable.<!INAPPLICABLE_CANDIDATE!>get<!>(2)