mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-21 00:21:29 +00:00
Compare commits
145 Commits
get-script
...
rr/ilmir/i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8c0a81da7 | ||
|
|
481a3878bd | ||
|
|
516fce37db | ||
|
|
a9c072f826 | ||
|
|
caea0a9df0 | ||
|
|
c776fcbd00 | ||
|
|
fae5b8da4b | ||
|
|
e5c46a86aa | ||
|
|
daf42c1ee6 | ||
|
|
984b3c2f30 | ||
|
|
68f8e88d8b | ||
|
|
dce3d4d1b7 | ||
|
|
b0ff3e7e5e | ||
|
|
9d749feb64 | ||
|
|
d25ad269e0 | ||
|
|
9f58e4bcfe | ||
|
|
1ccbb09029 | ||
|
|
8e5bcd349e | ||
|
|
6b649d02d3 | ||
|
|
8ce2e4654b | ||
|
|
e6a3e38c4d | ||
|
|
11673bd09c | ||
|
|
08a2b47c77 | ||
|
|
0522583602 | ||
|
|
05e47da458 | ||
|
|
c7e5beece5 | ||
|
|
d512158c25 | ||
|
|
a917ebd11e | ||
|
|
c7c793c724 | ||
|
|
d41d1bf64d | ||
|
|
be03bc477d | ||
|
|
988cc52174 | ||
|
|
697b2b02f1 | ||
|
|
6cb573cb45 | ||
|
|
4d7b6c022b | ||
|
|
842d31d04e | ||
|
|
7cbcde77dd | ||
|
|
a7d7aa123e | ||
|
|
a1603716ed | ||
|
|
5630667320 | ||
|
|
56c3faee00 | ||
|
|
18e5af37ff | ||
|
|
535aa1e9e0 | ||
|
|
229c6f97ac | ||
|
|
aff90b335c | ||
|
|
6aff96a401 | ||
|
|
3fc424246b | ||
|
|
2a8f783393 | ||
|
|
4c69043a15 | ||
|
|
3e3ec5fc69 | ||
|
|
fdaf31dbf3 | ||
|
|
aae0081f3f | ||
|
|
2429f429c5 | ||
|
|
eae8821dec | ||
|
|
2ffedd2731 | ||
|
|
8a969dab7d | ||
|
|
b23d7a79b0 | ||
|
|
c0cd9064d7 | ||
|
|
14b773c1fd | ||
|
|
f0a787551a | ||
|
|
129de76288 | ||
|
|
ae8abd1832 | ||
|
|
1412ee96f8 | ||
|
|
e96fc74ffa | ||
|
|
2b4564059e | ||
|
|
85b5948931 | ||
|
|
4c3ffc3451 | ||
|
|
b0e2d5637d | ||
|
|
bb4950a021 | ||
|
|
91bccad72b | ||
|
|
7550a1870b | ||
|
|
b179b567a9 | ||
|
|
2fdc2dfaaf | ||
|
|
4607eca987 | ||
|
|
f50480d258 | ||
|
|
94a5379631 | ||
|
|
19ca9c0fde | ||
|
|
606de26646 | ||
|
|
50ae360ff9 | ||
|
|
4817d5e01d | ||
|
|
995d96e5a3 | ||
|
|
67e4b0948e | ||
|
|
ac42dcd8da | ||
|
|
e7789d2e30 | ||
|
|
96ed99d62e | ||
|
|
b2aed536c9 | ||
|
|
3b604cfa7f | ||
|
|
a157b58c61 | ||
|
|
c43db2ee8d | ||
|
|
7d9eeb6847 | ||
|
|
e1d54bf99f | ||
|
|
ad579de328 | ||
|
|
d706a7ff74 | ||
|
|
1cccf2645f | ||
|
|
04d9afe83e | ||
|
|
feb13f98c0 | ||
|
|
9b30655d66 | ||
|
|
e6f380182a | ||
|
|
f8b6559b6a | ||
|
|
dba14ba995 | ||
|
|
e127ea3dad | ||
|
|
8a00470b40 | ||
|
|
29bed39a54 | ||
|
|
37ee2cbe53 | ||
|
|
d6f54a7730 | ||
|
|
f3424a98b7 | ||
|
|
e39560b134 | ||
|
|
0634351fbc | ||
|
|
84f5a294f7 | ||
|
|
64d85f259c | ||
|
|
2ee8bf7dde | ||
|
|
f668e906cc | ||
|
|
e7d305b97a | ||
|
|
78c786de46 | ||
|
|
33b545aea7 | ||
|
|
85c59328c7 | ||
|
|
3d33ea7da8 | ||
|
|
124888eb43 | ||
|
|
e251a9be14 | ||
|
|
cc1a0bf6d7 | ||
|
|
17e6e88176 | ||
|
|
406e863a73 | ||
|
|
dc364b8be4 | ||
|
|
95e5ea4840 | ||
|
|
02f71a63b8 | ||
|
|
bf1abed246 | ||
|
|
ad953b6285 | ||
|
|
986ab9cb54 | ||
|
|
1b559fe676 | ||
|
|
7396abf5a4 | ||
|
|
5ab9710cc5 | ||
|
|
d3ef0eb519 | ||
|
|
68719831ee | ||
|
|
dc35a13008 | ||
|
|
46fcc7d59d | ||
|
|
48cbb74a01 | ||
|
|
d887814cc5 | ||
|
|
4779092ba5 | ||
|
|
2a053c214d | ||
|
|
d50d56f68c | ||
|
|
e4e28a5495 | ||
|
|
07dd9179e8 | ||
|
|
eeb9b3214c | ||
|
|
89bba93615 | ||
|
|
65ce7cd0c2 |
11
.bunch
11
.bunch
@@ -1,7 +1,6 @@
|
||||
201
|
||||
202
|
||||
203_202
|
||||
193
|
||||
as40_193
|
||||
as41
|
||||
as42_202
|
||||
201
|
||||
193_201
|
||||
as40_193_201
|
||||
as41_201
|
||||
as42
|
||||
@@ -188,7 +188,7 @@ extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.4.30-dev-17200"
|
||||
extra["versions.kotlin-native"] = "1.4.30-dev-17395"
|
||||
}
|
||||
|
||||
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
|
||||
@@ -854,6 +854,7 @@ tasks {
|
||||
|
||||
register("kaptIdeTest") {
|
||||
dependsOn(":kotlin-annotation-processing:test")
|
||||
dependsOn(":kotlin-annotation-processing-base:test")
|
||||
}
|
||||
|
||||
register("gradleIdeTest") {
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||
@@ -55,6 +56,13 @@ class ErasedInlineClassBodyCodegen(
|
||||
generateUnboxMethod()
|
||||
generateFunctionsFromAny()
|
||||
generateSpecializedEqualsStub()
|
||||
generateJvmInlineAnnotation()
|
||||
}
|
||||
|
||||
private fun generateJvmInlineAnnotation() {
|
||||
if (descriptor.isInline) {
|
||||
v.newAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME.topLevelClassAsmType().descriptor, true).visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateFunctionsFromAny() {
|
||||
|
||||
@@ -136,9 +136,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
) {
|
||||
var nodeAndSmap: SMAPAndMethodNode? = null
|
||||
try {
|
||||
nodeAndSmap = createInlineMethodNode(
|
||||
functionDescriptor, methodOwner, jvmSignature, mapDefaultSignature, typeArguments, typeSystem, state, sourceCompiler
|
||||
)
|
||||
nodeAndSmap = createInlineMethodNode(mapDefaultSignature, typeArguments, typeSystem)
|
||||
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards)
|
||||
} catch (e: CompilationException) {
|
||||
throw e
|
||||
@@ -274,6 +272,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
|
||||
abstract fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda>
|
||||
|
||||
abstract fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean
|
||||
|
||||
fun generateAndInsertFinallyBlocks(
|
||||
intoNode: MethodNode,
|
||||
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
||||
@@ -512,38 +512,33 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun createInlineMethodNode(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
methodOwner: Type,
|
||||
jvmSignature: JvmMethodSignature,
|
||||
callDefault: Boolean,
|
||||
typeArguments: List<TypeParameterMarker>?,
|
||||
typeSystem: TypeSystemCommonBackendContext,
|
||||
state: GenerationState,
|
||||
sourceCompilerForInline: SourceCompilerForInline
|
||||
): SMAPAndMethodNode {
|
||||
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem)
|
||||
if (intrinsic != null) {
|
||||
return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP())
|
||||
}
|
||||
|
||||
val asmMethod = if (callDefault)
|
||||
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompilerForInline.contextKind)
|
||||
else
|
||||
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
|
||||
|
||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) {
|
||||
val node = sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
|
||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||
return node
|
||||
}
|
||||
|
||||
return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature)
|
||||
internal fun createInlineMethodNode(
|
||||
callDefault: Boolean,
|
||||
typeArguments: List<TypeParameterMarker>?,
|
||||
typeSystem: TypeSystemCommonBackendContext
|
||||
): SMAPAndMethodNode {
|
||||
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem)
|
||||
if (intrinsic != null) {
|
||||
return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP())
|
||||
}
|
||||
|
||||
val asmMethod = if (callDefault)
|
||||
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompiler.contextKind)
|
||||
else
|
||||
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
|
||||
|
||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !descriptorIsDeserialized(directMember)) {
|
||||
val node = sourceCompiler.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
|
||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||
return node
|
||||
}
|
||||
|
||||
return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun createSpecialInlineMethodNodeFromBinaries(functionDescriptor: FunctionDescriptor, state: GenerationState): MethodNode {
|
||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||
assert(directMember is DescriptorWithContainerSource) {
|
||||
@@ -577,7 +572,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
doCreateMethodNodeFromCompiled(directMember, state, jvmSignature.asmMethod)
|
||||
else
|
||||
null
|
||||
result ?: throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
|
||||
result ?:
|
||||
throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
|
||||
}
|
||||
|
||||
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.linkWithLabel
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
@@ -16,7 +15,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
class InlineCodegenForDefaultBody(
|
||||
@@ -41,8 +39,10 @@ class InlineCodegenForDefaultBody(
|
||||
}
|
||||
|
||||
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||
val nodeAndSmap = InlineCodegen.createInlineMethodNode(
|
||||
function, methodOwner, jvmSignature, callDefault, null, codegen.typeSystem, state, sourceCompilerForInline
|
||||
val nodeAndSmap = PsiInlineCodegen(
|
||||
codegen, state, function, methodOwner, jvmSignature, TypeParameterMappings(), sourceCompilerForInline
|
||||
).createInlineMethodNode(
|
||||
callDefault, null, codegen.typeSystem
|
||||
)
|
||||
val childSourceMapper = SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpres
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -208,4 +210,7 @@ class PsiInlineCodegen(
|
||||
::PsiDefaultLambda
|
||||
)
|
||||
}
|
||||
|
||||
override fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean =
|
||||
memberDescriptor is DescriptorWithContainerSource
|
||||
}
|
||||
|
||||
@@ -130,7 +130,9 @@ fun <T, R : DefaultLambda> expandMaskConditionsAndUpdateVariableNodes(
|
||||
node.instructions.insert(position, newInsn)
|
||||
}
|
||||
|
||||
node.localVariables.removeIf { it.start in toDelete && it.end in toDelete }
|
||||
node.localVariables.removeIf {
|
||||
(it.start in toDelete && it.end in toDelete) || defaultLambdas.contains(it.index)
|
||||
}
|
||||
|
||||
node.remove(toDelete)
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
|
||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
|
||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>
|
||||
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
|
||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>
|
||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
|
||||
@@ -5,4 +5,4 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.state
|
||||
|
||||
typealias JvmMethodExceptionTypes = Array<out String>?
|
||||
typealias JvmMethodExceptionTypes = Array<out String?>?
|
||||
@@ -5,4 +5,4 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.state
|
||||
|
||||
typealias JvmMethodExceptionTypes = Array<out String?>?
|
||||
typealias JvmMethodExceptionTypes = Array<out String>?
|
||||
@@ -0,0 +1,10 @@
|
||||
<idea-plugin>
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
<version>1.2</version>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="com.intellij.psi.classFileDecompiler"
|
||||
interface="com.intellij.psi.compiled.ClassFileDecompilers$Decompiler"
|
||||
dynamic="true"/>
|
||||
</extensionPoints>
|
||||
</idea-plugin>
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.cli.common.messages
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
|
||||
/**
|
||||
* This class behaviour is the same as [MessageCollector.report] in [AnalyzerWithCompilerReport.reportDiagnostic].
|
||||
*/
|
||||
class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter
|
||||
|
||||
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
|
||||
val messageCollector: MessageCollector
|
||||
|
||||
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
|
||||
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
|
||||
render,
|
||||
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
|
||||
)
|
||||
}
|
||||
@@ -17,8 +17,6 @@
|
||||
package org.jetbrains.kotlin.cli.common.messages;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarVirtualFile;
|
||||
import com.intellij.openapi.vfs.local.CoreLocalVirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -53,10 +51,6 @@ public class MessageUtil {
|
||||
|
||||
@NotNull
|
||||
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
|
||||
// Convert path to platform-dependent format when virtualFile is local file.
|
||||
if (virtualFile instanceof CoreLocalVirtualFile || virtualFile instanceof CoreJarVirtualFile) {
|
||||
return toSystemDependentName(virtualFile.getPath());
|
||||
}
|
||||
return virtualFile.getPath();
|
||||
return toSystemDependentName(virtualFile.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.cli.common.messages;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
||||
|
||||
import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
|
||||
|
||||
public class MessageUtil {
|
||||
private MessageUtil() {}
|
||||
|
||||
@Nullable
|
||||
public static CompilerMessageLocation psiElementToMessageLocation(@Nullable PsiElement element) {
|
||||
if (element == null) return null;
|
||||
PsiFile file = element.getContainingFile();
|
||||
return psiFileToMessageLocation(file, "<no path>", DiagnosticUtils.getLineAndColumnInPsiFile(file, element.getTextRange()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CompilerMessageLocation psiFileToMessageLocation(
|
||||
@NotNull PsiFile file,
|
||||
@Nullable String defaultValue,
|
||||
@NotNull PsiDiagnosticUtils.LineAndColumn lineAndColumn
|
||||
) {
|
||||
VirtualFile virtualFile = file.getVirtualFile();
|
||||
String path = virtualFile != null ? virtualFileToPath(virtualFile) : defaultValue;
|
||||
return CompilerMessageLocation.create(path, lineAndColumn.getLine(), lineAndColumn.getColumn(), lineAndColumn.getLineContent());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
|
||||
return toSystemDependentName(virtualFile.getPath());
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,6 @@ public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnviron
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
registerApplicationExtensionPoint(ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
@@ -52,4 +51,4 @@ public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnviron
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.DynamicBundle;
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.FileContextProvider;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
registerExtensionPoints();
|
||||
return environment;
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private static void registerExtensionPoints() {
|
||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
registerApplicationExtensionPoint(ClassFileDecompilers.getInstance().EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.DynamicBundle;
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.FileContextProvider;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
registerExtensionPoints();
|
||||
return environment;
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private static void registerExtensionPoints() {
|
||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -509,6 +509,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, unitTestMode)
|
||||
|
||||
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
|
||||
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/core.xml")
|
||||
|
||||
registerApplicationServicesForCLI(applicationEnvironment)
|
||||
registerApplicationServices(applicationEnvironment)
|
||||
@@ -692,4 +693,4 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,4 +686,4 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,6 @@ fun setupIdeaStandaloneExecution() {
|
||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||
System.getProperties().setProperty("ast.loading.filter", "false")
|
||||
System.getProperties().setProperty("idea.ignore.disabled.plugins", "true")
|
||||
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
|
||||
}
|
||||
@@ -12,6 +12,4 @@ fun setupIdeaStandaloneExecution() {
|
||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||
System.getProperties().setProperty("ast.loading.filter", "false")
|
||||
System.getProperties().setProperty("idea.ignore.disabled.plugins", "true")
|
||||
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public final class Test : R|kotlin/Any| {
|
||||
|
||||
}
|
||||
|
||||
public final inline class Z : R|kotlin/Any| {
|
||||
@R|kotlin/jvm/JvmInline|() public final inline class Z : R|kotlin/Any| {
|
||||
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
||||
|
||||
public open fun hashCode(): R|kotlin/Int|
|
||||
@@ -41,3 +41,4 @@ public final inline class Z : R|kotlin/Any| {
|
||||
public constructor(x: R|kotlin/Int|): R|test/Z|
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public final inline class Z : R|kotlin/Any| {
|
||||
@R|kotlin/jvm/JvmInline|() public final inline class Z : R|kotlin/Any| {
|
||||
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
||||
|
||||
public open fun hashCode(): R|kotlin/Int|
|
||||
@@ -11,3 +11,4 @@ public final inline class Z : R|kotlin/Any| {
|
||||
@R|kotlin/PublishedApi|() internal constructor(value: R|kotlin/Int|): R|test/Z|
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,6 @@ public final const val s: R|kotlin/Short| = Short(20000)
|
||||
public final const val s1: R|kotlin/Short| = Short(1)
|
||||
public get(): R|kotlin/Short|
|
||||
|
||||
public final const val str: R|kotlin/String|
|
||||
public final const val str: R|kotlin/String| = String(:))
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
|
||||
44
compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt
vendored
Normal file
44
compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
interface CommonBackendContext
|
||||
|
||||
interface PhaserState<Data> {
|
||||
var depth: Int
|
||||
}
|
||||
|
||||
interface PhaseConfig {
|
||||
val needProfiling: Boolean
|
||||
}
|
||||
|
||||
inline fun <R, D> PhaserState<D>.downlevel(nlevels: Int, block: () -> R): R {
|
||||
depth += nlevels
|
||||
val result = block()
|
||||
depth -= nlevels
|
||||
return result
|
||||
}
|
||||
|
||||
interface CompilerPhase<in Context : CommonBackendContext, Input, Output> {
|
||||
fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Input>, context: Context, input: Input): Output
|
||||
}
|
||||
|
||||
class NamedCompilerPhase<in Context : CommonBackendContext, Data>(
|
||||
private val lower: CompilerPhase<Context, Data, Data>
|
||||
) : CompilerPhase<Context, Data, Data> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, input: Data): Data {
|
||||
// Expected: output: Data, Actual: output: Data?
|
||||
val output = if (phaseConfig.needProfiling) {
|
||||
runAndProfile(phaseConfig, phaserState, context, input)
|
||||
} else {
|
||||
phaserState.downlevel(1) {
|
||||
lower.invoke(phaseConfig, phaserState, context, input)
|
||||
}
|
||||
}
|
||||
runAfter(phaseConfig, phaserState, context, output)
|
||||
}
|
||||
|
||||
private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, output: Data) {
|
||||
|
||||
}
|
||||
|
||||
private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, source: Data): Data {
|
||||
|
||||
}
|
||||
}
|
||||
55
compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.txt
vendored
Normal file
55
compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.txt
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
FILE: compilerPhase.kt
|
||||
public abstract interface CommonBackendContext : R|kotlin/Any| {
|
||||
}
|
||||
public abstract interface PhaserState<Data> : R|kotlin/Any| {
|
||||
public abstract var depth: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface PhaseConfig : R|kotlin/Any| {
|
||||
public abstract val needProfiling: R|kotlin/Boolean|
|
||||
public get(): R|kotlin/Boolean|
|
||||
|
||||
}
|
||||
public final inline fun <R, D> R|PhaserState<D>|.downlevel(nlevels: R|kotlin/Int|, block: R|() -> R|): R|R| {
|
||||
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.plus|(R|<local>/nlevels|)
|
||||
lval result: R|R| = R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()
|
||||
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.minus|(R|<local>/nlevels|)
|
||||
^downlevel R|<local>/result|
|
||||
}
|
||||
public abstract interface CompilerPhase<in Context : R|CommonBackendContext|, Input, Output> : R|kotlin/Any| {
|
||||
public abstract fun invoke(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Input>|, context: R|Context|, input: R|Input|): R|Output|
|
||||
|
||||
}
|
||||
public final class NamedCompilerPhase<in Context : R|CommonBackendContext|, Data> : R|CompilerPhase<Context, Data, Data>| {
|
||||
public constructor<in Context : R|CommonBackendContext|, Data>(lower: R|CompilerPhase<Context, Data, Data>|): R|NamedCompilerPhase<Context, Data>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
private final val lower: R|CompilerPhase<Context, Data, Data>| = R|<local>/lower|
|
||||
private get(): R|CompilerPhase<Context, Data, Data>|
|
||||
|
||||
public final override fun invoke(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, input: R|Data|): R|Data| {
|
||||
lval output: R|Data| = when () {
|
||||
R|<local>/phaseConfig|.R|/PhaseConfig.needProfiling| -> {
|
||||
this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.runAndProfile|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/input|)
|
||||
}
|
||||
else -> {
|
||||
R|<local>/phaserState|.R|/downlevel|<R|Data|, R|Data|>(Int(1), <L> = downlevel@fun <anonymous>(): R|Data| <kind=UNKNOWN> {
|
||||
^ this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.lower|.R|SubstitutionOverride</CompilerPhase.invoke: R|Data|>|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/input|)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.runAfter|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/output|)
|
||||
}
|
||||
|
||||
private final fun runAfter(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, output: R|Data|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
private final fun runAndProfile(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, source: R|Data|): R|Data| {
|
||||
}
|
||||
|
||||
}
|
||||
20
compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt
vendored
Normal file
20
compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// FILE: AliasFor.java
|
||||
|
||||
public @interface AliasFor {
|
||||
@AliasFor(value = "attribute")
|
||||
String value() default "";
|
||||
|
||||
@AliasFor(value = "value")
|
||||
String attribute() default "";
|
||||
}
|
||||
|
||||
// FILE: Service.java
|
||||
public @interface Service {
|
||||
@AliasFor(value = "component")
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
// FILE: Annotated.kt
|
||||
|
||||
@Service(value = "Your")
|
||||
class My
|
||||
7
compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.txt
vendored
Normal file
7
compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.txt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FILE: Annotated.kt
|
||||
@R|Service|(value = String(Your)) public final class My : R|kotlin/Any| {
|
||||
public constructor(): R|My| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2024,6 +2024,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compilerPhase.kt")
|
||||
public void testCompilerPhase() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("complexLambdaWithTypeVariableAsExpectedType.kt")
|
||||
public void testComplexLambdaWithTypeVariableAsExpectedType() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/complexLambdaWithTypeVariableAsExpectedType.kt");
|
||||
@@ -2079,6 +2084,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/questionableSmartCast.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveNamedAnnotation.kt")
|
||||
public void testRecursiveNamedAnnotation() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeCallInvoke.kt")
|
||||
public void testSafeCallInvoke() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/safeCallInvoke.kt");
|
||||
|
||||
@@ -2024,6 +2024,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compilerPhase.kt")
|
||||
public void testCompilerPhase() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("complexLambdaWithTypeVariableAsExpectedType.kt")
|
||||
public void testComplexLambdaWithTypeVariableAsExpectedType() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/complexLambdaWithTypeVariableAsExpectedType.kt");
|
||||
@@ -2079,6 +2084,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/questionableSmartCast.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveNamedAnnotation.kt")
|
||||
public void testRecursiveNamedAnnotation() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeCallInvoke.kt")
|
||||
public void testSafeCallInvoke() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/safeCallInvoke.kt");
|
||||
|
||||
@@ -10659,6 +10659,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedFlexibleIntersectionTypesWithDifferentBounds.kt")
|
||||
public void testCapturedFlexibleIntersectionTypesWithDifferentBounds() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedFlexibleIntersectionTypesWithDifferentBounds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedFlexibleIntersectionTypesWithDifferentConstructors.kt")
|
||||
public void testCapturedFlexibleIntersectionTypesWithDifferentConstructors() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedFlexibleIntersectionTypesWithDifferentConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedType.kt")
|
||||
public void testCapturedType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedType.kt");
|
||||
@@ -12907,6 +12917,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inlineClasses/inlineClassesInsideAnnotations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("innerClassInsideInlineClass.kt")
|
||||
public void testInnerClassInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inlineClasses/innerClassInsideInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lateinitInlineClasses.kt")
|
||||
public void testLateinitInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inlineClasses/lateinitInlineClasses.kt");
|
||||
|
||||
@@ -2024,6 +2024,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compilerPhase.kt")
|
||||
public void testCompilerPhase() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/compilerPhase.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("complexLambdaWithTypeVariableAsExpectedType.kt")
|
||||
public void testComplexLambdaWithTypeVariableAsExpectedType() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/complexLambdaWithTypeVariableAsExpectedType.kt");
|
||||
@@ -2079,6 +2084,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/questionableSmartCast.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveNamedAnnotation.kt")
|
||||
public void testRecursiveNamedAnnotation() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/recursiveNamedAnnotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeCallInvoke.kt")
|
||||
public void testSafeCallInvoke() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/safeCallInvoke.kt");
|
||||
|
||||
@@ -20,24 +20,21 @@ import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerial
|
||||
|
||||
class FirConstDeserializer(
|
||||
val session: FirSession,
|
||||
private val partSource: KotlinJvmBinaryClass? = null,
|
||||
private val facadeSource: KotlinJvmBinaryClass? = null
|
||||
private val binaryClass: KotlinJvmBinaryClass? = null
|
||||
) {
|
||||
companion object {
|
||||
private val constantCache = mutableMapOf<CallableId, FirExpression>()
|
||||
}
|
||||
private val constantCache = mutableMapOf<CallableId, FirExpression>()
|
||||
|
||||
fun loadConstant(propertyProto: ProtoBuf.Property, callableId: CallableId, nameResolver: NameResolver): FirExpression? {
|
||||
if (!Flags.HAS_CONSTANT.get(propertyProto.flags)) return null
|
||||
|
||||
constantCache[callableId]?.let { return it }
|
||||
|
||||
if (facadeSource == null && partSource == null) {
|
||||
if (binaryClass == null) {
|
||||
val value = propertyProto.getExtensionOrNull(BuiltInSerializerProtocol.compileTimeValue) ?: return null
|
||||
return buildFirConstant(value, null, value.type.name, nameResolver)?.apply { constantCache[callableId] = this }
|
||||
}
|
||||
|
||||
(facadeSource ?: partSource)!!.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
||||
binaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
||||
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? = null
|
||||
|
||||
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
|
||||
@@ -60,11 +57,11 @@ class FirConstDeserializer(
|
||||
"CHAR", "C" -> buildConstExpression(null, FirConstKind.Char, ((protoValue?.intValue ?: sourceValue) as Number).toChar())
|
||||
"SHORT", "S" -> buildConstExpression(null, FirConstKind.Short, ((protoValue?.intValue ?: sourceValue) as Number).toShort())
|
||||
"INT", "I" -> buildConstExpression(null, FirConstKind.Int, protoValue?.intValue?.toInt() ?: sourceValue as Int)
|
||||
"LONG", "J" -> buildConstExpression(null, FirConstKind.Long, (protoValue?.intValue ?: sourceValue) as Long)
|
||||
"FLOAT", "F" -> buildConstExpression(null, FirConstKind.Float, (protoValue?.floatValue ?: sourceValue) as Float)
|
||||
"DOUBLE", "D" -> buildConstExpression(null, FirConstKind.Double, (protoValue?.doubleValue ?: sourceValue) as Double)
|
||||
"LONG", "J" -> buildConstExpression(null, FirConstKind.Long, protoValue?.intValue ?: sourceValue as Long)
|
||||
"FLOAT", "F" -> buildConstExpression(null, FirConstKind.Float, protoValue?.floatValue ?: sourceValue as Float)
|
||||
"DOUBLE", "D" -> buildConstExpression(null, FirConstKind.Double, protoValue?.doubleValue ?: sourceValue as Double)
|
||||
"BOOLEAN", "Z" -> buildConstExpression(null, FirConstKind.Boolean, (protoValue?.intValue?.toInt() ?: sourceValue) != 0)
|
||||
"STRING", "Ljava/lang/String" -> buildConstExpression(
|
||||
"STRING", "Ljava/lang/String;" -> buildConstExpression(
|
||||
null, FirConstKind.String, protoValue?.stringValue?.let { nameResolver.getString(it) } ?: sourceValue as String
|
||||
)
|
||||
else -> null
|
||||
|
||||
@@ -205,9 +205,6 @@ class FirElementSerializer private constructor(
|
||||
var hasGetter = false
|
||||
var hasSetter = false
|
||||
|
||||
//val compileTimeConstant = property.compileTimeInitializer
|
||||
val hasConstant = false // TODO: compileTimeConstant != null && compileTimeConstant !is NullValue
|
||||
|
||||
val hasAnnotations = property.nonSourceAnnotations(session).isNotEmpty()
|
||||
// TODO: hasAnnotations(descriptor) || hasAnnotations(descriptor.backingField) || hasAnnotations(descriptor.delegateField)
|
||||
|
||||
@@ -247,6 +244,7 @@ class FirElementSerializer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val hasConstant = property.isConst // TODO: this is only correct with LanguageFeature.NoConstantValueAttributeForNonConstVals
|
||||
val flags = Flags.getPropertyFlags(
|
||||
hasAnnotations,
|
||||
ProtoEnumFlags.visibility(normalizeVisibility(property)),
|
||||
|
||||
@@ -14,14 +14,14 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -86,8 +86,17 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
||||
typeContext.hasNothingInNonContravariantPosition(type)
|
||||
}
|
||||
|
||||
private fun FirClassLikeSymbol<*>.toRegularClassSymbol(): FirRegularClassSymbol? = when (this) {
|
||||
is FirRegularClassSymbol -> this
|
||||
is FirTypeAliasSymbol -> {
|
||||
val expandedType = fir.expandedTypeRef.coneType.fullyExpandedType(session) as? ConeClassLikeType
|
||||
expandedType?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun ConeClassLikeType.buildPossiblyInnerType(): PossiblyInnerConeType? =
|
||||
buildPossiblyInnerType(lookupTag.toSymbol(session) as? FirRegularClassSymbol?, 0)
|
||||
buildPossiblyInnerType(lookupTag.toSymbol(session)?.toRegularClassSymbol(), 0)
|
||||
|
||||
private fun ConeClassLikeType.parentClassOrNull(): FirRegularClassSymbol? {
|
||||
val parentClassId = classId?.outerClassId ?: return null
|
||||
|
||||
@@ -404,9 +404,7 @@ class Fir2IrDeclarationStorage(
|
||||
factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction
|
||||
): IrSimpleFunction {
|
||||
if (signature == null) {
|
||||
val descriptor =
|
||||
if (containerSource != null) WrappedFunctionDescriptorWithContainerSource()
|
||||
else WrappedSimpleFunctionDescriptor()
|
||||
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||
return symbolTable.declareSimpleFunction(descriptor, factory).apply { descriptor.bind(this) }
|
||||
}
|
||||
return symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature, containerSource) }, factory)
|
||||
@@ -687,9 +685,7 @@ class Fir2IrDeclarationStorage(
|
||||
factory: (IrPropertySymbol) -> IrProperty
|
||||
): IrProperty {
|
||||
if (signature == null) {
|
||||
val descriptor =
|
||||
if (containerSource != null) WrappedPropertyDescriptorWithContainerSource()
|
||||
else WrappedPropertyDescriptor()
|
||||
val descriptor = WrappedPropertyDescriptor()
|
||||
return symbolTable.declareProperty(0, 0, IrDeclarationOrigin.DEFINED, descriptor, isDelegated = false, factory).apply {
|
||||
descriptor.bind(this)
|
||||
}
|
||||
|
||||
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.fir.backend.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.hasMetaAnnotationUseSiteTargets
|
||||
import org.jetbrains.kotlin.fir.declarations.useSiteTargetsFromMetaAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.util.isPropertyField
|
||||
import org.jetbrains.kotlin.ir.util.isSetter
|
||||
|
||||
/**
|
||||
@@ -36,80 +36,73 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp
|
||||
irContainer.annotations = firContainer.annotations.toIrAnnotations()
|
||||
}
|
||||
|
||||
fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter, isInConstructor: Boolean) {
|
||||
irValueParameter.annotations +=
|
||||
firValueParameter.annotations
|
||||
.filter {
|
||||
// TODO: for `null` use-site, refer to targets on the meta annotation
|
||||
it.useSiteTarget == null || !isInConstructor || it.useSiteTarget == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
|
||||
}
|
||||
.toIrAnnotations()
|
||||
private fun FirAnnotationCall.target(applicable: List<AnnotationUseSiteTarget>): AnnotationUseSiteTarget? =
|
||||
useSiteTarget ?: applicable.firstOrNull(useSiteTargetsFromMetaAnnotation(session)::contains)
|
||||
|
||||
companion object {
|
||||
// Priority order: constructor parameter (if applicable) -> property -> field. So, for example, if `A`
|
||||
// can be attached to all three, then in a declaration like
|
||||
// class C(@A val x: Int) { @A val y = 1 }
|
||||
// the parameter `x` and the property `y` will have the annotation, while the property `x` and both backing fields will not.
|
||||
private val propertyTargets = listOf(AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.FIELD)
|
||||
private val constructorPropertyTargets = listOf(AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER) + propertyTargets
|
||||
private val delegatedPropertyTargets = propertyTargets + listOf(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD)
|
||||
}
|
||||
|
||||
private fun FirAnnotationCall.targetsField(): Boolean =
|
||||
// Check if the annotation has a field-targeting meta annotation, e.g., @Target(FIELD)
|
||||
hasMetaAnnotationUseSiteTargets(session, AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD)
|
||||
// TODO: third argument should be whether this parameter is a property declaration (though this probably makes no difference)
|
||||
fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter, isInConstructor: Boolean) {
|
||||
if (isInConstructor) {
|
||||
irValueParameter.annotations += firValueParameter.annotations
|
||||
.filter { it.target(constructorPropertyTargets) == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER }
|
||||
.toIrAnnotations()
|
||||
} else {
|
||||
irValueParameter.annotations += firValueParameter.annotations.toIrAnnotations()
|
||||
}
|
||||
}
|
||||
|
||||
fun generate(irProperty: IrProperty, property: FirProperty) {
|
||||
irProperty.annotations +=
|
||||
property.annotations
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY ||
|
||||
// NB: annotation with null use-site should be landed on the property (ahead of field),
|
||||
// unless it has FIELD target on the meta annotation, like @Target(FIELD)
|
||||
(it.useSiteTarget == null && !it.targetsField())
|
||||
}
|
||||
.toIrAnnotations()
|
||||
val applicableTargets = when {
|
||||
property.source?.kind == FirFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets
|
||||
irProperty.isDelegated -> delegatedPropertyTargets
|
||||
else -> propertyTargets
|
||||
}
|
||||
irProperty.annotations += property.annotations
|
||||
.filter { it.target(applicableTargets) == AnnotationUseSiteTarget.PROPERTY }
|
||||
.toIrAnnotations()
|
||||
}
|
||||
|
||||
fun generate(irField: IrField, property: FirProperty) {
|
||||
assert(irField.isPropertyField) {
|
||||
"$irField is not a property field."
|
||||
val irProperty = irField.correspondingPropertySymbol?.owner ?: throw AssertionError("$irField is not a property field")
|
||||
val applicableTargets = when {
|
||||
property.source?.kind == FirFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets
|
||||
irProperty.isDelegated -> delegatedPropertyTargets
|
||||
else -> propertyTargets
|
||||
}
|
||||
irField.annotations +=
|
||||
property.annotations
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.FIELD ||
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD ||
|
||||
(it.useSiteTarget == null && it.targetsField())
|
||||
}
|
||||
.toIrAnnotations()
|
||||
irField.annotations += property.annotations.filter {
|
||||
val target = it.target(applicableTargets)
|
||||
target == AnnotationUseSiteTarget.FIELD || target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
}.toIrAnnotations()
|
||||
}
|
||||
|
||||
fun generate(propertyAccessor: IrFunction, property: FirProperty) {
|
||||
assert(propertyAccessor.isPropertyAccessor) {
|
||||
"$propertyAccessor is not a property accessor."
|
||||
}
|
||||
assert(propertyAccessor.isPropertyAccessor) { "$propertyAccessor is not a property accessor." }
|
||||
if (propertyAccessor.isSetter) {
|
||||
propertyAccessor.annotations +=
|
||||
property.annotations
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
}
|
||||
.toIrAnnotations()
|
||||
propertyAccessor.valueParameters.singleOrNull()?.annotations =
|
||||
propertyAccessor.valueParameters.singleOrNull()?.annotations?.plus(
|
||||
property.annotations
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER
|
||||
}
|
||||
.toIrAnnotations()
|
||||
)!!
|
||||
propertyAccessor.annotations += property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER }
|
||||
.toIrAnnotations()
|
||||
val parameter = propertyAccessor.valueParameters.single()
|
||||
parameter.annotations += property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
||||
.toIrAnnotations()
|
||||
} else {
|
||||
propertyAccessor.annotations +=
|
||||
property.annotations
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
}
|
||||
.toIrAnnotations()
|
||||
propertyAccessor.annotations += property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER }
|
||||
.toIrAnnotations()
|
||||
}
|
||||
propertyAccessor.extensionReceiverParameter?.let { receiver ->
|
||||
receiver.annotations += property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.RECEIVER }
|
||||
.toIrAnnotations()
|
||||
}
|
||||
propertyAccessor.extensionReceiverParameter?.annotations =
|
||||
propertyAccessor.extensionReceiverParameter?.annotations?.plus(
|
||||
property.annotations
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.RECEIVER
|
||||
}
|
||||
.toIrAnnotations()
|
||||
)!!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedTypeForSAMConversion
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.isFunctional
|
||||
@@ -445,8 +446,14 @@ class CallAndReferenceGenerator(
|
||||
is FirDelegatedConstructorCall -> call.calleeReference
|
||||
is FirAnnotationCall -> call.calleeReference
|
||||
else -> null
|
||||
} as? FirResolvedNamedReference
|
||||
val function = (calleeReference?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
||||
}
|
||||
val function = if (calleeReference == FirReferencePlaceholderForResolvedAnnotations) {
|
||||
val coneClassLikeType = (call as FirAnnotationCall).annotationTypeRef.coneTypeSafe<ConeClassLikeType>()
|
||||
val firClass = (coneClassLikeType?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol)?.fir
|
||||
firClass?.declarations?.filterIsInstance<FirConstructor>()?.firstOrNull()
|
||||
} else {
|
||||
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
||||
}
|
||||
val valueParameters = function?.valueParameters
|
||||
val argumentMapping = call.argumentMapping
|
||||
if (argumentMapping != null && (annotationMode || argumentMapping.isNotEmpty())) {
|
||||
@@ -559,11 +566,13 @@ class CallAndReferenceGenerator(
|
||||
}
|
||||
}
|
||||
with(adapterGenerator) {
|
||||
irArgument = irArgument.applySuspendConversionIfNeeded(argument, parameter)
|
||||
if (parameter?.returnTypeRef is FirResolvedTypeRef) {
|
||||
// Java type case (from annotations)
|
||||
irArgument = irArgument.applySuspendConversionIfNeeded(argument, parameter)
|
||||
irArgument = irArgument.applySamConversionIfNeeded(argument, parameter)
|
||||
}
|
||||
}
|
||||
return irArgument
|
||||
.applySamConversionIfNeeded(argument, parameter)
|
||||
.applyAssigningArrayElementsToVarargInNamedForm(argument, parameter)
|
||||
return irArgument.applyAssigningArrayElementsToVarargInNamedForm(argument, parameter)
|
||||
}
|
||||
|
||||
private fun IrExpression.applySamConversionIfNeeded(
|
||||
|
||||
@@ -232,13 +232,14 @@ class FakeOverrideGenerator(
|
||||
|
||||
private fun IrProperty.discardAccessorsAccordingToBaseVisibility(baseSymbols: List<FirPropertySymbol>) {
|
||||
for (baseSymbol in baseSymbols) {
|
||||
val unwrapped = baseSymbol.unwrapFakeOverrides()
|
||||
val unwrappedSymbol = baseSymbol.unwrapFakeOverrides()
|
||||
val unwrappedProperty = unwrappedSymbol.fir
|
||||
// Do not create fake overrides for accessors if not allowed to do so, e.g., private lateinit var.
|
||||
if (unwrapped.fir.getter?.allowsToHaveFakeOverride != true) {
|
||||
if (!(unwrappedProperty.getter?.allowsToHaveFakeOverride ?: unwrappedProperty.allowsToHaveFakeOverride)) {
|
||||
getter = null
|
||||
}
|
||||
// or private setter
|
||||
if (unwrapped.fir.setter?.allowsToHaveFakeOverride != true) {
|
||||
if (!(unwrappedProperty.setter?.allowsToHaveFakeOverride ?: unwrappedProperty.allowsToHaveFakeOverride)) {
|
||||
setter = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.symbols
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.*
|
||||
@@ -42,8 +40,6 @@ abstract class Fir2IrBindableSymbol<out D : DeclarationDescriptor, B : IrSymbolO
|
||||
is IrClass -> WrappedClassDescriptor().apply { bind(owner) }
|
||||
is IrConstructor -> WrappedClassConstructorDescriptor().apply { bind(owner) }
|
||||
is IrSimpleFunction -> when {
|
||||
containerSource != null ->
|
||||
WrappedFunctionDescriptorWithContainerSource()
|
||||
owner.name.isSpecial && owner.name.asString().startsWith(GETTER_PREFIX) ->
|
||||
WrappedPropertyGetterDescriptor()
|
||||
owner.name.isSpecial && owner.name.asString().startsWith(SETTER_PREFIX) ->
|
||||
@@ -54,11 +50,7 @@ abstract class Fir2IrBindableSymbol<out D : DeclarationDescriptor, B : IrSymbolO
|
||||
is IrVariable -> WrappedVariableDescriptor().apply { bind(owner) }
|
||||
is IrValueParameter -> WrappedValueParameterDescriptor().apply { bind(owner) }
|
||||
is IrTypeParameter -> WrappedTypeParameterDescriptor().apply { bind(owner) }
|
||||
is IrProperty -> if (containerSource != null) {
|
||||
WrappedPropertyDescriptorWithContainerSource()
|
||||
} else {
|
||||
WrappedPropertyDescriptor()
|
||||
}.apply { bind(owner) }
|
||||
is IrProperty -> WrappedPropertyDescriptor().apply { bind(owner) }
|
||||
is IrField -> WrappedFieldDescriptor().apply { bind(owner) }
|
||||
is IrTypeAlias -> WrappedTypeAliasDescriptor().apply { bind(owner) }
|
||||
else -> throw IllegalStateException("Unsupported owner in Fir2IrBindableSymbol: $owner")
|
||||
|
||||
@@ -148,6 +148,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/expectClassActualTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("importCompanion.kt")
|
||||
public void testImportCompanion() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/importCompanion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassFromBinaryDependencies.kt")
|
||||
public void testInlineClassFromBinaryDependencies() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
|
||||
@@ -243,6 +248,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmStaticInObjectPropertyReference.kt")
|
||||
public void testJvmStaticInObjectPropertyReference() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmStaticInObjectPropertyReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinPropertyAsAnnotationParameter.kt")
|
||||
public void testKotlinPropertyAsAnnotationParameter() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/kotlinPropertyAsAnnotationParameter.kt");
|
||||
|
||||
@@ -3840,6 +3840,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/classes/exceptionConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFunWithDefaultParam.kt")
|
||||
public void testExtensionFunWithDefaultParam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/classes/extensionFunWithDefaultParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionOnNamedClassObject.kt")
|
||||
public void testExtensionOnNamedClassObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/classes/extensionOnNamedClassObject.kt");
|
||||
@@ -5058,6 +5063,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/collections/javaCollectionWithRemovePrimitiveInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt40305.kt")
|
||||
public void testKt40305() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/collections/kt40305.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt41123.kt")
|
||||
public void testKt41123() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/collections/kt41123.kt");
|
||||
@@ -9833,6 +9843,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/defaultArguments/function/covariantOverrideGeneric.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultLambdaInline.kt")
|
||||
public void testDefaultLambdaInline() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/defaultArguments/function/defaultLambdaInline.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFunctionManyArgs.kt")
|
||||
public void testExtensionFunctionManyArgs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/defaultArguments/function/extensionFunctionManyArgs.kt");
|
||||
@@ -12189,6 +12204,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noOptimizedCallableReferences.kt")
|
||||
public void testNoOptimizedCallableReferences() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/noOptimizedCallableReferences.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
@@ -12562,6 +12582,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/functions/bigArity/javaLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedBigArityFunCalls.kt")
|
||||
public void testNestedBigArityFunCalls() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/functions/bigArity/nestedBigArityFunCalls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subclass.kt")
|
||||
public void testSubclass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/functions/bigArity/subclass.kt");
|
||||
@@ -14127,6 +14152,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mappingOfBoxedFlexibleInlineClassType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileClass.kt")
|
||||
public void testMultifileClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedInlineClass.kt")
|
||||
public void testNestedInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||
@@ -15139,6 +15174,59 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jvm8DefaultInterfaceMethods extends AbstractFirBlackBoxCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJvm8DefaultInterfaceMethods() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("javaDefaultMethod.kt")
|
||||
public void testJavaDefaultMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/javaDefaultMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaDefaultMethodOverriddenByKotlin.kt")
|
||||
public void testJavaDefaultMethodOverriddenByKotlin() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/javaDefaultMethodOverriddenByKotlin.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultAll.kt")
|
||||
public void testJvmDefaultAll() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultAll.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultAllPrimaryProperty.kt")
|
||||
public void testJvmDefaultAllPrimaryProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultAllPrimaryProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultAllProperty.kt")
|
||||
public void testJvmDefaultAllProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultAllProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultEnable.kt")
|
||||
public void testJvmDefaultEnable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultEnable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultEnablePrimaryProperty.kt")
|
||||
public void testJvmDefaultEnablePrimaryProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultEnablePrimaryProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultEnableProperty.kt")
|
||||
public void testJvmDefaultEnableProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/jvm8DefaultInterfaceMethods/jvmDefaultEnableProperty.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/propertyDelegation")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -17959,6 +18047,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/propertyGetterDelegatesToAnother.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyReference.kt")
|
||||
public void testPropertyReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/propertyReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/simple.kt");
|
||||
@@ -21443,6 +21536,31 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/properties/kt9603.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitialization.kt")
|
||||
public void testLazyInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitialization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitializationCyclicImports.kt")
|
||||
public void testLazyInitializationCyclicImports() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationCyclicImports.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitializationMultiModule.kt")
|
||||
public void testLazyInitializationMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitializationOrder.kt")
|
||||
public void testLazyInitializationOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitializationSplitPerModule.kt")
|
||||
public void testLazyInitializationSplitPerModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitializationSplitPerModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveOverrideDefaultAccessor.kt")
|
||||
public void testPrimitiveOverrideDefaultAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/primitiveOverrideDefaultAccessor.kt");
|
||||
@@ -32016,6 +32134,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("evaluateConstructorOfUnsignedArrayType.kt")
|
||||
public void testEvaluateConstructorOfUnsignedArrayType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedArrayType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("evaluateConstructorOfUnsignedType.kt")
|
||||
public void testEvaluateConstructorOfUnsignedType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/evaluateConstructorOfUnsignedType.kt");
|
||||
@@ -32195,6 +32318,59 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testWhenByUnsigned() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/whenByUnsigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jvm8Intrinsics extends AbstractFirBlackBoxCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJvm8Intrinsics() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedIntCompare_jvm8.kt")
|
||||
public void testUnsignedIntCompare_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntCompare_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedIntDivide_jvm8.kt")
|
||||
public void testUnsignedIntDivide_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntDivide_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedIntRemainder_jvm8.kt")
|
||||
public void testUnsignedIntRemainder_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntRemainder_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedIntToString_jvm8.kt")
|
||||
public void testUnsignedIntToString_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedIntToString_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedLongCompare_jvm8.kt")
|
||||
public void testUnsignedLongCompare_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongCompare_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedLongDivide_jvm8.kt")
|
||||
public void testUnsignedLongDivide_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongDivide_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedLongRemainder_jvm8.kt")
|
||||
public void testUnsignedLongRemainder_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongRemainder_jvm8.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsignedLongToString_jvm8.kt")
|
||||
public void testUnsignedLongToString_jvm8() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/unsignedTypes/jvm8Intrinsics/unsignedLongToString_jvm8.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/vararg")
|
||||
|
||||
@@ -774,6 +774,11 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/callableReference/kt36975.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt39612.kt")
|
||||
public void testKt39612() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/callableReference/kt39612.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nameIntrinsicWithImplicitThis.kt")
|
||||
public void testNameIntrinsicWithImplicitThis() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/callableReference/nameIntrinsicWithImplicitThis.kt");
|
||||
|
||||
@@ -1812,6 +1812,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/firProblems/InnerClassInAnonymous.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43342.kt")
|
||||
public void testKt43342() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/firProblems/kt43342.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MultiList.kt")
|
||||
public void testMultiList() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/firProblems/MultiList.kt");
|
||||
|
||||
@@ -50,7 +50,7 @@ class JavaSymbolProvider(
|
||||
private val searchScope: GlobalSearchScope,
|
||||
) : FirSymbolProvider(session) {
|
||||
companion object {
|
||||
private val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
internal val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
}
|
||||
|
||||
private val classCache = SymbolProviderCache<ClassId, FirRegularClassSymbol>()
|
||||
@@ -168,6 +168,7 @@ class JavaSymbolProvider(
|
||||
javaTypeParameterStack.addStack(parentStack)
|
||||
}
|
||||
}
|
||||
val methodMap = mutableMapOf<JavaMethod, FirJavaMethod>()
|
||||
val firJavaClass = buildJavaClass {
|
||||
source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
@@ -219,7 +220,9 @@ class JavaSymbolProvider(
|
||||
classIsAnnotation,
|
||||
valueParametersForAnnotationConstructor,
|
||||
dispatchReceiver
|
||||
)
|
||||
).apply {
|
||||
methodMap[javaMethod] = this
|
||||
}
|
||||
}
|
||||
val javaClassDeclaredConstructors = javaClass.constructors
|
||||
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
|
||||
@@ -270,6 +273,10 @@ class JavaSymbolProvider(
|
||||
}
|
||||
)
|
||||
firJavaClass.addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
// NB: this is done here to unbind possible annotation cycle
|
||||
for ((javaMethod, firJavaMethod) in methodMap) {
|
||||
firJavaMethod.annotations.addAnnotationsFrom(session, javaMethod, javaTypeParameterStack)
|
||||
}
|
||||
return firJavaClass
|
||||
}
|
||||
|
||||
@@ -364,7 +371,6 @@ class JavaSymbolProvider(
|
||||
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
|
||||
isStatic = javaMethod.isStatic
|
||||
typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaMethod, javaTypeParameterStack)
|
||||
for ((index, valueParameter) in javaMethod.valueParameters.withIndex()) {
|
||||
valueParameters += valueParameter.toFirValueParameter(
|
||||
this@JavaSymbolProvider.session, index, javaTypeParameterStack,
|
||||
|
||||
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
||||
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
@@ -31,6 +33,7 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
@@ -418,16 +421,51 @@ private fun FirRegularClass.createRawArguments(
|
||||
computeRawProjection(session, typeParameter, position, erasedUpperBound)
|
||||
}
|
||||
|
||||
private fun FirAnnotationCallBuilder.buildArgumentMapping(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
classId: ClassId?,
|
||||
annotationArguments: Collection<JavaAnnotationArgument>
|
||||
): LinkedHashMap<FirExpression, FirValueParameter>? {
|
||||
if (classId == null) {
|
||||
annotationTypeRef = buildErrorTypeRef { diagnostic = ConeUnresolvedReferenceError() }
|
||||
return null
|
||||
}
|
||||
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||
annotationTypeRef = buildResolvedTypeRef {
|
||||
type = ConeClassLikeTypeImpl(lookupTag, emptyArray(), isNullable = false)
|
||||
}
|
||||
if (annotationArguments.any { it.name != null }) {
|
||||
val mapping = linkedMapOf<FirExpression, FirValueParameter>()
|
||||
val annotationClassSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId).also {
|
||||
lookupTag.bindSymbolToLookupTag(session, it)
|
||||
}
|
||||
if (annotationClassSymbol != null) {
|
||||
val annotationConstructor =
|
||||
(annotationClassSymbol.fir as FirRegularClass).declarations.filterIsInstance<FirConstructor>().first()
|
||||
for (argument in annotationArguments) {
|
||||
mapping[argument.toFirExpression(session, javaTypeParameterStack)] =
|
||||
annotationConstructor.valueParameters.find { it.name == (argument.name ?: JavaSymbolProvider.VALUE_METHOD_NAME) }
|
||||
?: return null
|
||||
}
|
||||
return mapping
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun JavaAnnotation.toFirAnnotationCall(
|
||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||
): FirAnnotationCall {
|
||||
return buildAnnotationCall {
|
||||
annotationTypeRef = buildResolvedTypeRef {
|
||||
type = ConeClassLikeTypeImpl(FirRegularClassSymbol(classId!!).toLookupTag(), emptyArray(), isNullable = false)
|
||||
}
|
||||
argumentList = buildArgumentList {
|
||||
for (argument in this@toFirAnnotationCall.arguments) {
|
||||
arguments += argument.toFirExpression(session, javaTypeParameterStack)
|
||||
val mapping = buildArgumentMapping(session, javaTypeParameterStack, classId, arguments)
|
||||
argumentList = if (mapping != null) {
|
||||
buildResolvedArgumentList(mapping)
|
||||
} else {
|
||||
buildArgumentList {
|
||||
for (argument in this@toFirAnnotationCall.arguments) {
|
||||
arguments += argument.toFirExpression(session, javaTypeParameterStack)
|
||||
}
|
||||
}
|
||||
}
|
||||
calleeReference = FirReferencePlaceholderForResolvedAnnotations
|
||||
@@ -447,7 +485,7 @@ internal fun FirJavaClass.addAnnotationsFrom(
|
||||
annotations.addAnnotationsFrom(session, javaAnnotationOwner, javaTypeParameterStack)
|
||||
}
|
||||
|
||||
private fun MutableList<FirAnnotationCall>.addAnnotationsFrom(
|
||||
internal fun MutableList<FirAnnotationCall>.addAnnotationsFrom(
|
||||
session: FirSession,
|
||||
javaAnnotationOwner: JavaAnnotationOwner,
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
@@ -126,7 +127,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
FirDeserializationContext.createForPackage(
|
||||
packageFqName, packageProto, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
|
||||
FirConstDeserializer(session, kotlinJvmBinaryClass, facadeBinaryClass),
|
||||
FirConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
|
||||
source
|
||||
),
|
||||
source,
|
||||
@@ -300,6 +301,12 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
return loadAnnotation(annotationClassId, result)
|
||||
}
|
||||
|
||||
private fun findAndDeserializeClassViaParent(classId: ClassId): FirRegularClassSymbol? {
|
||||
val outerClassId = classId.outerClassId ?: return null
|
||||
findAndDeserializeClass(outerClassId) ?: return null
|
||||
return classCache[classId]
|
||||
}
|
||||
|
||||
private fun findAndDeserializeClass(
|
||||
classId: ClassId,
|
||||
parentContext: FirDeserializationContext? = null
|
||||
@@ -314,7 +321,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
} catch (e: ProcessCanceledException) {
|
||||
return null
|
||||
}
|
||||
val kotlinClassWithContent = when (result) {
|
||||
val (kotlinJvmBinaryClass, byteContent) = when (result) {
|
||||
is KotlinClassFinder.Result.KotlinClass -> result
|
||||
is KotlinClassFinder.Result.ClassFileContent -> {
|
||||
handledByJava.add(classId)
|
||||
@@ -324,45 +331,39 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
null
|
||||
}
|
||||
}
|
||||
null -> null
|
||||
null -> return findAndDeserializeClassViaParent(classId)
|
||||
}
|
||||
if (kotlinClassWithContent == null) {
|
||||
val outerClassId = classId.outerClassId ?: return null
|
||||
findAndDeserializeClass(outerClassId) ?: return null
|
||||
} else {
|
||||
val (kotlinJvmBinaryClass, byteContent) = kotlinClassWithContent
|
||||
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
|
||||
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
|
||||
|
||||
if (kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
|
||||
val (nameResolver, classProto) = kotlinJvmBinaryClass.readClassDataFrom() ?: return null
|
||||
|
||||
val symbol = FirRegularClassSymbol(classId)
|
||||
deserializeClassToSymbol(
|
||||
classId, classProto, symbol, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
|
||||
kotlinScopeProvider,
|
||||
parentContext, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass),
|
||||
this::findAndDeserializeClass
|
||||
)
|
||||
|
||||
classCache[classId] = symbol
|
||||
val annotations = mutableListOf<FirAnnotationCall>()
|
||||
kotlinJvmBinaryClass.loadClassAnnotations(
|
||||
object : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, annotations)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
byteContent,
|
||||
)
|
||||
(symbol.fir.annotations as MutableList<FirAnnotationCall>) += annotations
|
||||
if (parentContext == null && Flags.CLASS_KIND.get(classProto.flags) == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
|
||||
return findAndDeserializeClassViaParent(classId)
|
||||
}
|
||||
|
||||
return classCache[classId]
|
||||
val symbol = FirRegularClassSymbol(classId)
|
||||
deserializeClassToSymbol(
|
||||
classId, classProto, symbol, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
|
||||
kotlinScopeProvider,
|
||||
parentContext, KotlinJvmBinarySourceElement(kotlinJvmBinaryClass),
|
||||
this::findAndDeserializeClass
|
||||
)
|
||||
|
||||
classCache[classId] = symbol
|
||||
val annotations = mutableListOf<FirAnnotationCall>()
|
||||
kotlinJvmBinaryClass.loadClassAnnotations(
|
||||
object : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, annotations)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
}
|
||||
},
|
||||
byteContent,
|
||||
)
|
||||
(symbol.fir.annotations as MutableList<FirAnnotationCall>) += annotations
|
||||
return symbol
|
||||
}
|
||||
|
||||
private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List<FirCallableSymbol<*>> {
|
||||
|
||||
@@ -54,36 +54,36 @@ inline val FirProperty.hasJvmFieldAnnotation: Boolean
|
||||
val FirAnnotationCall.isJvmFieldAnnotation: Boolean
|
||||
get() = toAnnotationClassId() == JVM_FIELD_CLASS_ID
|
||||
|
||||
private fun FirAnnotationCall.useSiteTargetsFromMetaAnnotation(session: FirSession): List<AnnotationUseSiteTarget> {
|
||||
val metaAnnotationAboutTarget =
|
||||
toAnnotationClass(session)?.annotations?.find { it.toAnnotationClassId() == TARGET_CLASS_ID }
|
||||
?: return emptyList()
|
||||
return metaAnnotationAboutTarget.argumentList.arguments.toAnnotationUseSiteTargets()
|
||||
}
|
||||
fun FirAnnotationCall.useSiteTargetsFromMetaAnnotation(session: FirSession): Set<AnnotationUseSiteTarget> =
|
||||
toAnnotationClass(session)?.annotations?.find { it.toAnnotationClassId() == TARGET_CLASS_ID }?.argumentList?.arguments
|
||||
?.toAnnotationUseSiteTargets() ?: DEFAULT_USE_SITE_TARGETS
|
||||
|
||||
private fun List<FirExpression>.toAnnotationUseSiteTargets(): List<AnnotationUseSiteTarget> =
|
||||
flatMap { arg ->
|
||||
val unwrappedArg = if (arg is FirNamedArgumentExpression) arg.expression else arg
|
||||
if (unwrappedArg is FirArrayOfCall) {
|
||||
unwrappedArg.argumentList.arguments.toAnnotationUseSiteTargets()
|
||||
} else {
|
||||
unwrappedArg.toAnnotationUseSiteTarget()?.let { listOf(it) } ?: emptyList()
|
||||
private fun List<FirExpression>.toAnnotationUseSiteTargets(): Set<AnnotationUseSiteTarget> =
|
||||
flatMapTo(mutableSetOf()) { arg ->
|
||||
when (val unwrappedArg = if (arg is FirNamedArgumentExpression) arg.expression else arg) {
|
||||
is FirArrayOfCall -> unwrappedArg.argumentList.arguments.toAnnotationUseSiteTargets()
|
||||
is FirVarargArgumentsExpression -> unwrappedArg.arguments.toAnnotationUseSiteTargets()
|
||||
else -> USE_SITE_TARGET_NAME_MAP[unwrappedArg.callableNameOfMetaAnnotationArgument?.identifier] ?: setOf()
|
||||
}
|
||||
}
|
||||
|
||||
private val USE_SITE_TARGET_NAME_MAP =
|
||||
AnnotationUseSiteTarget.values().map { it.name to it }.toMap()
|
||||
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.USE_SITE_MAPPING] (it's in reverse)
|
||||
private val USE_SITE_TARGET_NAME_MAP = mapOf(
|
||||
"FIELD" to setOf(AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD),
|
||||
"FILE" to setOf(AnnotationUseSiteTarget.FILE),
|
||||
"PROPERTY" to setOf(AnnotationUseSiteTarget.PROPERTY),
|
||||
"PROPERTY_GETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_GETTER),
|
||||
"PROPERTY_SETTER" to setOf(AnnotationUseSiteTarget.PROPERTY_SETTER),
|
||||
"VALUE_PARAMETER" to setOf(
|
||||
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER,
|
||||
AnnotationUseSiteTarget.RECEIVER,
|
||||
AnnotationUseSiteTarget.SETTER_PARAMETER,
|
||||
),
|
||||
)
|
||||
|
||||
private fun FirExpression.toAnnotationUseSiteTarget(): AnnotationUseSiteTarget? =
|
||||
// TODO: depending on the context, "PARAMETER" can be mapped to either CONSTRUCTOR_PARAMETER or SETTER_PARAMETER ?
|
||||
callableNameOfMetaAnnotationArgument?.identifier?.let {
|
||||
USE_SITE_TARGET_NAME_MAP[it]
|
||||
}
|
||||
|
||||
fun FirAnnotationCall.hasMetaAnnotationUseSiteTargets(session: FirSession, vararg useSiteTargets: AnnotationUseSiteTarget): Boolean {
|
||||
val meta = useSiteTargetsFromMetaAnnotation(session)
|
||||
return useSiteTargets.any { meta.contains(it) }
|
||||
}
|
||||
// See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget] (the second argument of each entry)
|
||||
private val DEFAULT_USE_SITE_TARGETS: Set<AnnotationUseSiteTarget> =
|
||||
USE_SITE_TARGET_NAME_MAP.values.fold(setOf<AnnotationUseSiteTarget>()) { a, b -> a + b } - setOf(AnnotationUseSiteTarget.FILE)
|
||||
|
||||
fun FirAnnotatedDeclaration.hasAnnotation(classId: ClassId): Boolean {
|
||||
return annotations.any { it.toAnnotationClassId() == classId }
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
|
||||
@NoMutableState
|
||||
class InferenceComponents(val session: FirSession) : FirSessionComponent {
|
||||
val ctx: ConeTypeCheckerContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
|
||||
val ctx: ConeTypeCheckerContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = true, session)
|
||||
|
||||
val approximator: AbstractTypeApproximator = object : AbstractTypeApproximator(ctx) {}
|
||||
val trivialConstraintTypeInferenceOracle = TrivialConstraintTypeInferenceOracle.create(ctx)
|
||||
|
||||
@@ -584,7 +584,7 @@ class ConeTypeCheckerContext(
|
||||
errorTypesEqualToAnything: Boolean,
|
||||
stubTypesEqualToAnything: Boolean
|
||||
): AbstractTypeCheckerContext =
|
||||
if (this.isErrorTypeEqualsToAnything == errorTypesEqualToAnything)
|
||||
if (this.isErrorTypeEqualsToAnything == errorTypesEqualToAnything && this.isStubTypeEqualsToAnything == stubTypesEqualToAnything)
|
||||
this
|
||||
else
|
||||
ConeTypeCheckerContext(errorTypesEqualToAnything, stubTypesEqualToAnything, session)
|
||||
|
||||
@@ -34,7 +34,7 @@ fun ConeClassLikeType.isByte(): Boolean = lookupTag.classId == StandardClassIds.
|
||||
fun ConeClassLikeType.isBoolean(): Boolean = lookupTag.classId == StandardClassIds.Boolean
|
||||
fun ConeClassLikeType.isChar(): Boolean = lookupTag.classId == StandardClassIds.Char
|
||||
|
||||
fun ConeClassLikeType.isPrimitiveType(): Boolean = isPrimitiveNumberOrUnsignedNumberType() || isBoolean() || isByte() || isShort()
|
||||
fun ConeClassLikeType.isPrimitiveType(): Boolean = isPrimitiveNumberOrUnsignedNumberType() || isBoolean() || isByte() || isShort() || isChar()
|
||||
fun ConeClassLikeType.isPrimitiveNumberType(): Boolean = lookupTag.classId in PRIMITIVE_NUMBER_CLASS_IDS
|
||||
fun ConeClassLikeType.isPrimitiveUnsignedNumberType(): Boolean = lookupTag.classId in PRIMITIVE_UNSIGNED_NUMBER_CLASS_IDS
|
||||
fun ConeClassLikeType.isPrimitiveNumberOrUnsignedNumberType(): Boolean = isPrimitiveNumberType() || isPrimitiveUnsignedNumberType()
|
||||
|
||||
@@ -64,6 +64,9 @@ inline val FirPropertyAccessor.modality get() = status.modality
|
||||
inline val FirPropertyAccessor.visibility get() = status.visibility
|
||||
inline val FirPropertyAccessor.isInline get() = status.isInline
|
||||
inline val FirPropertyAccessor.isExternal get() = status.isExternal
|
||||
|
||||
inline val FirProperty.allowsToHaveFakeOverride: Boolean
|
||||
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.InvisibleFake
|
||||
inline val FirPropertyAccessor.allowsToHaveFakeOverride: Boolean
|
||||
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.InvisibleFake
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ inline val FirCall.argumentMapping: LinkedHashMap<FirExpression, FirValueParamet
|
||||
get() = (argumentList as? FirResolvedArgumentList)?.mapping
|
||||
|
||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||
if (this is FirWrappedArgumentExpression) return expression.toResolvedCallableReference()
|
||||
return (this as? FirResolvable)?.calleeReference as? FirResolvedNamedReference
|
||||
}
|
||||
|
||||
|
||||
@@ -362,6 +362,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtTypeReference> INLINE_CLASS_CANNOT_BE_RECURSIVE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> RESERVED_MEMBER_INSIDE_INLINE_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INNER_CLASS_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Result class
|
||||
|
||||
|
||||
@@ -704,7 +704,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_ENUM, "Constructor must be private in enum class");
|
||||
MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_SEALED, "Constructor must be private in sealed class");
|
||||
|
||||
MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes are only allowed on top level");
|
||||
MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes cannot be local or inner");
|
||||
MAP.put(INLINE_CLASS_NOT_FINAL, "Inline classes can be only final");
|
||||
MAP.put(ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS, "Primary constructor is required for inline class");
|
||||
MAP.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter");
|
||||
@@ -717,6 +717,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(INLINE_CLASS_CANNOT_BE_RECURSIVE, "Inline class cannot be recursive");
|
||||
MAP.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", STRING);
|
||||
MAP.put(SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS, "Secondary constructors with bodies are reserved for for future releases");
|
||||
MAP.put(INNER_CLASS_INSIDE_INLINE_CLASS, "Inline class cannot have inner classes");
|
||||
|
||||
MAP.put(RESULT_CLASS_IN_RETURN_TYPE, "'kotlin.Result' cannot be used as a return type");
|
||||
MAP.put(RESULT_CLASS_WITH_NULLABLE_OPERATOR, "Expression of type 'kotlin.Result' cannot be used as a left operand of ''{0}''", STRING);
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -93,12 +94,16 @@ class CollectionLiteralResolver(
|
||||
}
|
||||
|
||||
private fun getArrayFunctionCallName(expectedType: KotlinType): Name {
|
||||
if (NO_EXPECTED_TYPE === expectedType || !KotlinBuiltIns.isPrimitiveArray(expectedType)) {
|
||||
if (NO_EXPECTED_TYPE === expectedType ||
|
||||
!(KotlinBuiltIns.isPrimitiveArray(expectedType) || KotlinBuiltIns.isUnsignedArrayType(expectedType))
|
||||
) {
|
||||
return ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
}
|
||||
|
||||
val descriptor = expectedType.constructor.declarationDescriptor ?: return ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
|
||||
return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)] ?: ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
return ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)]
|
||||
?: UnsignedTypes.unsignedArrayTypeToArrayCall[UnsignedTypes.toUnsignedArrayType(descriptor)]
|
||||
?: ArrayFqNames.ARRAY_OF_FUNCTION
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,11 @@ public class CompileTimeConstantUtils {
|
||||
"kotlin.shortArrayOf",
|
||||
"kotlin.byteArrayOf",
|
||||
"kotlin.booleanArrayOf",
|
||||
"kotlin.emptyArray"
|
||||
"kotlin.emptyArray",
|
||||
"kotlin.ubyteArrayOf",
|
||||
"kotlin.ushortArrayOf",
|
||||
"kotlin.uintArrayOf",
|
||||
"kotlin.ulongArrayOf"
|
||||
);
|
||||
|
||||
public static void checkConstructorParametersType(@NotNull List<KtParameter> parameters, @NotNull BindingTrace trace) {
|
||||
@@ -91,7 +95,8 @@ public class CompileTimeConstantUtils {
|
||||
KotlinBuiltIns.isPrimitiveArray(parameterType) ||
|
||||
KotlinBuiltIns.isPrimitiveType(parameterType) ||
|
||||
KotlinBuiltIns.isString(parameterType) ||
|
||||
UnsignedTypes.INSTANCE.isUnsignedType(parameterType)) {
|
||||
UnsignedTypes.isUnsignedType(parameterType) ||
|
||||
UnsignedTypes.isUnsignedArrayType(parameterType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
SuspendLimitationsChecker,
|
||||
InlineClassDeclarationChecker,
|
||||
PropertiesWithBackingFieldsInsideInlineClass(),
|
||||
InnerClassInsideInlineClass(),
|
||||
AnnotationClassTargetAndRetentionChecker(),
|
||||
ReservedMembersAndConstructsForInlineClass(),
|
||||
ResultClassInReturnTypeChecker(),
|
||||
|
||||
@@ -29,7 +29,7 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
require(inlineOrValueKeyword != null) { "Declaration of inline class must have 'inline' keyword" }
|
||||
|
||||
val trace = context.trace
|
||||
if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||
if (descriptor.isInner || DescriptorUtils.isLocal(descriptor)) {
|
||||
trace.report(Errors.INLINE_CLASS_NOT_TOP_LEVEL.on(inlineOrValueKeyword))
|
||||
return
|
||||
}
|
||||
@@ -124,6 +124,18 @@ class PropertiesWithBackingFieldsInsideInlineClass : DeclarationChecker {
|
||||
}
|
||||
}
|
||||
|
||||
class InnerClassInsideInlineClass : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (declaration !is KtClass) return
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
if (!descriptor.isInner) return
|
||||
|
||||
if (!descriptor.containingDeclaration.isInlineClass()) return
|
||||
|
||||
context.trace.report(Errors.INNER_CLASS_INSIDE_INLINE_CLASS.on(declaration.modifierList!!.getModifier(KtTokens.INNER_KEYWORD)!!))
|
||||
}
|
||||
}
|
||||
|
||||
class ReservedMembersAndConstructsForInlineClass : DeclarationChecker {
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -397,7 +397,7 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun isElseBranch(branch: IrBranch) = branch is IrElseBranch || ((branch.condition as? IrConst<Boolean>)?.value == true)
|
||||
|
||||
fun IrSimpleFunction.isMethodOfAny() =
|
||||
fun IrFunction.isMethodOfAny() =
|
||||
((valueParameters.size == 0 && name.asString().let { it == "hashCode" || it == "toString" }) ||
|
||||
(valueParameters.size == 1 && name.asString() == "equals" && valueParameters[0].type.isNullableAny()))
|
||||
|
||||
@@ -497,9 +497,7 @@ fun IrFactory.createStaticFunctionWithReceivers(
|
||||
copyMetadata: Boolean = true,
|
||||
typeParametersFromContext: List<IrTypeParameter> = listOf()
|
||||
): IrSimpleFunction {
|
||||
val descriptor = (oldFunction.descriptor as? DescriptorWithContainerSource)?.let {
|
||||
WrappedFunctionDescriptorWithContainerSource()
|
||||
} ?: WrappedSimpleFunctionDescriptor()
|
||||
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||
return createFunction(
|
||||
oldFunction.startOffset, oldFunction.endOffset,
|
||||
origin,
|
||||
|
||||
@@ -55,14 +55,19 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val callableReference = expression.dispatchReceiver as? IrCallableReference<*> ?: return expression
|
||||
val callableReference = expression.dispatchReceiver as? IrCallableReference<*>
|
||||
?: return super.visitCall(expression)
|
||||
|
||||
//TODO rewrite checking
|
||||
val directMember = expression.symbol.owner.let {
|
||||
(it as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: it
|
||||
}
|
||||
val irClass = directMember.parent as? IrClass ?: return expression
|
||||
if (!irClass.isSubclassOf(lower.context.irBuiltIns.kCallableClass.owner)) return expression
|
||||
|
||||
val irClass = directMember.parent as? IrClass
|
||||
?: return super.visitCall(expression)
|
||||
if (!irClass.isSubclassOf(lower.context.irBuiltIns.kCallableClass.owner)) {
|
||||
return super.visitCall(expression)
|
||||
}
|
||||
|
||||
val name = when (directMember) {
|
||||
is IrSimpleFunction -> directMember.name
|
||||
is IrProperty -> directMember.name
|
||||
|
||||
@@ -11,8 +11,6 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyProperty
|
||||
import org.jetbrains.kotlin.ir.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
@@ -77,9 +75,7 @@ fun IrClass.addField(fieldName: String, fieldType: IrType, fieldVisibility: Desc
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildProperty(builder: IrPropertyBuilder): IrProperty = with(builder) {
|
||||
val wrappedDescriptor = if (originalDeclaration is IrLazyProperty || containerSource != null)
|
||||
WrappedPropertyDescriptorWithContainerSource()
|
||||
else WrappedPropertyDescriptor()
|
||||
val wrappedDescriptor = WrappedPropertyDescriptor()
|
||||
|
||||
createProperty(
|
||||
startOffset, endOffset, origin,
|
||||
@@ -117,9 +113,7 @@ inline fun IrProperty.addGetter(builder: IrFunctionBuilder.() -> Unit = {}): IrS
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildFunction(builder: IrFunctionBuilder): IrSimpleFunction = with(builder) {
|
||||
val wrappedDescriptor = if (originalDeclaration is IrLazyFunction || containerSource != null)
|
||||
WrappedFunctionDescriptorWithContainerSource()
|
||||
else WrappedSimpleFunctionDescriptor()
|
||||
val wrappedDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
createFunction(
|
||||
startOffset, endOffset, origin,
|
||||
IrSimpleFunctionSymbolImpl(wrappedDescriptor),
|
||||
|
||||
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getJsName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.hasStableJsName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
@@ -118,7 +118,7 @@ abstract class BridgesConstruction(val context: JsCommonBackendContext) : Declar
|
||||
): IrFunction {
|
||||
|
||||
val origin =
|
||||
if (bridge.isEffectivelyExternal() || bridge.getJsName() != null)
|
||||
if (bridge.hasStableJsName())
|
||||
JsLoweredDeclarationOrigin.BRIDGE_TO_EXTERNAL_FUNCTION
|
||||
else
|
||||
IrDeclarationOrigin.BRIDGE
|
||||
|
||||
@@ -37,11 +37,12 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
||||
): IrExpression {
|
||||
val paramCount = oldIrFunction.valueParameters.size
|
||||
val invokeFunctionN = resolveInvoke(paramCount)
|
||||
// NOTE: currently we do not have a syntax to perform super extension call
|
||||
// but in case we have such functionality in the future the logic bellow should be fixed
|
||||
|
||||
return irCall(invokeFunctionN, IrStatementOrigin.INVOKE).apply {
|
||||
dispatchReceiver = irImplicitCast(irGet(handlerDeclaration), invokeFunctionN.dispatchReceiverParameter!!.type)
|
||||
assert(newIrFunction.extensionReceiverParameter == null)
|
||||
// NOTE: currently we do not have a syntax to perform super extension call
|
||||
// that's why we've used to just fail with an exception in case we have extension function in for JS IR compilation
|
||||
// TODO: that was overkill, however, we still need to revisit this issue later on
|
||||
params.forEachIndexed { i, variable -> putValueArgument(i, irGet(variable)) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,9 +47,11 @@ class PropertyLazyInitLowering(
|
||||
return
|
||||
}
|
||||
|
||||
if (container !is IrSimpleFunction && container !is IrField && container !is IrProperty)
|
||||
if (container !is IrField && container !is IrSimpleFunction && container !is IrProperty)
|
||||
return
|
||||
|
||||
if (container.origin !in compatibleOrigins) return
|
||||
|
||||
val file = container.parent as? IrFile
|
||||
?: return
|
||||
|
||||
@@ -224,6 +226,8 @@ class RemoveInitializersForLazyProperties(
|
||||
|
||||
if (declaration !is IrField) return null
|
||||
|
||||
if (!declaration.isCompatibleDeclaration()) return null
|
||||
|
||||
val file = declaration.parent as? IrFile ?: return null
|
||||
|
||||
if (fileToInitializerPureness[file] == true) return null
|
||||
@@ -257,6 +261,7 @@ class RemoveInitializersForLazyProperties(
|
||||
private fun calculateFieldToExpression(declarations: Collection<IrDeclaration>): Map<IrField, IrExpression> =
|
||||
declarations
|
||||
.asSequence()
|
||||
.filter { it.isCompatibleDeclaration() }
|
||||
.map { it.correspondingProperty }
|
||||
.filterNotNull()
|
||||
.filter { it.isForLazyInit() }
|
||||
@@ -288,4 +293,14 @@ private val IrDeclaration.correspondingProperty: IrProperty?
|
||||
private fun IrDeclaration.propertyWithPersistentSafe(transform: IrDeclaration.() -> IrProperty?): IrProperty? =
|
||||
if (((this as? PersistentIrElementBase<*>)?.createdOn ?: 0) <= stageController.currentStage) {
|
||||
transform()
|
||||
} else null
|
||||
} else null
|
||||
|
||||
private fun IrDeclaration.isCompatibleDeclaration() =
|
||||
origin in compatibleOrigins
|
||||
|
||||
private val compatibleOrigins = listOf(
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
|
||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||
)
|
||||
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.isElseBranch
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
@@ -156,14 +153,33 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
// Argument value constructs unboxed inline class instance
|
||||
arguments.single()
|
||||
} else {
|
||||
val ref = when {
|
||||
klass.isEffectivelyExternal() ->
|
||||
context.getRefForExternalClass(klass)
|
||||
|
||||
else ->
|
||||
context.getNameForClass(klass).makeRef()
|
||||
when {
|
||||
klass.isEffectivelyExternal() -> {
|
||||
val refForExternalClass = context.getRefForExternalClass(klass)
|
||||
val varargParameterIndex = expression.symbol.owner.varargParameterIndex()
|
||||
if (varargParameterIndex == -1) {
|
||||
JsNew(refForExternalClass, arguments)
|
||||
} else {
|
||||
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
||||
JsNullLiteral(),
|
||||
arguments,
|
||||
varargParameterIndex
|
||||
)
|
||||
JsNew(
|
||||
JsInvocation(
|
||||
JsNameRef("apply", JsNameRef("bind", JsNameRef("Function"))),
|
||||
refForExternalClass,
|
||||
argumentsAsSingleArray
|
||||
),
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val ref = context.getNameForClass(klass).makeRef()
|
||||
JsNew(ref, arguments)
|
||||
}
|
||||
}
|
||||
JsNew(ref, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -120,7 +121,7 @@ fun translateCall(
|
||||
return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) + arguments } ?: arguments)
|
||||
}
|
||||
|
||||
val varargParameterIndex = function.valueParameters.indexOfFirst { it.varargElementType != null }
|
||||
val varargParameterIndex = function.varargParameterIndex()
|
||||
val isExternalVararg = function.isEffectivelyExternal() && varargParameterIndex != -1
|
||||
|
||||
val symbolName = when (jsDispatchReceiver) {
|
||||
@@ -134,28 +135,12 @@ fun translateCall(
|
||||
}
|
||||
|
||||
return if (isExternalVararg) {
|
||||
|
||||
// External vararg arguments should be represented in JS as multiple "plain" arguments (opposed to arrays in Kotlin)
|
||||
// We are using `Function.prototype.apply` function to pass all arguments as a single array.
|
||||
// For this purpose are concatenating non-vararg arguments with vararg.
|
||||
// TODO: Don't use `Function.prototype.apply` when number of arguments is known at compile time (e.g. there are no spread operators)
|
||||
val arrayConcat = JsNameRef("concat", JsArrayLiteral())
|
||||
val arraySliceCall = JsNameRef("call", JsNameRef("slice", JsArrayLiteral()))
|
||||
|
||||
val argumentsAsSingleArray = JsInvocation(
|
||||
arrayConcat,
|
||||
listOfNotNull(jsExtensionReceiver) + arguments.mapIndexed { index, argument ->
|
||||
when (index) {
|
||||
|
||||
// Call `Array.prototype.slice` on vararg arguments in order to convert array-like objects into proper arrays
|
||||
// TODO: Optimize for proper arrays
|
||||
varargParameterIndex -> JsInvocation(arraySliceCall, argument)
|
||||
|
||||
// TODO: Don't wrap non-array-like arguments with array literal
|
||||
// TODO: Wrap adjacent non-vararg arguments in a single array literal
|
||||
else -> JsArrayLiteral(listOf(argument))
|
||||
}
|
||||
}
|
||||
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
||||
jsExtensionReceiver,
|
||||
arguments,
|
||||
varargParameterIndex
|
||||
)
|
||||
|
||||
if (jsDispatchReceiver != null) {
|
||||
@@ -198,13 +183,66 @@ fun translateCall(
|
||||
}
|
||||
}
|
||||
|
||||
fun argumentsWithVarargAsSingleArray(
|
||||
additionalReceiver: JsExpression?,
|
||||
arguments: List<JsExpression>,
|
||||
varargParameterIndex: Int,
|
||||
): JsExpression {
|
||||
// External vararg arguments should be represented in JS as multiple "plain" arguments (opposed to arrays in Kotlin)
|
||||
// We are using `Function.prototype.apply` function to pass all arguments as a single array.
|
||||
// For this purpose are concatenating non-vararg arguments with vararg.
|
||||
var arraysForConcat: MutableList<JsExpression> = mutableListOf<JsExpression>().apply {
|
||||
additionalReceiver?.let { add(it) }
|
||||
}
|
||||
val concatElements: MutableList<JsExpression> = mutableListOf()
|
||||
|
||||
arguments
|
||||
.forEachIndexed { index, argument ->
|
||||
when (index) {
|
||||
|
||||
// Call `Array.prototype.slice` on vararg arguments in order to convert array-like objects into proper arrays
|
||||
varargParameterIndex -> {
|
||||
concatElements.add(JsArrayLiteral(arraysForConcat))
|
||||
arraysForConcat = mutableListOf()
|
||||
|
||||
val varargArgument = if (argument is JsArrayLiteral) {
|
||||
argument
|
||||
} else {
|
||||
val arraySliceCall = JsNameRef("call", JsNameRef("slice", JsArrayLiteral()))
|
||||
JsInvocation(arraySliceCall, argument)
|
||||
}
|
||||
|
||||
concatElements.add(varargArgument)
|
||||
}
|
||||
|
||||
else -> {
|
||||
arraysForConcat.add(argument)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arraysForConcat.isNotEmpty() || concatElements.isEmpty()) {
|
||||
concatElements.add(JsArrayLiteral(arraysForConcat))
|
||||
}
|
||||
|
||||
return concatElements.singleOrNull()
|
||||
?: JsInvocation(
|
||||
JsNameRef("concat", concatElements.first()),
|
||||
concatElements.drop(1)
|
||||
)
|
||||
}
|
||||
|
||||
fun IrFunction.varargParameterIndex() = valueParameters.indexOfFirst { it.varargElementType != null }
|
||||
|
||||
fun translateCallArguments(
|
||||
expression: IrMemberAccessExpression<*>,
|
||||
expression: IrMemberAccessExpression<IrFunctionSymbol>,
|
||||
context: JsGenerationContext,
|
||||
transformer: IrElementToJsExpressionTransformer,
|
||||
): List<JsExpression> {
|
||||
val size = expression.valueArgumentsCount
|
||||
|
||||
val varargParameterIndex = expression.symbol.owner.realOverrideTarget.varargParameterIndex()
|
||||
|
||||
val validWithNullArgs = expression.validWithNullArgs()
|
||||
val arguments = (0 until size)
|
||||
.mapTo(ArrayList(size)) { index ->
|
||||
@@ -216,6 +254,16 @@ fun translateCallArguments(
|
||||
assert(validWithNullArgs)
|
||||
}
|
||||
}
|
||||
.mapIndexed { index, result ->
|
||||
val isEmptyExternalVararg = validWithNullArgs &&
|
||||
varargParameterIndex == index &&
|
||||
result is JsArrayLiteral &&
|
||||
result.expressions.isEmpty()
|
||||
|
||||
if (isEmptyExternalVararg) {
|
||||
null
|
||||
} else result
|
||||
}
|
||||
.dropLastWhile { it == null }
|
||||
.map { it ?: JsPrefixOperation(JsUnaryOperator.VOID, JsIntLiteral(1)) }
|
||||
|
||||
|
||||
@@ -109,20 +109,13 @@ fun jsFunctionSignature(declaration: IrFunction): Signature {
|
||||
require(declaration.dispatchReceiverParameter != null)
|
||||
|
||||
val declarationName = declaration.getJsNameOrKotlinName().asString()
|
||||
val stableName = StableNameSignature(declarationName)
|
||||
|
||||
if (declaration.origin == JsLoweredDeclarationOrigin.BRIDGE_TO_EXTERNAL_FUNCTION) {
|
||||
return stableName
|
||||
}
|
||||
if (declaration.isEffectivelyExternal()) {
|
||||
return stableName
|
||||
}
|
||||
if (declaration.getJsName() != null) {
|
||||
return stableName
|
||||
}
|
||||
// Handle names for special functions
|
||||
if (declaration is IrSimpleFunction && declaration.isMethodOfAny()) {
|
||||
return stableName
|
||||
val needsStableName = declaration.origin == JsLoweredDeclarationOrigin.BRIDGE_TO_EXTERNAL_FUNCTION ||
|
||||
declaration.hasStableJsName() ||
|
||||
(declaration as? IrSimpleFunction)?.isMethodOfAny() == true // Handle names for special functions
|
||||
|
||||
if (needsStableName) {
|
||||
return StableNameSignature(declarationName)
|
||||
}
|
||||
|
||||
val nameBuilder = StringBuilder()
|
||||
|
||||
@@ -15,11 +15,29 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun TODO(element: IrElement): Nothing = TODO(element::class.java.simpleName + " is not supported yet here")
|
||||
|
||||
fun IrFunction.hasStableJsName(): Boolean {
|
||||
val namedOrMissingGetter = when (this) {
|
||||
is IrSimpleFunction -> {
|
||||
val owner = correspondingPropertySymbol?.owner
|
||||
if (owner == null) {
|
||||
true
|
||||
} else {
|
||||
owner.getter?.getJsName() != null
|
||||
}
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
|
||||
return (isEffectivelyExternal() || getJsName() != null || parentClassOrNull?.isJsExport() == true) && namedOrMissingGetter
|
||||
}
|
||||
|
||||
fun IrFunction.isEqualsInheritedFromAny() =
|
||||
name == Name.identifier("equals") &&
|
||||
dispatchReceiverParameter != null &&
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.AnnotationCodegen.Companion.annotationClass
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.copyCorrespondingPropertyFrom
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||
@@ -156,27 +157,9 @@ class JvmCachedDeclarations(
|
||||
//
|
||||
// is supposed to allow using `I2.DefaultImpls.f` as if it was inherited from `I1.DefaultImpls`.
|
||||
// The classes are not actually related and `I2.DefaultImpls.f` is not a fake override but a bridge.
|
||||
val defaultImplsOrigin = when {
|
||||
!forCompatibilityMode && !interfaceFun.isFakeOverride ->
|
||||
when {
|
||||
interfaceFun.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ->
|
||||
interfaceFun.origin
|
||||
interfaceFun.origin.isSynthetic ->
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC
|
||||
else ->
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS
|
||||
}
|
||||
interfaceFun.resolveFakeOverride()!!.origin.isSynthetic ->
|
||||
if (forCompatibilityMode)
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
|
||||
else
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC
|
||||
else ->
|
||||
if (forCompatibilityMode)
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY
|
||||
else
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
|
||||
}
|
||||
val defaultImplsOrigin =
|
||||
if (!forCompatibilityMode && !interfaceFun.isFakeOverride) interfaceFun.origin
|
||||
else interfaceFun.resolveFakeOverride()!!.origin
|
||||
|
||||
// Interface functions are public or private, with one exception: clone in Cloneable, which is protected.
|
||||
// However, Cloneable has no DefaultImpls, so this merely replicates the incorrect behavior of the old backend.
|
||||
@@ -198,11 +181,12 @@ class JvmCachedDeclarations(
|
||||
typeParametersFromContext = parent.typeParameters
|
||||
).also {
|
||||
it.copyCorrespondingPropertyFrom(interfaceFun)
|
||||
if (it.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY &&
|
||||
!it.annotations.hasAnnotation(DeprecationResolver.JAVA_DEPRECATED)
|
||||
) {
|
||||
|
||||
if (forCompatibilityMode && !interfaceFun.resolveFakeOverride()!!.origin.isSynthetic) {
|
||||
context.createJvmIrBuilder(it.symbol).run {
|
||||
it.annotations += irCall(irSymbols.javaLangDeprecatedConstructorWithDeprecatedFlag)
|
||||
it.annotations = it.annotations
|
||||
.filterNot { it.annotationClass.hasEqualFqName(DeprecationResolver.JAVA_DEPRECATED) }
|
||||
.plus(irCall(irSymbols.javaLangDeprecatedConstructorWithDeprecatedFlag))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +216,7 @@ class JvmCachedDeclarations(
|
||||
assert(fakeOverride.isFakeOverride)
|
||||
val irClass = fakeOverride.parentAsClass
|
||||
context.irFactory.buildFun {
|
||||
origin = JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
|
||||
origin = JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE
|
||||
name = fakeOverride.name
|
||||
visibility = fakeOverride.visibility
|
||||
modality = fakeOverride.modality
|
||||
|
||||
@@ -11,13 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
|
||||
object DEFAULT_IMPLS : IrDeclarationOriginImpl("DEFAULT_IMPLS")
|
||||
object DEFAULT_IMPLS_WITH_MOVED_RECEIVERS : IrDeclarationOriginImpl("STATIC_WITH_MOVED_RECEIVERS")
|
||||
object DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC :
|
||||
IrDeclarationOriginImpl("STATIC_WITH_MOVED_RECEIVERS_SYNTHETIC", isSynthetic = true)
|
||||
object DEFAULT_IMPLS_BRIDGE : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE")
|
||||
object DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY")
|
||||
object DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC", isSynthetic = true)
|
||||
object DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC", isSynthetic = true)
|
||||
object SUPER_INTERFACE_METHOD_BRIDGE : IrDeclarationOriginImpl("SUPER_INTERFACE_METHOD_BRIDGE")
|
||||
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
||||
object LAMBDA_IMPL : IrDeclarationOriginImpl("LAMBDA_IMPL")
|
||||
object FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL", isSynthetic = true)
|
||||
@@ -28,10 +22,8 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object TO_ARRAY : IrDeclarationOriginImpl("TO_ARRAY")
|
||||
object JVM_STATIC_WRAPPER : IrDeclarationOriginImpl("JVM_STATIC_WRAPPER")
|
||||
object JVM_OVERLOADS_WRAPPER : IrDeclarationOriginImpl("JVM_OVERLOADS_WRAPPER")
|
||||
object SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS :
|
||||
IrDeclarationOriginImpl("SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS", isSynthetic = true)
|
||||
object SYNTHETIC_METHOD_FOR_TYPEALIAS_ANNOTATIONS :
|
||||
IrDeclarationOriginImpl("SYNTHETIC_METHOD_FOR_TYPEALIAS_ANNOTATIONS", isSynthetic = true)
|
||||
object SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS :
|
||||
IrDeclarationOriginImpl("SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS", isSynthetic = true)
|
||||
object GENERATED_PROPERTY_REFERENCE : IrDeclarationOriginImpl("GENERATED_PROPERTY_REFERENCE", isSynthetic = true)
|
||||
object GENERATED_MEMBER_IN_CALLABLE_REFERENCE : IrDeclarationOriginImpl("GENERATED_MEMBER_IN_CALLABLE_REFERENCE", isSynthetic = false)
|
||||
object ENUM_MAPPINGS_FOR_WHEN : IrDeclarationOriginImpl("ENUM_MAPPINGS_FOR_WHEN", isSynthetic = true)
|
||||
@@ -8,6 +8,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.ir.addChild
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -73,6 +75,7 @@ class JvmSymbols(
|
||||
"kotlin.coroutines.jvm.internal" -> kotlinCoroutinesJvmInternalPackage
|
||||
"kotlin.jvm.internal" -> kotlinJvmInternalPackage
|
||||
"kotlin.jvm.functions" -> kotlinJvmFunctionsPackage
|
||||
"kotlin.jvm" -> kotlinJvmPackage
|
||||
"kotlin.reflect" -> kotlinReflectPackage
|
||||
"java.lang" -> javaLangPackage
|
||||
else -> error("Other packages are not supported yet: $fqName")
|
||||
@@ -392,6 +395,12 @@ class JvmSymbols(
|
||||
}
|
||||
}
|
||||
|
||||
val jvmInlineAnnotation: IrClassSymbol = createClass(JVM_INLINE_ANNOTATION_FQ_NAME, ClassKind.ANNOTATION_CLASS).apply {
|
||||
owner.addConstructor {
|
||||
isPrimary = true
|
||||
}
|
||||
}
|
||||
|
||||
private data class PropertyReferenceKey(
|
||||
val mutable: Boolean,
|
||||
val parameterCount: Int,
|
||||
|
||||
@@ -365,7 +365,7 @@ class ClassCodegen private constructor(
|
||||
|
||||
when (val metadata = method.metadata) {
|
||||
is MetadataSource.Property -> {
|
||||
assert(method.isSyntheticMethodForProperty) {
|
||||
assert(method.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS) {
|
||||
"MetadataSource.Property on IrFunction should only be used for synthetic \$annotations methods: ${method.render()}"
|
||||
}
|
||||
metadataSerializer.bindMethodMetadata(metadata, Method(node.name, node.desc))
|
||||
@@ -457,9 +457,8 @@ private val IrClass.flags: Int
|
||||
|
||||
private fun IrField.computeFieldFlags(context: JvmBackendContext, languageVersionSettings: LanguageVersionSettings): Int =
|
||||
origin.flags or visibility.flags or
|
||||
(if (isDeprecatedCallable ||
|
||||
correspondingPropertySymbol?.owner?.isDeprecatedCallable == true ||
|
||||
shouldHaveSpecialDeprecationFlag(context)
|
||||
(if (isDeprecatedCallable(context) ||
|
||||
correspondingPropertySymbol?.owner?.isDeprecatedCallable(context) == true
|
||||
) Opcodes.ACC_DEPRECATED else 0) or
|
||||
(if (isFinal) Opcodes.ACC_FINAL else 0) or
|
||||
(if (isStatic) Opcodes.ACC_STATIC else 0) or
|
||||
@@ -475,10 +474,6 @@ private fun IrField.isPrivateCompanionFieldInInterface(languageVersionSettings:
|
||||
parentAsClass.isJvmInterface &&
|
||||
DescriptorVisibilities.isPrivate(parentAsClass.companionObject()!!.visibility)
|
||||
|
||||
fun IrField.shouldHaveSpecialDeprecationFlag(context: JvmBackendContext): Boolean {
|
||||
return annotations.any { it.symbol == context.ir.symbols.javaLangDeprecatedConstructorWithDeprecatedFlag }
|
||||
}
|
||||
|
||||
private val IrDeclarationOrigin.flags: Int
|
||||
get() = (if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
|
||||
(if (this == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) Opcodes.ACC_ENUM else 0)
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.isMultifileBridge
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
||||
@@ -146,10 +145,7 @@ internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspen
|
||||
origin != JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER &&
|
||||
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR &&
|
||||
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR &&
|
||||
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE &&
|
||||
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY &&
|
||||
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC &&
|
||||
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC &&
|
||||
origin != JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE &&
|
||||
origin != IrDeclarationOrigin.BRIDGE &&
|
||||
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
|
||||
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
|
||||
|
||||
@@ -293,8 +293,9 @@ class ExpressionCodegen(
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
|
||||
// Although these are accessible from Java, the functions they bridge to already have the assertions.
|
||||
irFunction.origin == IrDeclarationOrigin.BRIDGE_SPECIAL ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE ||
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER ||
|
||||
irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB ||
|
||||
irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.CONTINUATION_CLASS ||
|
||||
irFunction.parentAsClass.origin == JvmLoweredDeclarationOrigin.SUSPEND_LAMBDA ||
|
||||
irFunction.isMultifileBridge()
|
||||
|
||||
@@ -118,7 +118,7 @@ class FunctionCodegen(
|
||||
|
||||
private fun shouldGenerateAnnotationsOnValueParameters(): Boolean =
|
||||
when {
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS ->
|
||||
irFunction.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS ->
|
||||
false
|
||||
irFunction is IrConstructor && irFunction.parentAsClass.shouldNotGenerateConstructorParameterAnnotations() ->
|
||||
// Not generating parameter annotations for default stubs fixes KT-7892, though
|
||||
@@ -146,7 +146,7 @@ class FunctionCodegen(
|
||||
private fun IrFunction.calculateMethodFlags(): Int {
|
||||
if (origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
|
||||
return getVisibilityForDefaultArgumentStub() or Opcodes.ACC_SYNTHETIC or
|
||||
(if (isDeprecatedFunction) Opcodes.ACC_DEPRECATED else 0) or
|
||||
(if (isDeprecatedFunction(context)) Opcodes.ACC_DEPRECATED else 0) or
|
||||
(if (this is IrConstructor) 0 else Opcodes.ACC_STATIC)
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ class FunctionCodegen(
|
||||
val isSynchronized = hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
|
||||
|
||||
return getVisibilityAccessFlag() or modalityFlag or
|
||||
(if (isDeprecatedFunction) Opcodes.ACC_DEPRECATED else 0) or
|
||||
(if (isDeprecatedFunction(context)) Opcodes.ACC_DEPRECATED else 0) or
|
||||
(if (isStatic) Opcodes.ACC_STATIC else 0) or
|
||||
(if (isVararg) Opcodes.ACC_VARARGS else 0) or
|
||||
(if (isExternal) Opcodes.ACC_NATIVE else 0) or
|
||||
|
||||
@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.ValueKind
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||
import org.jetbrains.kotlin.ir.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
@@ -161,6 +161,9 @@ class IrInlineCodegen(
|
||||
::IrDefaultLambda
|
||||
)
|
||||
}
|
||||
|
||||
override fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean =
|
||||
((memberDescriptor as IrBasedDeclarationDescriptor<*>).owner as IrMemberWithContainerSource).parentClassId != null
|
||||
}
|
||||
|
||||
class IrExpressionLambdaImpl(
|
||||
|
||||
@@ -53,6 +53,10 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
|
||||
}
|
||||
|
||||
private fun computeClassInternalName(irClass: IrClass): StringBuilder {
|
||||
context.getLocalClassType(irClass)?.internalName?.let {
|
||||
return StringBuilder(it)
|
||||
}
|
||||
|
||||
val shortName = SpecialNames.safeIdentifier(irClass.name).identifier
|
||||
|
||||
when (val parent = irClass.parent) {
|
||||
@@ -73,11 +77,6 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
|
||||
}
|
||||
}
|
||||
|
||||
val localClassType = context.getLocalClassType(irClass)
|
||||
if (localClassType != null) {
|
||||
return StringBuilder(localClassType.internalName)
|
||||
}
|
||||
|
||||
error(
|
||||
"Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" +
|
||||
"Ensure that any lowering that transforms elements with local class info (classes, function references) " +
|
||||
|
||||
@@ -187,10 +187,7 @@ class JvmSignatureClashDetector(
|
||||
IrDeclarationOrigin.BRIDGE_SPECIAL,
|
||||
IrDeclarationOrigin.IR_BUILTINS_STUB,
|
||||
JvmLoweredDeclarationOrigin.TO_ARRAY,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
|
||||
JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE,
|
||||
)
|
||||
|
||||
val PREDEFINED_SIGNATURES = listOf(
|
||||
|
||||
@@ -127,10 +127,10 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
originalForDefaultAdapter?.isInvisibleInMultifilePart() == true)
|
||||
|
||||
private fun IrSimpleFunction.getInternalFunctionForManglingIfNeeded(): IrSimpleFunction? {
|
||||
if (origin != JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR &&
|
||||
visibility == DescriptorVisibilities.INTERNAL &&
|
||||
!isPublishedApi() &&
|
||||
!isSyntheticMethodForProperty
|
||||
if (visibility == DescriptorVisibilities.INTERNAL &&
|
||||
origin != JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR &&
|
||||
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS &&
|
||||
!isPublishedApi()
|
||||
) {
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -14,16 +14,17 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.FrameMapBase
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.SourceInfo
|
||||
import org.jetbrains.kotlin.codegen.classFileContainsMethod
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -344,19 +344,16 @@ fun IrClass.isOptionalAnnotationClass(): Boolean =
|
||||
val IrDeclaration.isAnnotatedWithDeprecated: Boolean
|
||||
get() = annotations.hasAnnotation(FqNames.deprecated)
|
||||
|
||||
val IrDeclaration.isDeprecatedCallable: Boolean
|
||||
get() = isAnnotatedWithDeprecated || origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY
|
||||
internal fun IrDeclaration.isDeprecatedCallable(context: JvmBackendContext): Boolean =
|
||||
isAnnotatedWithDeprecated ||
|
||||
annotations.any { it.symbol == context.ir.symbols.javaLangDeprecatedConstructorWithDeprecatedFlag }
|
||||
|
||||
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
|
||||
// moved to DefaultImpls, origin is changed to DEFAULT_IMPLS
|
||||
// TODO: Fix origin somehow
|
||||
val IrFunction.isSyntheticMethodForProperty: Boolean
|
||||
get() = name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)
|
||||
|
||||
val IrFunction.isDeprecatedFunction: Boolean
|
||||
get() = isSyntheticMethodForProperty || isDeprecatedCallable ||
|
||||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isDeprecatedCallable == true ||
|
||||
isAccessorForDeprecatedPropertyImplementedByDelegation
|
||||
internal fun IrFunction.isDeprecatedFunction(context: JvmBackendContext): Boolean =
|
||||
origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS ||
|
||||
isDeprecatedCallable(context) ||
|
||||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isDeprecatedCallable(context) == true ||
|
||||
isAccessorForDeprecatedPropertyImplementedByDelegation ||
|
||||
isAccessorForDeprecatedJvmStaticProperty(context)
|
||||
|
||||
private val IrFunction.isAccessorForDeprecatedPropertyImplementedByDelegation: Boolean
|
||||
get() =
|
||||
@@ -364,9 +361,20 @@ private val IrFunction.isAccessorForDeprecatedPropertyImplementedByDelegation: B
|
||||
this is IrSimpleFunction &&
|
||||
correspondingPropertySymbol != null &&
|
||||
overriddenSymbols.any {
|
||||
it.owner.correspondingPropertySymbol?.owner?.isDeprecatedCallable == true
|
||||
it.owner.correspondingPropertySymbol?.owner?.isAnnotatedWithDeprecated == true
|
||||
}
|
||||
|
||||
private fun IrFunction.isAccessorForDeprecatedJvmStaticProperty(context: JvmBackendContext): Boolean {
|
||||
if (origin != JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER) return false
|
||||
val irExpressionBody = this.body as? IrExpressionBody
|
||||
?: throw AssertionError("IrExpressionBody expected for JvmStatic wrapper:\n${this.dump()}")
|
||||
val irCall = irExpressionBody.expression as? IrCall
|
||||
?: throw AssertionError("IrCall expected inside JvmStatic wrapper:\n${this.dump()}")
|
||||
val callee = irCall.symbol.owner
|
||||
val property = callee.correspondingPropertySymbol?.owner ?: return false
|
||||
return property.isDeprecatedCallable(context)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
val IrDeclaration.psiElement: PsiElement?
|
||||
get() = (descriptor as? DeclarationDescriptorWithSource)?.psiElement
|
||||
@@ -379,7 +387,7 @@ fun IrSimpleType.isRawType(): Boolean =
|
||||
hasAnnotation(JvmGeneratorExtensions.RAW_TYPE_ANNOTATION_FQ_NAME)
|
||||
|
||||
internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendContext, name: String): Boolean? {
|
||||
val classId = (function.parent as? IrClass)?.classId ?: (function.containerSource as? JvmPackagePartSource)?.classId ?: return null
|
||||
val classId = function.parentClassId ?: return null
|
||||
val originalDescriptor = context.methodSignatureMapper.mapSignatureWithGeneric(function).asmMethod.descriptor
|
||||
val descriptor = if (function.isSuspend)
|
||||
listOf(*Type.getArgumentTypes(originalDescriptor), Type.getObjectType("kotlin/coroutines/Continuation"))
|
||||
@@ -388,6 +396,9 @@ internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendCo
|
||||
return classFileContainsMethod(classId, context.state, Method(name, descriptor))
|
||||
}
|
||||
|
||||
val IrMemberWithContainerSource.parentClassId: ClassId?
|
||||
get() = (containerSource as? JvmPackagePartSource)?.classId ?: (parent as? IrClass)?.classId
|
||||
|
||||
// Translated into IR-based terms from classifierDescriptor?.classId
|
||||
val IrClass.classId: ClassId?
|
||||
get() = when (val parent = parent) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.jvm.localDeclarationsPhase
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -208,10 +209,8 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
|
||||
}
|
||||
}
|
||||
|
||||
private fun Name.toSuspendImplementationName() = when {
|
||||
isSpecial -> Name.special(asString() + SUSPEND_IMPL_NAME_SUFFIX)
|
||||
else -> Name.identifier(asString() + SUSPEND_IMPL_NAME_SUFFIX)
|
||||
}
|
||||
private fun Name.toSuspendImplementationName(): Name =
|
||||
Name.guessByFirstCharacter(asString() + SUSPEND_IMPL_NAME_SUFFIX)
|
||||
|
||||
private fun createStaticSuspendImpl(irFunction: IrSimpleFunction): IrSimpleFunction {
|
||||
// Create static suspend impl method.
|
||||
@@ -220,6 +219,8 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
|
||||
irFunction.name.toSuspendImplementationName(),
|
||||
irFunction,
|
||||
origin = JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION,
|
||||
modality = Modality.OPEN,
|
||||
visibility = JavaDescriptorVisibilities.PACKAGE_VISIBILITY,
|
||||
isFakeOverride = false,
|
||||
copyMetadata = false
|
||||
)
|
||||
@@ -341,7 +342,7 @@ internal fun IrFunction.suspendFunctionOriginal(): IrFunction =
|
||||
if (this is IrSimpleFunction && isSuspend &&
|
||||
!isStaticInlineClassReplacement &&
|
||||
!isOrOverridesDefaultParameterStub() &&
|
||||
!isDefaultImplsFunction
|
||||
parentAsClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS
|
||||
)
|
||||
attributeOwnerId as IrFunction
|
||||
else this
|
||||
@@ -354,19 +355,6 @@ private fun IrSimpleFunction.isOrOverridesDefaultParameterStub(): Boolean =
|
||||
{ it.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER }
|
||||
)
|
||||
|
||||
private val defaultImplsOrigins = setOf(
|
||||
IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC,
|
||||
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
|
||||
)
|
||||
|
||||
private val IrSimpleFunction.isDefaultImplsFunction: Boolean
|
||||
get() = origin in defaultImplsOrigins
|
||||
|
||||
private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction {
|
||||
require(this.isSuspend && this is IrSimpleFunction)
|
||||
return factory.buildFun {
|
||||
@@ -385,7 +373,7 @@ private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): Ir
|
||||
val substitutionMap = makeTypeParameterSubstitutionMap(this, function)
|
||||
function.copyReceiverParametersFrom(this, substitutionMap)
|
||||
|
||||
if (origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE) {
|
||||
if (origin != JvmLoweredDeclarationOrigin.SUPER_INTERFACE_METHOD_BRIDGE) {
|
||||
function.overriddenSymbols +=
|
||||
overriddenSymbols.map { it.owner.suspendFunctionViewOrStub(context).symbol as IrSimpleFunctionSymbol }
|
||||
}
|
||||
|
||||
@@ -188,8 +188,16 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
return false
|
||||
|
||||
// We don't produce bridges for abstract functions in interfaces.
|
||||
if (irFunction.isJvmAbstract(context.state.jvmDefaultMode))
|
||||
return !irFunction.parentAsClass.isJvmInterface
|
||||
if (irFunction.isJvmAbstract(context.state.jvmDefaultMode)) {
|
||||
if (irFunction.parentAsClass.isJvmInterface) {
|
||||
// If function requires a special bridge, we should record it for generic signatures generation.
|
||||
if (irFunction.specialBridgeOrNull != null) {
|
||||
context.functionsWithSpecialBridges.add(irFunction)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Finally, the JVM backend also ignores concrete fake overrides whose implementation is directly inherited from an interface.
|
||||
// This is sound, since we do not generate type-specialized versions of fake overrides and if the method
|
||||
|
||||
@@ -57,16 +57,21 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
|
||||
at(expression)
|
||||
irCall(functionNInvokeFun).apply {
|
||||
dispatchReceiver = irImplicitCast(
|
||||
expression.dispatchReceiver!!,
|
||||
expression.dispatchReceiver!!.transformVoid(),
|
||||
this@FunctionNVarargBridgeLowering.context.ir.symbols.functionN.defaultType
|
||||
)
|
||||
putValueArgument(0, irArray(irSymbols.array.typeWith(context.irBuiltIns.anyNType)) {
|
||||
(0 until expression.valueArgumentsCount).forEach { +expression.getValueArgument(it)!! }
|
||||
(0 until expression.valueArgumentsCount).forEach {
|
||||
+expression.getValueArgument(it)!!.transformVoid()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.transformVoid() =
|
||||
transform(this@FunctionNVarargBridgeLowering, null)
|
||||
|
||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
val bigArityFunctionSuperTypes = declaration.superTypes.filterIsInstance<IrSimpleType>().filter {
|
||||
it.isFunctionType && it.arguments.size > BuiltInFunctionArity.BIG_ARITY
|
||||
@@ -76,26 +81,22 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
|
||||
return super.visitClassNew(declaration)
|
||||
declaration.transformChildrenVoid(this)
|
||||
|
||||
// Note that we allow classes with multiple function supertypes, so long as only one
|
||||
// of them has more than 22 arguments.
|
||||
// TODO: Add a proper diagnostic message in the frontend
|
||||
assert(bigArityFunctionSuperTypes.size == 1) {
|
||||
"Class has multiple big-arity function super types: ${bigArityFunctionSuperTypes.joinToString { it.render() }}"
|
||||
}
|
||||
// Note that we allow classes with multiple function supertypes, so long as only one of them has more than 22 arguments.
|
||||
// Code below will generate one 'invoke' for each function supertype,
|
||||
// which will cause conflicting inherited JVM signatures error diagnostics in case of multiple big arity function supertypes.
|
||||
for (superType in bigArityFunctionSuperTypes) {
|
||||
declaration.superTypes -= superType
|
||||
declaration.superTypes += context.ir.symbols.functionN.typeWith(
|
||||
(superType.arguments.last() as IrTypeProjection).type
|
||||
)
|
||||
|
||||
// Fix super class
|
||||
val superType = bigArityFunctionSuperTypes.single()
|
||||
declaration.superTypes -= superType
|
||||
declaration.superTypes += context.ir.symbols.functionN.typeWith(
|
||||
(superType.arguments.last() as IrTypeProjection).type
|
||||
)
|
||||
|
||||
// Add vararg invoke bridge
|
||||
val invokeFunction = declaration.functions.single {
|
||||
it.name.asString() == "invoke" && it.valueParameters.size == superType.arguments.size - if (it.isSuspend) 0 else 1
|
||||
// Add vararg invoke bridge
|
||||
val invokeFunction = declaration.functions.single {
|
||||
it.name.asString() == "invoke" && it.valueParameters.size == superType.arguments.size - if (it.isSuspend) 0 else 1
|
||||
}
|
||||
invokeFunction.overriddenSymbols = emptyList()
|
||||
declaration.addBridge(invokeFunction, functionNInvokeFun.owner)
|
||||
}
|
||||
invokeFunction.overriddenSymbols = emptyList()
|
||||
declaration.addBridge(invokeFunction, functionNInvokeFun.owner)
|
||||
|
||||
return declaration
|
||||
}
|
||||
@@ -123,7 +124,7 @@ private class FunctionNVarargBridgeLowering(val context: JvmBackendContext) :
|
||||
irInt(argumentCount)
|
||||
),
|
||||
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
|
||||
putValueArgument(0, irString("Expected ${argumentCount} arguments"))
|
||||
putValueArgument(0, irString("Expected $argumentCount arguments"))
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
|
||||
if (!useOptimizedSuperClass) {
|
||||
// This is the case of a fun interface wrapper over a (maybe adapted) function reference,
|
||||
// with `-Xno-optimized-callable-referenced` enabled. We can't use constructors of FunctionReferenceImpl,
|
||||
// with `-Xno-optimized-callable-references` enabled. We can't use constructors of FunctionReferenceImpl,
|
||||
// so we'd need to basically generate a full class for a reference inheriting from FunctionReference,
|
||||
// effectively disabling the optimization of fun interface wrappers over references.
|
||||
// This scenario is probably not very popular because it involves using equals/hashCode on function references
|
||||
@@ -254,8 +254,11 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
// TODO: generate getFunctionDelegate, equals and hashCode properly in this case
|
||||
functionReferenceClass.addFunction("equals", backendContext.irBuiltIns.booleanType, Modality.ABSTRACT).apply {
|
||||
addValueParameter("other", backendContext.irBuiltIns.anyNType)
|
||||
overriddenSymbols = listOf(functionSuperClass.functions.single { isEqualsFromAny(it.owner) })
|
||||
}
|
||||
functionReferenceClass.addFunction("hashCode", backendContext.irBuiltIns.intType, Modality.ABSTRACT).apply {
|
||||
overriddenSymbols = listOf(functionSuperClass.functions.single { isHashCodeFromAny(it.owner) })
|
||||
}
|
||||
functionReferenceClass.addFunction("hashCode", backendContext.irBuiltIns.intType, Modality.ABSTRACT)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -274,6 +277,13 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
}.generate()
|
||||
}
|
||||
|
||||
private fun isEqualsFromAny(f: IrSimpleFunction): Boolean =
|
||||
f.name.asString() == "equals" && f.extensionReceiverParameter == null &&
|
||||
f.valueParameters.singleOrNull()?.type?.isNullableAny() == true
|
||||
|
||||
private fun isHashCodeFromAny(f: IrSimpleFunction): Boolean =
|
||||
f.name.asString() == "hashCode" && f.extensionReceiverParameter == null && f.valueParameters.isEmpty()
|
||||
|
||||
private fun createConstructor(): IrConstructor =
|
||||
functionReferenceClass.addConstructor {
|
||||
origin = JvmLoweredDeclarationOrigin.GENERATED_MEMBER_IN_CALLABLE_REFERENCE
|
||||
|
||||
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.common.phaser.makeCustomPhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isSyntheticMethodForProperty
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -145,6 +144,9 @@ private fun generateMultifileFacades(
|
||||
for (member in partClass.declarations) {
|
||||
if (member !is IrSimpleFunction) continue
|
||||
|
||||
// KT-43519 Don't generate delegates for external methods
|
||||
if (member.isExternal) continue
|
||||
|
||||
val correspondingProperty = member.correspondingPropertySymbol?.owner
|
||||
if (member.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) ||
|
||||
correspondingProperty?.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) == true
|
||||
@@ -220,7 +222,8 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded(
|
||||
name == StaticInitializersLowering.clinitName ||
|
||||
origin == JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ||
|
||||
// $annotations methods in the facade are only needed for const properties.
|
||||
(isSyntheticMethodForProperty && (metadata as? MetadataSource.Property)?.isConst != true)
|
||||
(origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS &&
|
||||
(metadata as? MetadataSource.Property)?.isConst != true)
|
||||
) return null
|
||||
|
||||
val function = context.irFactory.buildFun {
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
@@ -260,24 +259,18 @@ private class InterfaceObjectCallsLowering(val context: JvmBackendContext) : IrE
|
||||
* interface implementation should be generated into the class containing the fake override; or null if the given function is not a fake
|
||||
* override of any interface implementation or such method was already generated into the superclass or is a method from Any.
|
||||
*/
|
||||
private fun isDefaultImplsBridge(f: IrSimpleFunction) =
|
||||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
|
||||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY ||
|
||||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC ||
|
||||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
|
||||
|
||||
internal fun IrSimpleFunction.findInterfaceImplementation(jvmDefaultMode: JvmDefaultMode): IrSimpleFunction? {
|
||||
if (!isFakeOverride) return null
|
||||
parent.let { if (it is IrClass && it.isJvmInterface) return null }
|
||||
|
||||
val implementation = resolveFakeOverride(toSkip = ::isDefaultImplsBridge) ?: return null
|
||||
val implementation = resolveFakeOverride() ?: return null
|
||||
|
||||
// Only generate interface delegation for functions immediately inherited from an interface.
|
||||
// (Otherwise, delegation will be present in the parent class)
|
||||
if (overriddenSymbols.any {
|
||||
!it.owner.parentAsClass.isInterface &&
|
||||
it.owner.modality != Modality.ABSTRACT &&
|
||||
it.owner.resolveFakeOverride(toSkip = ::isDefaultImplsBridge) == implementation
|
||||
it.owner.resolveFakeOverride() == implementation
|
||||
}) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
|
||||
*/
|
||||
(DescriptorVisibilities.isPrivate(function.visibility) && !function.isCompiledToJvmDefault(jvmDefaultMode))
|
||||
|| (function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER && !function.isCompiledToJvmDefault(jvmDefaultMode))
|
||||
|| function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS -> {
|
||||
|| function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS -> {
|
||||
val defaultImpl = createDefaultImpl(function)
|
||||
defaultImpl.body = function.moveBodyTo(defaultImpl)
|
||||
removedFunctions[function.symbol] = defaultImpl.symbol
|
||||
@@ -175,7 +175,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
|
||||
private fun handleAnnotationClass(irClass: IrClass) {
|
||||
// We produce $DefaultImpls for annotation classes only to move $annotations methods (for property annotations) there.
|
||||
val annotationsMethods =
|
||||
irClass.functions.filter { it.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS }
|
||||
irClass.functions.filter { it.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS }
|
||||
if (annotationsMethods.none()) return
|
||||
|
||||
for (function in annotationsMethods) {
|
||||
|
||||
@@ -28,10 +28,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
@@ -42,6 +39,7 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
val jvmInlineClassPhase = makeIrFilePhase(
|
||||
@@ -98,11 +96,21 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
|
||||
buildBoxFunction(declaration)
|
||||
buildUnboxFunction(declaration)
|
||||
buildSpecializedEqualsMethod(declaration)
|
||||
addJvmInlineAnnotation(declaration)
|
||||
}
|
||||
|
||||
return declaration
|
||||
}
|
||||
|
||||
private fun addJvmInlineAnnotation(declaration: IrClass) {
|
||||
if (declaration.hasAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME)) return
|
||||
val constructor = context.ir.symbols.jvmInlineAnnotation.constructors.first()
|
||||
declaration.annotations = declaration.annotations + IrConstructorCallImpl.fromSymbolOwner(
|
||||
constructor.owner.returnType,
|
||||
constructor
|
||||
)
|
||||
}
|
||||
|
||||
private fun transformFunctionFlat(function: IrFunction): List<IrDeclaration>? {
|
||||
if (function.isPrimaryInlineClassConstructor)
|
||||
return null
|
||||
|
||||
@@ -129,7 +129,7 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
||||
|
||||
private fun createSyntheticMethodForAnnotations(declaration: IrProperty): IrSimpleFunction =
|
||||
backendContext.irFactory.buildFun {
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS
|
||||
name = Name.identifier(computeSyntheticMethodName(declaration))
|
||||
visibility = declaration.visibility
|
||||
modality = Modality.OPEN
|
||||
@@ -152,8 +152,10 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
||||
private fun IrType.erasePropertyAnnotationsExtensionReceiverType(): IrType {
|
||||
// Use raw type of extension receiver to avoid generic signature,
|
||||
// which should not be generated for '...$annotations' method.
|
||||
val classifier = classifierOrFail
|
||||
return if (this is IrSimpleType && isArray()) {
|
||||
if (this !is IrSimpleType) {
|
||||
throw AssertionError("Unexpected property receiver type: $this")
|
||||
}
|
||||
val erasedType = if (isArray()) {
|
||||
when (val arg0 = arguments[0]) {
|
||||
is IrStarProjection -> {
|
||||
// 'Array<*>' becomes 'Array<*>'
|
||||
@@ -171,6 +173,9 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
||||
} else {
|
||||
classifier.typeWith()
|
||||
}
|
||||
return erasedType
|
||||
.withHasQuestionMark(this.hasQuestionMark)
|
||||
.addAnnotations(this.annotations)
|
||||
}
|
||||
|
||||
private fun computeSyntheticMethodName(property: IrProperty): String {
|
||||
|
||||
@@ -14,8 +14,9 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
|
||||
internal val jvmStandardLibraryBuiltInsPhase = makeIrFilePhase(
|
||||
@@ -60,11 +61,14 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
||||
// Originals are so far only instance methods, and the replacements are
|
||||
// statics, so we copy dispatch receivers to a value argument if needed.
|
||||
// If we can't coerce arguments to required types, keep original expression (see below).
|
||||
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol): IrCall =
|
||||
IrCallImpl.fromSymbolOwner(
|
||||
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol): IrExpression {
|
||||
val expectedType = this.type
|
||||
val intrinsicCallType = replacement.owner.returnType
|
||||
|
||||
val intrinsicCall = IrCallImpl.fromSymbolOwner(
|
||||
startOffset,
|
||||
endOffset,
|
||||
type,
|
||||
intrinsicCallType,
|
||||
replacement
|
||||
).also { newCall ->
|
||||
var valueArgumentOffset = 0
|
||||
@@ -81,6 +85,15 @@ class JvmStandardLibraryBuiltInsLowering(val context: JvmBackendContext) : FileL
|
||||
}
|
||||
}
|
||||
|
||||
// Coerce intrinsic call result from JVM 'int' or 'long' to corresponding unsigned type if required.
|
||||
return if (intrinsicCallType.isInt() || intrinsicCallType.isLong()) {
|
||||
intrinsicCall.coerceIfPossible(expectedType)
|
||||
?: throw AssertionError("Can't coerce '${intrinsicCallType.render()}' to '${expectedType.render()}'")
|
||||
} else {
|
||||
intrinsicCall
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.coerceIfPossible(toType: IrType): IrExpression? {
|
||||
// TODO maybe UnsafeCoerce could handle types with different, but coercible underlying representations.
|
||||
// See KT-43286 and related tests for details.
|
||||
|
||||
@@ -63,7 +63,7 @@ private class JvmStaticInCompanionLowering(val context: JvmBackendContext) : IrE
|
||||
.filter {
|
||||
it.isJvmStaticDeclaration() &&
|
||||
it.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER &&
|
||||
it.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
||||
it.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS
|
||||
}
|
||||
.forEach { declaration ->
|
||||
val jvmStaticFunction = declaration as IrSimpleFunction
|
||||
@@ -171,4 +171,5 @@ private class MakeCallsStatic(val context: JvmBackendContext) : IrElementTransfo
|
||||
|
||||
private fun IrDeclaration.isJvmStaticDeclaration(): Boolean =
|
||||
hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) ||
|
||||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true
|
||||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true ||
|
||||
(this as? IrProperty)?.getter?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true
|
||||
|
||||
@@ -156,23 +156,29 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem
|
||||
val wrapper: IrFunction
|
||||
)
|
||||
|
||||
private fun propertyReferenceKind(mutable: Boolean, i: Int) = PropertyReferenceKind(
|
||||
context.ir.symbols.getPropertyReferenceClass(mutable, i, false),
|
||||
context.ir.symbols.getPropertyReferenceClass(mutable, i, true),
|
||||
context.ir.symbols.reflection.owner.functions.single { it.name.asString() == (if (mutable) "mutableProperty$i" else "property$i") }
|
||||
)
|
||||
private fun propertyReferenceKind(expression: IrCallableReference<*>, mutable: Boolean, i: Int): PropertyReferenceKind {
|
||||
check(i in 0..2) { "Incorrect number of receivers ($i) for property reference: ${expression.render()}" }
|
||||
return PropertyReferenceKind(
|
||||
context.ir.symbols.getPropertyReferenceClass(mutable, i, false),
|
||||
context.ir.symbols.getPropertyReferenceClass(mutable, i, true),
|
||||
context.ir.symbols.reflection.owner.functions.single {
|
||||
it.name.asString() == (if (mutable) "mutableProperty$i" else "property$i")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun propertyReferenceKindFor(expression: IrMemberAccessExpression<*>): PropertyReferenceKind =
|
||||
private fun propertyReferenceKindFor(expression: IrCallableReference<*>): PropertyReferenceKind =
|
||||
expression.getter?.owner?.let {
|
||||
val boundReceivers = listOfNotNull(expression.dispatchReceiver, expression.extensionReceiver).size
|
||||
val needReceivers = listOfNotNull(it.dispatchReceiverParameter, it.extensionReceiverParameter).size
|
||||
// PropertyReference1 will swap the receivers if bound with the extension one, and PropertyReference0
|
||||
// has no way to bind two receivers at once.
|
||||
if (boundReceivers == 2 || (expression.extensionReceiver != null && needReceivers == 2))
|
||||
TODO("property reference with 2 receivers")
|
||||
propertyReferenceKind(expression.setter != null, needReceivers - boundReceivers)
|
||||
check(boundReceivers < 2 && (expression.extensionReceiver == null || needReceivers < 2)) {
|
||||
"Property reference with two receivers is not supported: ${expression.render()}"
|
||||
}
|
||||
propertyReferenceKind(expression, expression.setter != null, needReceivers - boundReceivers)
|
||||
} ?: expression.field?.owner?.let {
|
||||
propertyReferenceKind(!it.isFinal, if (it.isStatic || expression.dispatchReceiver != null) 0 else 1)
|
||||
propertyReferenceKind(expression, !it.isFinal, if (it.isStatic || expression.dispatchReceiver != null) 0 else 1)
|
||||
} ?: throw AssertionError("property has no getter and no field: ${expression.dump()}")
|
||||
|
||||
private data class PropertyInstance(val initializer: IrExpression, val index: Int)
|
||||
@@ -343,14 +349,15 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem
|
||||
fun IrBuilderWithScope.setCallArguments(call: IrCall, arguments: List<IrValueParameter>) {
|
||||
var index = 1
|
||||
call.copyTypeArgumentsFrom(expression)
|
||||
val hasBoundReceiver = expression.getBoundReceiver() != null
|
||||
call.dispatchReceiver = call.symbol.owner.dispatchReceiverParameter?.let {
|
||||
if (expression.dispatchReceiver != null)
|
||||
if (hasBoundReceiver)
|
||||
irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type)
|
||||
else
|
||||
irImplicitCast(irGet(arguments[index++]), it.type)
|
||||
}
|
||||
call.extensionReceiver = call.symbol.owner.extensionReceiverParameter?.let {
|
||||
if (expression.extensionReceiver != null)
|
||||
if (hasBoundReceiver)
|
||||
irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type)
|
||||
else
|
||||
irImplicitCast(irGet(arguments[index++]), it.type)
|
||||
|
||||
@@ -588,7 +588,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
if (!withSuper && !declaration.visibility.isPrivate && !declaration.visibility.isProtected) return true
|
||||
|
||||
// `toArray` is always accessible cause mapped to public functions
|
||||
if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray(context) || symbolOwner.isGenericToArray(context))) {
|
||||
if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray() || symbolOwner.isGenericToArray(context))) {
|
||||
if (symbolOwner.parentAsClass.isCollectionSubClass) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addDispatchReceiver
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addTypeParameter
|
||||
@@ -75,7 +75,7 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
|
||||
}
|
||||
}
|
||||
|
||||
irClass.findOrCreate(indirectCollectionSubClass, { it.isNonGenericToArray(context) }) {
|
||||
irClass.findOrCreate(indirectCollectionSubClass, IrSimpleFunction::isNonGenericToArray) {
|
||||
irClass.addFunction {
|
||||
name = Name.identifier("toArray")
|
||||
origin = JvmLoweredDeclarationOrigin.TO_ARRAY
|
||||
@@ -132,7 +132,12 @@ internal fun IrSimpleFunction.isGenericToArray(context: JvmBackendContext): Bool
|
||||
returnType.isArrayOrNullableArrayOf(context, typeParameters[0].symbol) &&
|
||||
valueParameters[0].type.isArrayOrNullableArrayOf(context, typeParameters[0].symbol)
|
||||
|
||||
// Match `fun toArray(): Array<Any?>`
|
||||
internal fun IrSimpleFunction.isNonGenericToArray(context: JvmBackendContext): Boolean =
|
||||
// Match `fun toArray(): Array<...>`.
|
||||
// It would be more correct to check that the return type is erased to `Object[]`, however the old backend doesn't do that
|
||||
// (see `FunctionDescriptor.isNonGenericToArray` and KT-43111).
|
||||
internal fun IrSimpleFunction.isNonGenericToArray(): Boolean =
|
||||
name.asString() == "toArray" && typeParameters.isEmpty() && valueParameters.isEmpty() &&
|
||||
extensionReceiverParameter == null && returnType.isArrayOrNullableArrayOf(context, context.irBuiltIns.anyClass)
|
||||
extensionReceiverParameter == null && returnType.isArrayOrNullableArray()
|
||||
|
||||
private fun IrType.isArrayOrNullableArray(): Boolean =
|
||||
this is IrSimpleType && (isArray() || isNullableArray())
|
||||
|
||||
@@ -45,7 +45,7 @@ class TypeAliasAnnotationMethodsLowering(val context: CommonBackendContext) :
|
||||
visibility = alias.visibility
|
||||
returnType = context.irBuiltIns.unitType
|
||||
modality = Modality.OPEN
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_TYPEALIAS_ANNOTATIONS
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS
|
||||
}.apply {
|
||||
body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||
annotations += alias.annotations
|
||||
|
||||
@@ -12,10 +12,12 @@ import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.classFileContainsMethod
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi.mangledNameFor
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
@@ -70,6 +72,8 @@ class MemoizedInlineClassReplacements(
|
||||
when {
|
||||
it.isRemoveAtSpecialBuiltinStub() ->
|
||||
null
|
||||
it.isInlineClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod() ->
|
||||
null
|
||||
it.origin == IrDeclarationOrigin.IR_BUILTINS_STUB ->
|
||||
createMethodReplacement(it)
|
||||
else ->
|
||||
@@ -94,6 +98,23 @@ class MemoizedInlineClassReplacements(
|
||||
valueParameters.size == 1 &&
|
||||
valueParameters[0].type.isInt()
|
||||
|
||||
private fun IrFunction.isInlineClassMemberFakeOverriddenFromJvmDefaultInterfaceMethod(): Boolean {
|
||||
if (this !is IrSimpleFunction) return false
|
||||
if (!this.isFakeOverride) return false
|
||||
val parentClass = parentClassOrNull ?: return false
|
||||
if (!parentClass.isInline) return false
|
||||
|
||||
val overridden = resolveFakeOverride() ?: return false
|
||||
if (!overridden.parentAsClass.isJvmInterface) return false
|
||||
if (overridden.modality == Modality.ABSTRACT) return false
|
||||
|
||||
// We have a non-abstract interface member.
|
||||
// It is a JVM default interface method if one of the following conditions are true:
|
||||
// - it is a Java method,
|
||||
// - it is a Kotlin function compiled to JVM default interface method.
|
||||
return overridden.isFromJava() || overridden.isCompiledToJvmDefault(context.state.jvmDefaultMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the box function for an inline class. Concretely, this is a synthetic
|
||||
* static function named "box-impl" which takes an unboxed value and returns
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
interface IrSymbolOwner : IrElement {
|
||||
val symbol: IrSymbol
|
||||
@@ -66,3 +67,7 @@ interface IrDeclarationWithName : IrDeclaration {
|
||||
interface IrOverridableMember : IrDeclarationWithVisibility, IrDeclarationWithName, IrSymbolOwner {
|
||||
val modality: Modality
|
||||
}
|
||||
|
||||
interface IrMemberWithContainerSource : IrDeclarationWithName {
|
||||
val containerSource: DeserializedContainerSource?
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user