mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-21 00:21:32 +00:00
Compare commits
195 Commits
native-too
...
build-1.2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fd6dcd063 | ||
|
|
3c86e40bcb | ||
|
|
16fb5f6901 | ||
|
|
181a8d7d6a | ||
|
|
3349976279 | ||
|
|
7a208c3e01 | ||
|
|
615f57f2fc | ||
|
|
a72ad8b267 | ||
|
|
1dea01a479 | ||
|
|
03ed4e39e3 | ||
|
|
e4af8dc7d8 | ||
|
|
4f2fdd1c01 | ||
|
|
8ccbbf71ec | ||
|
|
4266e50be8 | ||
|
|
a7c80f2df1 | ||
|
|
25ee67a644 | ||
|
|
42de05f3fa | ||
|
|
50c515deca | ||
|
|
17fc41e0f9 | ||
|
|
b52b07ec79 | ||
|
|
3e91346240 | ||
|
|
22d74276a0 | ||
|
|
65dad5eb74 | ||
|
|
59567c8012 | ||
|
|
2e88f5c47d | ||
|
|
c887b88ed9 | ||
|
|
f1a44ed1a4 | ||
|
|
30a2969887 | ||
|
|
3b968351bb | ||
|
|
0fc9bb3f4a | ||
|
|
de60c9b635 | ||
|
|
931ebb4c3c | ||
|
|
ece991639e | ||
|
|
bed26dc700 | ||
|
|
80f022c3d5 | ||
|
|
bbcb12ea4b | ||
|
|
92430fc63a | ||
|
|
38e9c86443 | ||
|
|
f0050930b5 | ||
|
|
da0a966d65 | ||
|
|
7bd5031eaf | ||
|
|
b1d0a5e807 | ||
|
|
71c5bf0b97 | ||
|
|
799fcc2606 | ||
|
|
7fd3fac122 | ||
|
|
2a721ea0f6 | ||
|
|
95d72d0a32 | ||
|
|
ba9f12b617 | ||
|
|
068859eece | ||
|
|
56bf1f895c | ||
|
|
15f33dd94a | ||
|
|
bf2aa5263e | ||
|
|
952163b2fb | ||
|
|
92407c509f | ||
|
|
686a3d631c | ||
|
|
f002e6030a | ||
|
|
d5906dd584 | ||
|
|
072804af52 | ||
|
|
6bc86bd42f | ||
|
|
fa51b962b8 | ||
|
|
1c2ac364c7 | ||
|
|
17454d3f9c | ||
|
|
576dfda3a8 | ||
|
|
ecb5d29130 | ||
|
|
3063de82aa | ||
|
|
1d67cd3b97 | ||
|
|
9bcc3cae79 | ||
|
|
80b6d84c72 | ||
|
|
7e9cf64754 | ||
|
|
49f2598907 | ||
|
|
ea7b344b80 | ||
|
|
d5286874bd | ||
|
|
ede3a34baa | ||
|
|
15eafc1513 | ||
|
|
b11abeed6a | ||
|
|
f1bdb48a76 | ||
|
|
25d0c57194 | ||
|
|
17312a305b | ||
|
|
56fdf2c735 | ||
|
|
0b4d9513eb | ||
|
|
be413e4fab | ||
|
|
a9d0e6d3da | ||
|
|
3a11767fae | ||
|
|
f837537cb6 | ||
|
|
35cf7c4db3 | ||
|
|
d1b6e8901a | ||
|
|
2d9ae6e93e | ||
|
|
93f4a4da10 | ||
|
|
5b3947da11 | ||
|
|
7497372f65 | ||
|
|
ad65fa8c45 | ||
|
|
eb6f652763 | ||
|
|
8ae17ecbcb | ||
|
|
847223683e | ||
|
|
0ffef64428 | ||
|
|
353076f596 | ||
|
|
25a66916a6 | ||
|
|
6649ef2740 | ||
|
|
609a6ca9bb | ||
|
|
4eb2fc66d0 | ||
|
|
062c4bf41d | ||
|
|
62a42130c8 | ||
|
|
c22f6dee4a | ||
|
|
e8fe788df6 | ||
|
|
54e9a2bb7b | ||
|
|
5f4f6ef863 | ||
|
|
0774ca415c | ||
|
|
0f718ec2d8 | ||
|
|
326e4a160f | ||
|
|
0e34ee5270 | ||
|
|
c97697d7a9 | ||
|
|
372f280578 | ||
|
|
1353cf879c | ||
|
|
f66f3c1fed | ||
|
|
4bd2504367 | ||
|
|
4992ca9179 | ||
|
|
c28877d23c | ||
|
|
1be28d6032 | ||
|
|
fdc0335b4a | ||
|
|
0fb183e302 | ||
|
|
dd0b267531 | ||
|
|
082c3e6767 | ||
|
|
16c6d63b10 | ||
|
|
b13e4535f5 | ||
|
|
aac71bf904 | ||
|
|
50e70e4638 | ||
|
|
465d5c077e | ||
|
|
5bdaef4983 | ||
|
|
8848d7a043 | ||
|
|
22c1907167 | ||
|
|
3a7c674957 | ||
|
|
a63aa5b7ca | ||
|
|
76ac65f723 | ||
|
|
60583e557f | ||
|
|
e2a632e326 | ||
|
|
ba2f28720f | ||
|
|
ed597e2da5 | ||
|
|
633c67ebf0 | ||
|
|
b1693acfcd | ||
|
|
83745010ba | ||
|
|
31d248c42d | ||
|
|
bede2e1c16 | ||
|
|
9b7450cfdb | ||
|
|
bd88e02172 | ||
|
|
b0e0460ee6 | ||
|
|
5ef54a2f03 | ||
|
|
87f4d0c5a4 | ||
|
|
c68284030d | ||
|
|
8c8d0eefbb | ||
|
|
173bcd90df | ||
|
|
e149cbe852 | ||
|
|
a10c06eb4d | ||
|
|
dc7678a700 | ||
|
|
698096f13e | ||
|
|
25e6b76238 | ||
|
|
3dc38fe2f8 | ||
|
|
c73657b38d | ||
|
|
5c16633175 | ||
|
|
5820656aae | ||
|
|
abd3ac4e96 | ||
|
|
a829251690 | ||
|
|
23ee463053 | ||
|
|
16b4d25c1d | ||
|
|
62c0d37d45 | ||
|
|
8ea19eda73 | ||
|
|
17d4961760 | ||
|
|
099f3f3ddf | ||
|
|
54bb09a5fb | ||
|
|
0c45f20515 | ||
|
|
a765ee41d7 | ||
|
|
7c44992016 | ||
|
|
984e37c7f1 | ||
|
|
8d124eb77f | ||
|
|
46a3f7420c | ||
|
|
bef3d4ace2 | ||
|
|
eb92b7ed7f | ||
|
|
30327aa9cc | ||
|
|
7e0e7dc983 | ||
|
|
e885e54233 | ||
|
|
97d158d833 | ||
|
|
abbfea357a | ||
|
|
69e420991a | ||
|
|
0a36edcf20 | ||
|
|
ea7db42af6 | ||
|
|
a46e4f3142 | ||
|
|
cc2869988f | ||
|
|
600d135786 | ||
|
|
84b26fc61d | ||
|
|
5df0879538 | ||
|
|
1951d38f40 | ||
|
|
4e217b180a | ||
|
|
ba6da7c40a | ||
|
|
333411c57d | ||
|
|
3e45a1529c | ||
|
|
3f462659d2 |
2
.idea/runConfigurations/IDEA.xml
generated
2
.idea/runConfigurations/IDEA.xml
generated
@@ -15,6 +15,6 @@
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<method v="2" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -5,6 +5,7 @@ import java.util.*
|
||||
import java.io.File
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import proguard.gradle.ProGuardTask
|
||||
@@ -12,7 +13,7 @@ import proguard.gradle.ProGuardTask
|
||||
buildscript {
|
||||
extra["defaultSnapshotVersion"] = "1.2-SNAPSHOT"
|
||||
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.60-dev-980", onlySuccessBootstrap = false))
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.70-dev-23", onlySuccessBootstrap = false))
|
||||
|
||||
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
|
||||
|
||||
@@ -22,7 +23,6 @@ buildscript {
|
||||
"https://jcenter.bintray.com/",
|
||||
"https://plugins.gradle.org/m2",
|
||||
"http://dl.bintray.com/kotlin/kotlinx",
|
||||
"https://jetbrains.bintray.com/kotlin-native-dependencies",
|
||||
"https://repo.gradle.org/gradle/ext-releases-local", // for native-platform
|
||||
"https://jetbrains.bintray.com/intellij-third-party-dependencies", // for jflex
|
||||
"https://dl.bintray.com/jetbrains/markdown" // for org.jetbrains:markdown
|
||||
@@ -206,6 +206,7 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:daemon",
|
||||
":compiler:ir.tree",
|
||||
":compiler:ir.psi2ir",
|
||||
":compiler:ir.backend.common",
|
||||
":compiler:backend.js",
|
||||
":compiler:backend-common",
|
||||
":compiler:backend",
|
||||
@@ -306,7 +307,7 @@ allprojects {
|
||||
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
|
||||
val commonCompilerArgs = listOf("-Xallow-kotlin-package", "-Xread-deserialized-contracts")
|
||||
val commonCompilerArgs = listOfNotNull("-Xallow-kotlin-package", "-Xread-deserialized-contracts", "-Xprogressive".takeIf { hasProperty("test.progressive.mode") })
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
kotlinOptions {
|
||||
@@ -371,6 +372,22 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isTeamcityBuild) {
|
||||
gradle.taskGraph.whenReady {
|
||||
for (project in allprojects) {
|
||||
for (task in project.tasks) {
|
||||
when (task) {
|
||||
is AbstractKotlinCompile<*> -> task.incremental = true
|
||||
is JavaCompile -> task.options.isIncremental = true
|
||||
is org.gradle.jvm.tasks.Jar -> task.entryCompression = ZipEntryCompression.STORED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.warn("Local build profile is active (IC is on, proguard is off). Use -Pteamcity=true to reproduce TC build")
|
||||
}
|
||||
}
|
||||
|
||||
val dist by task<Copy> {
|
||||
val childDistTasks = getTasksByName("dist", true) - this@task
|
||||
dependsOn(childDistTasks)
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
|
||||
buildscript {
|
||||
val buildSrcKotlinVersion: String by extra(findProperty("buildSrc.kotlin.version")?.toString() ?: embeddedKotlinVersion)
|
||||
val buildSrcKotlinRepo: String? by extra(findProperty("buildSrc.kotlin.repo") as String?)
|
||||
extra["versions.shadow"] = "2.0.2"
|
||||
extra["versions.native-platform"] = "0.14"
|
||||
|
||||
repositories {
|
||||
buildSrcKotlinRepo?.let {
|
||||
maven(url = it)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$buildSrcKotlinVersion")
|
||||
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:$buildSrcKotlinVersion")
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("buildSrcKotlinVersion: " + extra["buildSrcKotlinVersion"])
|
||||
logger.info("buildSrc kotlin compiler version: " + org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)
|
||||
logger.info("buildSrc stdlib version: " + KotlinVersion.CURRENT)
|
||||
|
||||
apply {
|
||||
plugin("kotlin")
|
||||
plugin("kotlin-sam-with-receiver")
|
||||
}
|
||||
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
`java-gradle-plugin`
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
(plugins) {
|
||||
"pill-configurable" {
|
||||
id = "pill-configurable"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
|
||||
}
|
||||
"jps-compatible" {
|
||||
id = "jps-compatible"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatiblePlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
|
||||
val v = it.toString()
|
||||
if (v.isBlank()) true
|
||||
else v.toBoolean()
|
||||
}
|
||||
|
||||
rootProject.apply {
|
||||
from(rootProject.file("../versions.gradle.kts"))
|
||||
}
|
||||
|
||||
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
|
||||
val intellijUltimateEnabled by extra(project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild)
|
||||
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
|
||||
|
||||
extra["intellijRepo"] = "https://www.jetbrains.com/intellij-repository"
|
||||
extra["intellijReleaseType"] = "snapshots" // or "snapshots"
|
||||
extra["versions.androidDxSources"] = "5.0.0_r2"
|
||||
|
||||
extra["customDepsOrg"] = "kotlin.build.custom.deps"
|
||||
|
||||
repositories {
|
||||
extra["buildSrcKotlinRepo"]?.let {
|
||||
maven(url = it)
|
||||
}
|
||||
maven(url = "https://repo.gradle.org/gradle/ext-releases-local") // for native-platform
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
|
||||
compile("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
|
||||
compile("net.rubygrapefruit:native-platform-windows-i386:${property("versions.native-platform")}")
|
||||
compile("com.jakewharton.dex:dex-method-list:3.0.0")
|
||||
// TODO: adding the dep to the plugin breaks the build unexpectedly, resolve and uncomment
|
||||
// compile("org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.extra["bootstrap_kotlin_version"]}")
|
||||
// Shadow plugin is used in many projects of the main build. Once it's no longer used in buildSrc, please move this dependency to the root project
|
||||
compile("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
|
||||
compile("org.ow2.asm:asm-all:6.0_BETA")
|
||||
}
|
||||
|
||||
samWithReceiver {
|
||||
annotation("org.gradle.api.HasImplicitReceiver")
|
||||
}
|
||||
|
||||
fun Project.`samWithReceiver`(configure: org.jetbrains.kotlin.samWithReceiver.gradle.SamWithReceiverExtension.() -> Unit): Unit =
|
||||
extensions.configure("samWithReceiver", configure)
|
||||
|
||||
tasks["build"].dependsOn(":prepare-deps:android-dx:build", ":prepare-deps:intellij-sdk:build")
|
||||
@@ -6,6 +6,7 @@ import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.jar.JarFile
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
/**
|
||||
@@ -47,8 +48,8 @@ fun stripMetadata(logger: Logger, classNamePattern: String, inFile: File, outFil
|
||||
error("Size increased for ${entry.name}: was ${inBytes.size} bytes, became ${outBytes.size} bytes")
|
||||
}
|
||||
|
||||
entry.compressedSize = -1L
|
||||
outJar.putNextEntry(entry)
|
||||
val newEntry = ZipEntry(entry.name)
|
||||
outJar.putNextEntry(newEntry)
|
||||
outJar.write(outBytes)
|
||||
outJar.closeEntry()
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" {
|
||||
projectDefault()
|
||||
java.srcDir("../ir/backend.common/src")
|
||||
}
|
||||
"test" {}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -167,9 +168,24 @@ object CodegenUtil {
|
||||
return KtPsiFactory(project, markGenerated = false).createExpression(fakeFunctionCall) as KtCallExpression
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns declarations in the given [file] which should be generated by the back-end. This includes all declarations
|
||||
* minus all expected declarations (except annotation classes annotated with @OptionalExpectation).
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getActualDeclarations(file: KtFile): List<KtDeclaration> =
|
||||
file.declarations.filterNot(KtDeclaration::hasExpectModifier)
|
||||
fun getDeclarationsToGenerate(file: KtFile, bindingContext: BindingContext): List<KtDeclaration> =
|
||||
file.declarations.filter(fun(declaration: KtDeclaration): Boolean {
|
||||
if (!declaration.hasExpectModifier()) return true
|
||||
|
||||
if (declaration is KtClass) {
|
||||
val descriptor = bindingContext.get(BindingContext.CLASS, declaration)
|
||||
if (descriptor != null && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(descriptor)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
@JvmStatic
|
||||
fun findExpectedFunctionForActual(descriptor: FunctionDescriptor): FunctionDescriptor? {
|
||||
|
||||
@@ -13,6 +13,7 @@ dependencies {
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compile(project(":compiler:ir.psi2ir"))
|
||||
compile(project(":compiler:ir.backend.common"))
|
||||
compile(project(":compiler:serialization"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("annotations", "asm-all", "trove4j", "guava", rootProject = rootProject) }
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.types.FlexibleType;
|
||||
@@ -300,7 +301,10 @@ public abstract class AnnotationCodegen {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (classDescriptor.isExpect()) {
|
||||
// We do not generate annotations whose classes are optional (annotated with `@OptionalExpectation`) because if an annotation entry
|
||||
// is resolved to the expected declaration, this means that annotation has no actual class, and thus should not be generated.
|
||||
// (Otherwise we would've resolved the entry to the actual annotation class.)
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(classDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
@@ -278,6 +279,9 @@ public class AsmUtil {
|
||||
if (descriptor instanceof SyntheticClassDescriptorForLambda) {
|
||||
return getVisibilityAccessFlagForAnonymous(descriptor);
|
||||
}
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
if (descriptor.getVisibility() == Visibilities.PUBLIC ||
|
||||
descriptor.getVisibility() == Visibilities.PROTECTED ||
|
||||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
|
||||
|
||||
@@ -1707,11 +1707,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
|
||||
boolean isUnderlyingPropertyOfInlineClass =
|
||||
InlineClassesUtilsKt.isInlineClass(propertyDescriptor.getContainingDeclaration()) &&
|
||||
JvmCodegenUtil.hasBackingField(propertyDescriptor, contextKind(), bindingContext);
|
||||
|
||||
if (isUnderlyingPropertyOfInlineClass) {
|
||||
if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(propertyDescriptor)) {
|
||||
KotlinType propertyType = propertyDescriptor.getType();
|
||||
return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(propertyType), propertyType, receiver);
|
||||
}
|
||||
@@ -2655,12 +2651,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
"Containing declaration of the companion object " + companionObjectDescriptor +
|
||||
": expected a class, actual: " + hostClassDescriptor;
|
||||
|
||||
CodegenContext hostClassContext = context;
|
||||
while (hostClassContext.getContextDescriptor() != hostClassDescriptor) {
|
||||
hostClassContext = hostClassContext.getParentContext();
|
||||
assert hostClassContext != null :
|
||||
"Host class context for " + hostClassDescriptor + " not found in context hierarchy for " + context;
|
||||
}
|
||||
CodegenContext hostClassContext = context.findParentContextWithDescriptor(hostClassDescriptor);
|
||||
assert hostClassContext != null :
|
||||
"Host class context for " + hostClassDescriptor + " not found in context hierarchy for " + context;
|
||||
|
||||
hostClassContext.markCompanionObjectDescriptorWithAccessorRequired(companionObjectDescriptor);
|
||||
|
||||
@@ -2902,6 +2895,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
KotlinType argumentKotlinType = kotlinType(argumentExpression);
|
||||
if (argument.getSpreadElement() != null) {
|
||||
gen(argumentExpression, OBJECT_TYPE, argumentKotlinType);
|
||||
|
||||
if (argumentKotlinType != null && InlineClassesUtilsKt.isInlineClassType(argumentKotlinType)) {
|
||||
// we're going to pass value of inline class type to j/l/Object, which would result in boxing and then
|
||||
// will cause check cast error on toArray() call. To mitigate this problem, we unbox this value and pass
|
||||
// primitive array to the method. Note that bytecode optimisations will remove box/unbox calls.
|
||||
StackValue.coerce(
|
||||
OBJECT_TYPE, argumentKotlinType,
|
||||
asmType(argumentKotlinType), argumentKotlinType,
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V", false);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy
|
||||
import org.jetbrains.kotlin.codegen.coroutines.SuspendInlineFunctionGenerationStrategy;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
@@ -295,8 +294,7 @@ public class FunctionCodegen {
|
||||
// descriptor corresponds to the underlying value
|
||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty();
|
||||
// property for the underlying value
|
||||
if (JvmCodegenUtil.hasBackingField(property, contextKind, bindingContext)) {
|
||||
if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(property)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,42 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public class GeneratedClassLoader extends URLClassLoader {
|
||||
private static final URLStreamHandler FAKE_BASE64_URL_HANDLER = new URLStreamHandler() {
|
||||
@Override
|
||||
protected URLConnection openConnection(URL url) {
|
||||
return new URLConnection(url) {
|
||||
@Override
|
||||
public void connect() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return new ByteArrayInputStream(Base64.getDecoder().decode(url.getPath()));
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private ClassFileFactory factory;
|
||||
|
||||
public GeneratedClassLoader(@NotNull ClassFileFactory factory, ClassLoader parentClassLoader, URL... urls) {
|
||||
@@ -43,6 +68,39 @@ public class GeneratedClassLoader extends URLClassLoader {
|
||||
return super.getResourceAsStream(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> findResources(String name) throws IOException {
|
||||
Enumeration<URL> fromParent = super.findResources(name);
|
||||
|
||||
URL url = createFakeURLForResource(name);
|
||||
if (url == null) return fromParent;
|
||||
|
||||
List<URL> fromMe = Collections.singletonList(url);
|
||||
List<URL> result = fromParent.hasMoreElements()
|
||||
? CollectionsKt.plus(fromMe, Collections.list(fromParent))
|
||||
: fromMe;
|
||||
return Collections.enumeration(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL findResource(String name) {
|
||||
URL url = createFakeURLForResource(name);
|
||||
return url != null ? url : super.findResource(name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private URL createFakeURLForResource(@NotNull String name) {
|
||||
try {
|
||||
OutputFile outputFile = factory.get(name);
|
||||
// Encode the byte array in the URL path to prevent creating unneeded temporary files
|
||||
return outputFile == null
|
||||
? null
|
||||
: new URL(null, "bytes:" + Base64.getEncoder().encodeToString(outputFile.asByteArray()), FAKE_BASE64_URL_HANDLER);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Class<?> findClass(@NotNull String name) throws ClassNotFoundException {
|
||||
|
||||
@@ -159,6 +159,10 @@ public class JvmCodegenUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isDebuggerContext(contextBeforeInline)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();
|
||||
if (context.isInlineMethodContext()) {
|
||||
// Inline method can be called from a nested class.
|
||||
|
||||
@@ -85,7 +85,7 @@ class MultifileClassCodegenImpl(
|
||||
private val partInternalNamesSorted = run {
|
||||
val partInternalNamesSet = hashSetOf<String>()
|
||||
for (file in files) {
|
||||
if (file.hasDeclarationsForPartClass()) {
|
||||
if (file.hasDeclarationsForPartClass(state.bindingContext)) {
|
||||
partInternalNamesSet.add(JvmFileClassUtil.getFileClassInternalName(file))
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class MultifileClassCodegenImpl(
|
||||
|
||||
val singleSourceFile =
|
||||
if (previouslyCompiledCallables.isEmpty())
|
||||
files.singleOrNull { it.hasDeclarationsForPartClass() }
|
||||
files.singleOrNull { it.hasDeclarationsForPartClass(state.bindingContext) }
|
||||
else
|
||||
null
|
||||
|
||||
@@ -209,7 +209,9 @@ class MultifileClassCodegenImpl(
|
||||
|
||||
generateNonPartClassDeclarations(file, partContext)
|
||||
|
||||
if (!state.generateDeclaredClassFilter.shouldGeneratePackagePart(file) || !file.hasDeclarationsForPartClass()) return
|
||||
if (!state.generateDeclaredClassFilter.shouldGeneratePackagePart(file) ||
|
||||
!file.hasDeclarationsForPartClass(state.bindingContext)
|
||||
) return
|
||||
|
||||
packagePartRegistry.addPart(partType.internalName, facadeClassType.internalName)
|
||||
|
||||
@@ -243,7 +245,7 @@ class MultifileClassCodegenImpl(
|
||||
private fun addDelegateGenerationTasksForDeclarationsInFile(file: KtFile, packageFragment: PackageFragmentDescriptor, partType: Type) {
|
||||
val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType)
|
||||
val memberCodegen = createCodegenForDelegatesInMultifileFacade(facadeContext)
|
||||
for (declaration in CodegenUtil.getActualDeclarations(file)) {
|
||||
for (declaration in CodegenUtil.getDeclarationsToGenerate(file, state.bindingContext)) {
|
||||
if (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias) {
|
||||
val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||
if (descriptor !is MemberDescriptor) {
|
||||
@@ -375,8 +377,8 @@ class MultifileClassCodegenImpl(
|
||||
return fragments.firstOrNull()
|
||||
}
|
||||
|
||||
private fun KtFile.hasDeclarationsForPartClass() =
|
||||
CodegenUtil.getActualDeclarations(this).any { it is KtProperty || it is KtFunction || it is KtTypeAlias }
|
||||
private fun KtFile.hasDeclarationsForPartClass(bindingContext: BindingContext) =
|
||||
CodegenUtil.getDeclarationsToGenerate(this, bindingContext).any { it is KtProperty || it is KtFunction || it is KtTypeAlias }
|
||||
|
||||
private fun getCompiledPackageFragment(
|
||||
facadeFqName: FqName, state: GenerationState
|
||||
|
||||
@@ -132,7 +132,7 @@ class MultifileClassPartCodegen(
|
||||
}
|
||||
|
||||
override fun generateBody() {
|
||||
for (declaration in CodegenUtil.getActualDeclarations(element)) {
|
||||
for (declaration in CodegenUtil.getDeclarationsToGenerate(element, state.bindingContext)) {
|
||||
if (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias) {
|
||||
genSimpleMember(declaration)
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class PackageCodegenImpl implements PackageCodegen {
|
||||
|
||||
List<KtClassOrObject> classOrObjects = new ArrayList<>();
|
||||
|
||||
for (KtDeclaration declaration : CodegenUtil.getActualDeclarations(file)) {
|
||||
for (KtDeclaration declaration : CodegenUtil.getDeclarationsToGenerate(file, state.getBindingContext())) {
|
||||
if (isFilePartDeclaration(declaration)) {
|
||||
generatePackagePart = true;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
for (KtDeclaration declaration : CodegenUtil.getActualDeclarations(element)) {
|
||||
for (KtDeclaration declaration : CodegenUtil.getDeclarationsToGenerate(element, state.getBindingContext())) {
|
||||
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty || declaration instanceof KtTypeAlias) {
|
||||
genSimpleMember(declaration);
|
||||
}
|
||||
@@ -123,7 +123,8 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
@NotNull Type packagePartType
|
||||
) {
|
||||
BindingContext bindingContext = codegen.bindingContext;
|
||||
List<DeclarationDescriptor> members = CollectionsKt.mapNotNull(CodegenUtil.getActualDeclarations(codegen.element), declaration -> {
|
||||
List<KtDeclaration> allDeclarations = CodegenUtil.getDeclarationsToGenerate(codegen.element, bindingContext);
|
||||
List<DeclarationDescriptor> members = CollectionsKt.mapNotNull(allDeclarations, declaration -> {
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
return bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
}
|
||||
|
||||
@@ -193,8 +193,10 @@ public class SamWrapperCodegen {
|
||||
@NotNull KtFile containingFile,
|
||||
CallableMemberDescriptor contextDescriptor
|
||||
) {
|
||||
boolean hasPackagePartClass =
|
||||
CollectionsKt.any(CodegenUtil.getActualDeclarations(containingFile), PackageCodegenImpl::isFilePartDeclaration);
|
||||
boolean hasPackagePartClass = CollectionsKt.any(
|
||||
CodegenUtil.getDeclarationsToGenerate(containingFile, state.getBindingContext()),
|
||||
PackageCodegenImpl::isFilePartDeclaration
|
||||
);
|
||||
FqName filePartFqName = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile).getFileClassFqName();
|
||||
|
||||
FqName outermostOwner;
|
||||
|
||||
@@ -19,8 +19,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.topLevelClassAsmType
|
||||
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
|
||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
@@ -240,7 +240,7 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
||||
setReturnType(function.builtIns.nullableAnyType)
|
||||
setValueParameters(it.valueParameters + continuationParameter)
|
||||
if (dropSuspend) {
|
||||
setDropSuspend()
|
||||
setIsSuspend(false)
|
||||
}
|
||||
putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, it)
|
||||
}
|
||||
@@ -475,4 +475,4 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when
|
||||
is AnonymousFunctionDescriptor -> this.isSuspendLambda
|
||||
is SimpleFunctionDescriptor -> this.visibility == Visibilities.LOCAL
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
@Argument(
|
||||
value = "-Xuse-experimental",
|
||||
valueDescription = "<fq.name>",
|
||||
description = "Enable usages of COMPILATION-affecting experimental API for marker annotation with the given fully qualified name"
|
||||
description = "Enable, but don't propagate usages of experimental API for marker annotation with the given fully qualified name"
|
||||
)
|
||||
var useExperimental: Array<String>? by FreezableVar(null)
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
"-Xjvm-default=enable Allow usages of @JvmDefault; only generate the default method\n" +
|
||||
" in the interface (annotating an existing method can break binary compatibility)\n" +
|
||||
"-Xjvm-default=compatibility Allow usages of @JvmDefault; generate a compatibility accessor\n" +
|
||||
" in the 'DefaultImpls' class in addition to the interface method\n"
|
||||
" in the 'DefaultImpls' class in addition to the interface method"
|
||||
)
|
||||
var jvmDefault: String by FreezableVar(JvmDefaultMode.DEFAULT.description)
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
|
||||
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
||||
import org.jetbrains.kotlin.load.java.components.*
|
||||
import org.jetbrains.kotlin.load.java.lazy.JavaResolverSettings
|
||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
||||
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
@@ -115,6 +116,9 @@ fun createContainerForLazyResolveWithJava(
|
||||
}
|
||||
|
||||
useInstance(javaClassTracker ?: JavaClassesTracker.Default)
|
||||
useInstance(
|
||||
JavaResolverSettings.create(isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines))
|
||||
)
|
||||
|
||||
targetEnvironment.configure(this)
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
|
||||
object ExplicitMetadataChecker : AdditionalAnnotationChecker {
|
||||
private val METADATA_FQ_NAME = FqName("kotlin.Metadata")
|
||||
|
||||
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
|
||||
for (entry in entries) {
|
||||
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||
if (descriptor.fqName == METADATA_FQ_NAME) {
|
||||
trace.report(ErrorsJvm.EXPLICIT_METADATA_IS_DISALLOWED.on(entry))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,6 +141,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(JVM_DEFAULT_THROUGH_INHERITANCE, "Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option");
|
||||
MAP.put(USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL, "Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option");
|
||||
MAP.put(NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault");
|
||||
MAP.put(EXPLICIT_METADATA_IS_DISALLOWED, "Explicit @Metadata is disallowed");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -123,6 +123,8 @@ public interface ErrorsJvm {
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
|
||||
DiagnosticFactory0<KtAnnotationEntry> EXPLICIT_METADATA_IS_DISALLOWED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
enum NullabilityInformationSource {
|
||||
KOTLIN {
|
||||
@NotNull
|
||||
|
||||
@@ -71,7 +71,8 @@ object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
|
||||
additionalAnnotationCheckers = listOf(
|
||||
RepeatableAnnotationChecker,
|
||||
FileClassAnnotationsChecker
|
||||
FileClassAnnotationsChecker,
|
||||
ExplicitMetadataChecker
|
||||
),
|
||||
|
||||
identifierChecker = JvmSimpleNameBacktickChecker,
|
||||
|
||||
@@ -747,7 +747,9 @@ public interface Errors {
|
||||
DiagnosticFactory2<KtBinaryExpression, KotlinType, KotlinType> FORBIDDEN_IDENTITY_EQUALS = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory2<PsiElement, FunctionDescriptor, String> DEPRECATED_BINARY_MOD = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, FunctionDescriptor, String> FORBIDDEN_BINARY_MOD = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, FunctionDescriptor, String> DEPRECATED_BINARY_MOD_AS_REM = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, FunctionDescriptor, String> FORBIDDEN_BINARY_MOD_AS_REM = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtArrayAccessExpression> NO_GET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS);
|
||||
DiagnosticFactory0<KtArrayAccessExpression> NO_SET_METHOD = DiagnosticFactory0.create(ERROR, ARRAY_ACCESS);
|
||||
|
||||
@@ -396,7 +396,9 @@ public class DefaultErrorMessages {
|
||||
MAP.put(FORBIDDEN_IDENTITY_EQUALS, "Identity equality for arguments of types {0} and {1} is forbidden", RENDER_TYPE, RENDER_TYPE);
|
||||
|
||||
MAP.put(DEPRECATED_BINARY_MOD, "Deprecated convention for ''{0}''. Use ''{1}''", NAME, STRING);
|
||||
MAP.put(FORBIDDEN_BINARY_MOD, "Convention for ''{0}'' is forbidden. Use ''{1}''", NAME, STRING);
|
||||
MAP.put(DEPRECATED_BINARY_MOD_AS_REM, "''%'' is resolved to deprecated ''{0}'' operator. Replace with ''.{0}'' or add operator ''{1}''", NAME, STRING);
|
||||
MAP.put(FORBIDDEN_BINARY_MOD_AS_REM, "''%'' is resolved to forbidden ''{0}'' operator. Replace with ''.{0}'' or add operator ''{1}''", NAME, STRING);
|
||||
|
||||
MAP.put(NO_GET_METHOD, "No get method providing array access");
|
||||
MAP.put(NO_SET_METHOD, "No set method providing array access");
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -921,7 +922,9 @@ class DeclarationsChecker(
|
||||
val nullableNothing = callableDescriptor.builtIns.nullableNothingType
|
||||
for (parameter in varargParameters) {
|
||||
val varargElementType = parameter.varargElementType!!.upperIfFlexible()
|
||||
if (KotlinTypeChecker.DEFAULT.isSubtypeOf(varargElementType, nullableNothing) || varargElementType.isInlineClassType()) {
|
||||
if (KotlinTypeChecker.DEFAULT.isSubtypeOf(varargElementType, nullableNothing) ||
|
||||
(varargElementType.isInlineClassType() && !UnsignedTypes.isUnsignedType(varargElementType))
|
||||
) {
|
||||
val parameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(parameter) as? KtParameter ?: continue
|
||||
trace.report(FORBIDDEN_VARARG_PARAMETER_TYPE.on(parameterDeclaration, varargElementType))
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -50,10 +51,18 @@ object OperatorModifierChecker {
|
||||
checkSupportsFeature(LanguageFeature.OperatorProvideDelegate, languageVersionSettings, diagnosticHolder, modifier)
|
||||
}
|
||||
|
||||
if (functionDescriptor.name in REM_TO_MOD_OPERATION_NAMES.values
|
||||
&& languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)) {
|
||||
if (functionDescriptor.name in REM_TO_MOD_OPERATION_NAMES.values &&
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
|
||||
) {
|
||||
val diagnosticFactory = if (!KotlinBuiltIns.isUnderKotlinPackage(descriptor) &&
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOperatorMod)
|
||||
)
|
||||
Errors.FORBIDDEN_BINARY_MOD
|
||||
else
|
||||
Errors.DEPRECATED_BINARY_MOD
|
||||
|
||||
val newNameConvention = REM_TO_MOD_OPERATION_NAMES.inverse()[functionDescriptor.name]
|
||||
diagnosticHolder.report(Errors.DEPRECATED_BINARY_MOD.on(modifier, functionDescriptor, newNameConvention!!.asString()))
|
||||
diagnosticHolder.report(diagnosticFactory.on(modifier, functionDescriptor, newNameConvention!!.asString()))
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -117,16 +117,26 @@ private fun checkModConvention(
|
||||
|
||||
if (KotlinBuiltIns.isUnderKotlinPackage(descriptor)) {
|
||||
if (shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
|
||||
addWarningAboutDeprecatedMod(descriptor, diagnosticHolder, modifier)
|
||||
warnAboutDeprecatedOrForbiddenMod(descriptor, diagnosticHolder, modifier, languageVersionSettings)
|
||||
}
|
||||
} else {
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)) {
|
||||
addWarningAboutDeprecatedMod(descriptor, diagnosticHolder, modifier)
|
||||
warnAboutDeprecatedOrForbiddenMod(descriptor, diagnosticHolder, modifier, languageVersionSettings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addWarningAboutDeprecatedMod(descriptor: FunctionDescriptor, diagnosticHolder: DiagnosticSink, reportOn: PsiElement) {
|
||||
private fun warnAboutDeprecatedOrForbiddenMod(
|
||||
descriptor: FunctionDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
reportOn: PsiElement,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
val diagnosticFactory = if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOperatorMod))
|
||||
Errors.FORBIDDEN_BINARY_MOD_AS_REM
|
||||
else
|
||||
Errors.DEPRECATED_BINARY_MOD_AS_REM
|
||||
|
||||
val newNameConvention = OperatorConventions.REM_TO_MOD_OPERATION_NAMES.inverse()[descriptor.name]
|
||||
diagnosticHolder.report(Errors.DEPRECATED_BINARY_MOD_AS_REM.on(reportOn, descriptor, newNameConvention!!.asString()))
|
||||
diagnosticHolder.report(diagnosticFactory.on(reportOn, descriptor, newNameConvention!!.asString()))
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.psi.Call;
|
||||
import org.jetbrains.kotlin.psi.ValueArgument;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
|
||||
@@ -196,7 +197,14 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
||||
@Override
|
||||
public void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor) {
|
||||
resultingDescriptor = (D) candidateDescriptor.substitute(substitutor);
|
||||
assert resultingDescriptor != null : candidateDescriptor;
|
||||
//noinspection ConstantConditions
|
||||
if (resultingDescriptor == null) {
|
||||
throw new AssertionError(
|
||||
"resultingDescriptor shouldn't be null:\n" +
|
||||
"candidateDescriptor: " + DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(candidateDescriptor) + "\n" +
|
||||
"substitution: " + substitutor.getSubstitution()
|
||||
);
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor typeParameter : candidateDescriptor.getTypeParameters()) {
|
||||
TypeProjection typeArgumentProjection = substitutor.getSubstitution().get(typeParameter.getDefaultType());
|
||||
|
||||
@@ -92,8 +92,25 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isOptionalAnnotationClass(descriptor: DeclarationDescriptor): Boolean {
|
||||
return descriptor.annotations.hasAnnotation(OPTIONAL_EXPECTATION_FQ_NAME)
|
||||
@JvmStatic
|
||||
fun isOptionalAnnotationClass(descriptor: DeclarationDescriptor): Boolean =
|
||||
descriptor is ClassDescriptor &&
|
||||
descriptor.kind == ClassKind.ANNOTATION_CLASS &&
|
||||
descriptor.isExpect &&
|
||||
descriptor.annotations.hasAnnotation(OPTIONAL_EXPECTATION_FQ_NAME)
|
||||
|
||||
// TODO: move to some other place which is accessible both from backend-common and js.serializer
|
||||
@JvmStatic
|
||||
fun shouldGenerateExpectClass(descriptor: ClassDescriptor): Boolean {
|
||||
assert(descriptor.isExpect) { "Not an expected class: $descriptor" }
|
||||
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor)) {
|
||||
with(ExpectedActualResolver) {
|
||||
return descriptor.findCompatibleActualForExpected(descriptor.module).isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence<MemberDescriptor>) {
|
||||
@@ -135,7 +152,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
if (compatibility.allStrongIncompatibilities()) return
|
||||
|
||||
if (Compatible in compatibility) {
|
||||
if (checkActual && requireActualModifier(descriptor, trace)) {
|
||||
if (checkActual && requireActualModifier(descriptor)) {
|
||||
trace.report(Errors.ACTUAL_MISSING.on(reportOn))
|
||||
}
|
||||
|
||||
@@ -204,16 +221,14 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
// - annotation constructors, because annotation classes can only have one constructor
|
||||
// - inline class primary constructors, because inline class must have primary constructor
|
||||
// - value parameter inside primary constructor of inline class, because inline class must have one value parameter
|
||||
private fun requireActualModifier(descriptor: MemberDescriptor, trace: BindingTrace): Boolean {
|
||||
private fun requireActualModifier(descriptor: MemberDescriptor): Boolean {
|
||||
return !descriptor.isAnnotationConstructor() &&
|
||||
!descriptor.isPrimaryConstructorOfInlineClass() &&
|
||||
!isMainPropertyOfInlineClass(descriptor, trace)
|
||||
!isUnderlyingPropertyOfInlineClass(descriptor)
|
||||
}
|
||||
|
||||
private fun isMainPropertyOfInlineClass(descriptor: MemberDescriptor, trace: BindingTrace): Boolean {
|
||||
if (descriptor !is PropertyDescriptor) return false
|
||||
if (!descriptor.containingDeclaration.isInlineClass()) return false
|
||||
return trace.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor] == true
|
||||
private fun isUnderlyingPropertyOfInlineClass(descriptor: MemberDescriptor): Boolean {
|
||||
return descriptor is PropertyDescriptor && descriptor.isUnderlyingPropertyOfInlineClass()
|
||||
}
|
||||
|
||||
// This should ideally be handled by CallableMemberDescriptor.Kind, but default constructors have kind DECLARATION and non-empty source.
|
||||
|
||||
@@ -387,15 +387,19 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
val isUnsigned = hasUnsignedSuffix(text)
|
||||
val typedConstant = nodeElementType == KtNodeTypes.INTEGER_CONSTANT && (hasLongSuffix(text) || isUnsigned)
|
||||
val isIntegerConstant = nodeElementType == KtNodeTypes.INTEGER_CONSTANT
|
||||
val isUnsignedLong = isIntegerConstant && hasUnsignedLongSuffix(text)
|
||||
val isUnsigned = isUnsignedLong || hasUnsignedSuffix(text)
|
||||
val isTyped = isUnsigned || hasLongSuffix(text)
|
||||
|
||||
return createConstant(
|
||||
result,
|
||||
expectedType,
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation = true,
|
||||
isPure = !typedConstant,
|
||||
isPure = !isTyped,
|
||||
isUnsignedNumberLiteral = isUnsigned,
|
||||
isUnsignedLongNumberLiteral = isUnsignedLong,
|
||||
usesVariableAsConstant = false,
|
||||
usesNonConstValAsConstant = false
|
||||
)
|
||||
@@ -443,6 +447,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
CompileTimeConstant.Parameters(
|
||||
isPure = false,
|
||||
isUnsignedNumberLiteral = false,
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
canBeUsedInAnnotation = canBeUsedInAnnotation,
|
||||
usesVariableAsConstant = usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = usesNonConstantVariableAsConstant
|
||||
@@ -506,6 +511,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
canBeUsedInAnnotation = true,
|
||||
isPure = false,
|
||||
isUnsignedNumberLiteral = false,
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
usesVariableAsConstant = leftConstant.usesVariableAsConstant || rightConstant.usesVariableAsConstant,
|
||||
usesNonConstValAsConstant = leftConstant.usesNonConstValAsConstant || rightConstant.usesNonConstValAsConstant
|
||||
)
|
||||
@@ -553,7 +559,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation,
|
||||
!isNumberConversionMethod && isArgumentPure,
|
||||
false,
|
||||
false, false,
|
||||
usesVariableAsConstant, usesNonConstValAsConstant
|
||||
)
|
||||
)
|
||||
@@ -586,7 +592,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
val usesNonConstValAsConstant =
|
||||
usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression)
|
||||
val parameters = CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation, areArgumentsPure, false, usesVariableAsConstant, usesNonConstValAsConstant
|
||||
canBeUsedInAnnotation, areArgumentsPure, false, false, usesVariableAsConstant, usesNonConstValAsConstant
|
||||
)
|
||||
return when (resultingDescriptorName) {
|
||||
OperatorNameConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression)?.wrap(parameters)
|
||||
@@ -708,6 +714,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
|
||||
isPure = false,
|
||||
isUnsignedNumberLiteral = false,
|
||||
isUnsignedLongNumberLiteral = false,
|
||||
usesVariableAsConstant = true,
|
||||
usesNonConstValAsConstant = !callableDescriptor.isConst
|
||||
)
|
||||
@@ -934,10 +941,16 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
parameters: CompileTimeConstant.Parameters,
|
||||
expectedType: KotlinType
|
||||
): CompileTimeConstant<*>? {
|
||||
if (parameters.isUnsignedLongNumberLiteral) {
|
||||
return ULongValue(value).wrap(parameters)
|
||||
}
|
||||
|
||||
if (TypeUtils.noExpectedType(expectedType) || expectedType.isError) {
|
||||
return createIntegerValueTypeConstant(value, constantExpressionEvaluator.module, parameters)
|
||||
}
|
||||
val integerValue = ConstantValueFactory.createIntegerConstantValue(value, expectedType, parameters.isUnsignedNumberLiteral)
|
||||
val integerValue = ConstantValueFactory.createIntegerConstantValue(
|
||||
value, expectedType, parameters.isUnsignedNumberLiteral
|
||||
)
|
||||
if (integerValue != null) {
|
||||
return integerValue.wrap(parameters)
|
||||
}
|
||||
@@ -962,14 +975,22 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
canBeUsedInAnnotation: Boolean = this !is NullValue,
|
||||
isPure: Boolean = false,
|
||||
isUnsigned: Boolean = false,
|
||||
isUnsignedLong: Boolean = false,
|
||||
usesVariableAsConstant: Boolean = false,
|
||||
usesNonConstValAsConstant: Boolean = false
|
||||
): TypedCompileTimeConstant<T> =
|
||||
wrap(CompileTimeConstant.Parameters(canBeUsedInAnnotation, isPure, isUnsigned, usesVariableAsConstant, usesNonConstValAsConstant))
|
||||
wrap(
|
||||
CompileTimeConstant.Parameters(
|
||||
canBeUsedInAnnotation, isPure, isUnsigned, isUnsignedLong, usesVariableAsConstant, usesNonConstValAsConstant
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
|
||||
private fun hasUnsignedSuffix(text: String) = text.endsWith('u')
|
||||
private fun hasUnsignedSuffix(text: String) = text.endsWith('u') || text.endsWith('U')
|
||||
private fun hasUnsignedLongSuffix(text: String) =
|
||||
text.endsWith("ul") || text.endsWith("uL") ||
|
||||
text.endsWith("Ul") || text.endsWith("UL")
|
||||
|
||||
private fun parseNumericLiteral(text: String, type: IElementType): Any? {
|
||||
val canonicalText = LiteralFormatUtil.removeUnderscores(text)
|
||||
@@ -981,13 +1002,33 @@ private fun parseNumericLiteral(text: String, type: IElementType): Any? {
|
||||
}
|
||||
|
||||
private fun parseLong(text: String): Long? {
|
||||
return try {
|
||||
val hasUnsignedSuffix = hasUnsignedSuffix(text)
|
||||
val hasLongSuffix = hasLongSuffix(text)
|
||||
val textWithoutSuffix = if (hasUnsignedSuffix || hasLongSuffix) text.substring(0, text.length - 1) else text
|
||||
val (number, radix) = extractRadix(textWithoutSuffix)
|
||||
fun String.removeSuffix(i: Int): String = this.substring(0, this.length - i)
|
||||
|
||||
if (hasUnsignedSuffix) {
|
||||
return try {
|
||||
val isUnsigned: Boolean
|
||||
val numberWithoutSuffix: String
|
||||
when {
|
||||
hasUnsignedLongSuffix(text) -> {
|
||||
isUnsigned = true
|
||||
numberWithoutSuffix = text.removeSuffix(2)
|
||||
}
|
||||
hasUnsignedSuffix(text) -> {
|
||||
isUnsigned = true
|
||||
numberWithoutSuffix = text.removeSuffix(1)
|
||||
}
|
||||
hasLongSuffix(text) -> {
|
||||
isUnsigned = false
|
||||
numberWithoutSuffix = text.removeSuffix(1)
|
||||
}
|
||||
else -> {
|
||||
isUnsigned = false
|
||||
numberWithoutSuffix = text
|
||||
}
|
||||
}
|
||||
|
||||
val (number, radix) = extractRadix(numberWithoutSuffix)
|
||||
|
||||
if (isUnsigned) {
|
||||
java.lang.Long.parseUnsignedLong(number, radix)
|
||||
} else {
|
||||
java.lang.Long.parseLong(number, radix)
|
||||
|
||||
20
compiler/ir/backend.common/build.gradle.kts
Normal file
20
compiler/ir/backend.common/build.gradle.kts
Normal file
@@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
jvmTarget = "1.6"
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:backend-common"))
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
typealias ReportError = (element: IrElement, message: String) -> Unit
|
||||
|
||||
@@ -43,8 +44,9 @@ class CheckIrElementVisitor(val builtIns: KotlinBuiltIns, val reportError: Repor
|
||||
}
|
||||
|
||||
private fun IrExpression.ensureTypeIs(expectedType: KotlinType) {
|
||||
if (expectedType != type) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type}")
|
||||
// TODO: compare IR types instead.
|
||||
if (expectedType != type.toKotlinType()) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type.toKotlinType()}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,9 +156,9 @@ class CheckIrElementVisitor(val builtIns: KotlinBuiltIns, val reportError: Repor
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> typeOperand.toKotlinType()
|
||||
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable()
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable().toKotlinType()
|
||||
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> builtIns.booleanType
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolsRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
@@ -38,11 +39,13 @@ fun <T : IrElement> T.deepCopyWithVariables(): T {
|
||||
)
|
||||
}
|
||||
|
||||
val symbolsRemapper = DeepCopySymbolsRemapper(descriptorsRemapper)
|
||||
val symbolsRemapper = DeepCopySymbolRemapper(descriptorsRemapper)
|
||||
acceptVoid(symbolsRemapper)
|
||||
|
||||
val typesRemapper = DeepCopyTypeRemapper(symbolsRemapper)
|
||||
|
||||
return this.transform(
|
||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper) {
|
||||
object : DeepCopyIrTreeWithReturnableBlockSymbols(symbolsRemapper, typesRemapper) {
|
||||
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
||||
return irLoop
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -285,7 +286,7 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor<Unit,
|
||||
for (typeParameter in expression.descriptor.original.typeParameters) {
|
||||
val typeArgument = expression.getTypeArgument(typeParameter) ?: continue
|
||||
val renderedParameter = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.render(typeParameter)
|
||||
val renderedType = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.renderType(typeArgument)
|
||||
val renderedType = typeArgument.render()
|
||||
printer.println("$renderedParameter: $renderedType")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.SymbolRemapper
|
||||
import org.jetbrains.kotlin.ir.util.TypeRemapper
|
||||
|
||||
open class DeepCopyIrTreeWithReturnableBlockSymbols(
|
||||
private val symbolRemapper: SymbolRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper) {
|
||||
symbolRemapper: SymbolRemapper,
|
||||
typeRemapper: TypeRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
|
||||
|
||||
private inline fun <reified T : IrElement> T.transform() =
|
||||
transform(this@DeepCopyIrTreeWithReturnableBlockSymbols, null) as T
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -26,14 +25,12 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import java.io.StringWriter
|
||||
|
||||
|
||||
@@ -77,75 +74,62 @@ fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final:
|
||||
}
|
||||
}
|
||||
|
||||
fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(
|
||||
superConstructorDescriptor: ClassConstructorDescriptor,
|
||||
isPrimary: Boolean = false
|
||||
)
|
||||
: ClassConstructorDescriptor {
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
/* containingDeclaration = */ this,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* isPrimary = */ isPrimary,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
val valueParameters = superConstructorDescriptor.valueParameters.map {
|
||||
it.copy(constructorDescriptor, it.name, it.index)
|
||||
}
|
||||
constructorDescriptor.initialize(valueParameters, superConstructorDescriptor.visibility)
|
||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||
return constructorDescriptor
|
||||
}
|
||||
|
||||
fun IrClass.addSimpleDelegatingConstructor(
|
||||
superConstructorSymbol: IrConstructorSymbol,
|
||||
constructorDescriptor: ClassConstructorDescriptor,
|
||||
origin: IrDeclarationOrigin
|
||||
)
|
||||
: IrConstructor {
|
||||
superConstructor: IrConstructor,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
origin: IrDeclarationOrigin,
|
||||
isPrimary: Boolean = false
|
||||
): IrConstructor {
|
||||
val superConstructorDescriptor = superConstructor.descriptor
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
/* containingDeclaration = */ this.descriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* isPrimary = */ isPrimary,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
val valueParameters = superConstructor.valueParameters.map {
|
||||
val descriptor = it.descriptor as ValueParameterDescriptor
|
||||
val newDescriptor = descriptor.copy(constructorDescriptor, descriptor.name, descriptor.index)
|
||||
IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
newDescriptor,
|
||||
it.type,
|
||||
it.varargElementType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
constructorDescriptor.initialize(
|
||||
valueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
superConstructorDescriptor.visibility
|
||||
)
|
||||
constructorDescriptor.returnType = superConstructorDescriptor.returnType
|
||||
|
||||
return IrConstructorImpl(startOffset, endOffset, origin, constructorDescriptor).also { constructor ->
|
||||
constructor.createParameterDeclarations()
|
||||
|
||||
assert(superConstructor.dispatchReceiverParameter == null) // Inner classes aren't supported.
|
||||
|
||||
constructor.valueParameters += valueParameters
|
||||
constructor.returnType = this.defaultType
|
||||
|
||||
constructor.body = IrBlockBodyImpl(
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
superConstructorSymbol, superConstructorSymbol.descriptor
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol)
|
||||
)
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset, irBuiltIns.unitType,
|
||||
superConstructor.symbol, superConstructor.descriptor
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol, irBuiltIns.unitType)
|
||||
)
|
||||
)
|
||||
|
||||
constructor.parent = this
|
||||
this.declarations.add(constructor)
|
||||
}
|
||||
}
|
||||
|
||||
fun CommonBackendContext.createArrayOfExpression(
|
||||
arrayElementType: KotlinType,
|
||||
arrayElements: List<IrExpression>,
|
||||
startOffset: Int, endOffset: Int
|
||||
): IrExpression {
|
||||
|
||||
val genericArrayOfFunSymbol = ir.symbols.arrayOf
|
||||
val genericArrayOfFun = genericArrayOfFunSymbol.descriptor
|
||||
val typeParameter0 = genericArrayOfFun.typeParameters[0]
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
||||
val substitutedArrayOfFun = genericArrayOfFun.substitute(typeSubstitutor)!!
|
||||
|
||||
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
||||
|
||||
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
||||
val arg0VarargType = valueParameter0.type
|
||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
||||
val arg0 = IrVarargImpl(startOffset, endOffset, arg0VarargType, arg0VarargElementType, arrayElements)
|
||||
|
||||
return IrCallImpl(startOffset, endOffset, genericArrayOfFunSymbol, substitutedArrayOfFun, typeArguments).apply {
|
||||
putValueArgument(0, arg0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.common.lower
|
||||
@@ -21,7 +10,6 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
@@ -33,8 +21,8 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
@@ -42,18 +30,13 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
||||
DeclarationContainerLoweringPass {
|
||||
@@ -82,34 +65,31 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
log { "detected ${functionDescriptor.name.asString()} has got #${bodies.size} default expressions" }
|
||||
functionDescriptor.overriddenDescriptors.forEach { context.log { "DEFAULT-REPLACER: $it" } }
|
||||
if (bodies.isNotEmpty()) {
|
||||
val newIrFunction = functionDescriptor.generateDefaultsFunction(context)
|
||||
val newIrFunction = irFunction.generateDefaultsFunction(context)
|
||||
newIrFunction.parent = irFunction.parent
|
||||
val descriptor = newIrFunction.descriptor
|
||||
log { "$functionDescriptor -> $descriptor" }
|
||||
val builder = context.createIrBuilder(newIrFunction.symbol)
|
||||
newIrFunction.body = builder.irBlockBody(newIrFunction) {
|
||||
val params = mutableListOf<IrVariableSymbol>()
|
||||
val variables = mutableMapOf<ValueDescriptor, IrValueSymbol>()
|
||||
val params = mutableListOf<IrVariable>()
|
||||
val variables = mutableMapOf<ValueDescriptor, IrValueDeclaration>()
|
||||
|
||||
irFunction.dispatchReceiverParameter?.let {
|
||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!.symbol
|
||||
variables[it.descriptor] = newIrFunction.dispatchReceiverParameter!!
|
||||
}
|
||||
|
||||
if (descriptor.extensionReceiverParameter != null) {
|
||||
variables[functionDescriptor.extensionReceiverParameter!!] =
|
||||
newIrFunction.extensionReceiverParameter!!.symbol
|
||||
newIrFunction.extensionReceiverParameter!!
|
||||
}
|
||||
|
||||
for (valueParameter in functionDescriptor.valueParameters) {
|
||||
val parameterSymbol = newIrFunction.valueParameters[valueParameter.index].symbol
|
||||
val temporaryVariableSymbol =
|
||||
IrVariableSymbolImpl(scope.createTemporaryVariableDescriptor(parameterSymbol.descriptor))
|
||||
params.add(temporaryVariableSymbol)
|
||||
variables.put(valueParameter, temporaryVariableSymbol)
|
||||
if (valueParameter.hasDefaultValue()) {
|
||||
val kIntAnd = symbols.intAnd
|
||||
val parameter = newIrFunction.valueParameters[valueParameter.index]
|
||||
|
||||
val argument = if (valueParameter.hasDefaultValue()) {
|
||||
val kIntAnd = symbols.intAnd.owner
|
||||
val condition = irNotEquals(irCall(kIntAnd).apply {
|
||||
dispatchReceiver = irGet(maskParameterSymbol(newIrFunction, valueParameter.index / 32))
|
||||
dispatchReceiver = irGet(maskParameter(newIrFunction, valueParameter.index / 32))
|
||||
putValueArgument(0, irInt(1 shl (valueParameter.index % 32)))
|
||||
}, irInt(0))
|
||||
val expressionBody = getDefaultParameterExpressionBody(irFunction, valueParameter)
|
||||
@@ -122,41 +102,41 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
return irGet(valueSymbol)
|
||||
}
|
||||
})
|
||||
val variableInitialization = irIfThenElse(
|
||||
type = temporaryVariableSymbol.descriptor.type,
|
||||
irIfThenElse(
|
||||
type = parameter.type,
|
||||
condition = condition,
|
||||
thenPart = expressionBody.expression,
|
||||
elsePart = irGet(parameterSymbol)
|
||||
)
|
||||
+scope.createTemporaryVariable(
|
||||
symbol = temporaryVariableSymbol,
|
||||
initializer = variableInitialization
|
||||
elsePart = irGet(parameter)
|
||||
)
|
||||
|
||||
/* Mapping calculated values with its origin variables. */
|
||||
} else {
|
||||
+scope.createTemporaryVariable(
|
||||
symbol = temporaryVariableSymbol,
|
||||
initializer = irGet(parameterSymbol)
|
||||
)
|
||||
irGet(parameter)
|
||||
}
|
||||
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
|
||||
|
||||
params.add(temporaryVariable)
|
||||
variables.put(valueParameter, temporaryVariable)
|
||||
}
|
||||
if (irFunction is IrConstructor) {
|
||||
+IrDelegatingConstructorCallImpl(
|
||||
startOffset = irFunction.startOffset,
|
||||
endOffset = irFunction.endOffset,
|
||||
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor
|
||||
type = context.irBuiltIns.unitType,
|
||||
symbol = irFunction.symbol, descriptor = irFunction.symbol.descriptor,
|
||||
typeArgumentsCount = irFunction.typeParameters.size
|
||||
).apply {
|
||||
params.forEachIndexed { i, variable ->
|
||||
putValueArgument(i, irGet(variable))
|
||||
}
|
||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
+irReturn(irCall(irFunction.symbol).apply {
|
||||
+irReturn(irCall(irFunction).apply {
|
||||
if (functionDescriptor.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!.symbol)
|
||||
dispatchReceiver = irGet(newIrFunction.dispatchReceiverParameter!!)
|
||||
}
|
||||
if (functionDescriptor.extensionReceiverParameter != null) {
|
||||
extensionReceiver = irGet(variables[functionDescriptor.extensionReceiverParameter!!]!!)
|
||||
@@ -181,50 +161,29 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
||||
}
|
||||
|
||||
private fun Scope.createTemporaryVariableDescriptor(parameterDescriptor: ParameterDescriptor?): VariableDescriptor =
|
||||
IrTemporaryVariableDescriptorImpl(
|
||||
containingDeclaration = this.scopeOwner,
|
||||
name = parameterDescriptor!!.name.asString().synthesizedName,
|
||||
outType = parameterDescriptor.type,
|
||||
isMutable = false
|
||||
)
|
||||
|
||||
private fun Scope.createTemporaryVariable(symbol: IrVariableSymbol, initializer: IrExpression) =
|
||||
IrVariableImpl(
|
||||
startOffset = initializer.startOffset,
|
||||
endOffset = initializer.endOffset,
|
||||
origin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
symbol = symbol
|
||||
).apply {
|
||||
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
private fun getDefaultParameterExpressionBody(irFunction: IrFunction, valueParameter: ValueParameterDescriptor): IrExpressionBody {
|
||||
return irFunction.getDefault(valueParameter) ?: TODO("FIXME!!!")
|
||||
}
|
||||
|
||||
private fun maskParameterDescriptor(function: IrFunction, number: Int) =
|
||||
maskParameterSymbol(function, number).descriptor as ValueParameterDescriptor
|
||||
maskParameter(function, number).descriptor as ValueParameterDescriptor
|
||||
|
||||
private fun maskParameterSymbol(function: IrFunction, number: Int) =
|
||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }.symbol
|
||||
private fun maskParameter(function: IrFunction, number: Int) =
|
||||
function.valueParameters.single { it.descriptor.name == parameterMaskName(number) }
|
||||
|
||||
private fun markerParameterDescriptor(descriptor: FunctionDescriptor) =
|
||||
descriptor.valueParameters.single { it.name == kConstructorMarkerName }
|
||||
|
||||
private fun nullConst(expression: IrElement, type: KotlinType): IrExpression? {
|
||||
when {
|
||||
KotlinBuiltIns.isFloat(type) -> return IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||
KotlinBuiltIns.isDouble(type) -> return IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||
KotlinBuiltIns.isBoolean(type) -> return IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||
KotlinBuiltIns.isByte(type) -> return IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isChar(type) -> return IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||
KotlinBuiltIns.isShort(type) -> return IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isInt(type) -> return IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||
KotlinBuiltIns.isLong(type) -> return IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||
else -> return IrConstImpl.constNull(expression.startOffset, expression.endOffset, type.builtIns.nullableNothingType)
|
||||
}
|
||||
private fun nullConst(expression: IrElement, type: IrType, context: CommonBackendContext) = when {
|
||||
type.isFloat() -> IrConstImpl.float(expression.startOffset, expression.endOffset, type, 0.0F)
|
||||
type.isDouble() -> IrConstImpl.double(expression.startOffset, expression.endOffset, type, 0.0)
|
||||
type.isBoolean() -> IrConstImpl.boolean(expression.startOffset, expression.endOffset, type, false)
|
||||
type.isByte() -> IrConstImpl.byte(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isChar() -> IrConstImpl.char(expression.startOffset, expression.endOffset, type, 0.toChar())
|
||||
type.isShort() -> IrConstImpl.short(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isInt() -> IrConstImpl.int(expression.startOffset, expression.endOffset, type, 0)
|
||||
type.isLong() -> IrConstImpl.long(expression.startOffset, expression.endOffset, type, 0)
|
||||
else -> IrConstImpl.constNull(expression.startOffset, expression.endOffset, context.irBuiltIns.nothingNType)
|
||||
}
|
||||
|
||||
class DefaultParameterInjector constructor(val context: CommonBackendContext, private val skipInline: Boolean = true) : BodyLoweringPass {
|
||||
@@ -240,11 +199,14 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
if (argumentsCount == descriptor.valueParameters.size)
|
||||
return expression
|
||||
val (symbolForCall, params) = parametersForCall(expression)
|
||||
symbolForCall as IrConstructorSymbol
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
symbol = symbolForCall as IrConstructorSymbol,
|
||||
descriptor = symbolForCall.descriptor
|
||||
type = context.irBuiltIns.unitType,
|
||||
symbol = symbolForCall,
|
||||
descriptor = symbolForCall.descriptor,
|
||||
typeArgumentsCount = symbolForCall.owner.typeParameters.size
|
||||
)
|
||||
.apply {
|
||||
params.forEach {
|
||||
@@ -273,13 +235,14 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
return IrCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = symbol.owner.returnType,
|
||||
symbol = symbol,
|
||||
descriptor = descriptor,
|
||||
typeArguments = expression.descriptor.typeParameters.map {
|
||||
it to (expression.getTypeArgument(it) ?: it.defaultType)
|
||||
}.toMap()
|
||||
typeArgumentsCount = expression.typeArgumentsCount
|
||||
)
|
||||
.apply {
|
||||
this.copyTypeArgumentsFrom(expression)
|
||||
|
||||
params.forEach {
|
||||
log { "call::params@${it.first.index}/${it.first.name.asString()}: ${ir2string(it.second)}" }
|
||||
putValueArgument(it.first.index, it.second)
|
||||
@@ -310,8 +273,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
private fun parametersForCall(expression: IrFunctionAccessExpression): Pair<IrFunctionSymbol, List<Pair<ValueParameterDescriptor, IrExpression?>>> {
|
||||
val descriptor = expression.descriptor
|
||||
val keyFunction = expression.symbol.owner.findSuperMethodWithDefaultArguments()!!
|
||||
val keyDescriptor = keyFunction.descriptor
|
||||
val realFunction = keyDescriptor.generateDefaultsFunction(context)
|
||||
val realFunction = keyFunction.generateDefaultsFunction(context)
|
||||
realFunction.parent = keyFunction.parent
|
||||
val realDescriptor = realFunction.descriptor
|
||||
|
||||
@@ -325,15 +287,18 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
maskValues[maskIndex] = maskValues[maskIndex] or (1 shl (i % 32))
|
||||
}
|
||||
val valueParameterDescriptor = realDescriptor.valueParameters[i]
|
||||
val defaultValueArgument =
|
||||
if (valueParameterDescriptor.isVararg) null else nullConst(expression, valueParameterDescriptor.type)
|
||||
val defaultValueArgument = if (valueParameterDescriptor.isVararg) {
|
||||
null
|
||||
} else {
|
||||
nullConst(expression, realFunction.valueParameters[i].type, context)
|
||||
}
|
||||
valueParameterDescriptor to (valueArgument ?: defaultValueArgument)
|
||||
})
|
||||
maskValues.forEachIndexed { i, maskValue ->
|
||||
params += maskParameterDescriptor(realFunction, i) to IrConstImpl.int(
|
||||
startOffset = irBody.startOffset,
|
||||
endOffset = irBody.endOffset,
|
||||
type = descriptor.builtIns.intType,
|
||||
type = context.irBuiltIns.intType,
|
||||
value = maskValue
|
||||
)
|
||||
}
|
||||
@@ -347,7 +312,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
)
|
||||
} else if (context.ir.shouldGenerateHandlerParameterForDefaultBodyFun()) {
|
||||
params += realDescriptor.valueParameters.last() to
|
||||
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.builtIns.any.defaultType)
|
||||
IrConstImpl.constNull(irBody.startOffset, irBody.endOffset, context.irBuiltIns.nothingNType)
|
||||
}
|
||||
params.forEach {
|
||||
log { "descriptor::${realDescriptor.name.asString()}#${it.first.index}: ${it.first.name.asString()}" }
|
||||
@@ -366,7 +331,7 @@ class DefaultParameterInjector constructor(val context: CommonBackendContext, pr
|
||||
private fun CallableMemberDescriptor.needsDefaultArgumentsLowering(skipInlineMethods: Boolean) =
|
||||
valueParameters.any { it.hasDefaultValue() } && !(this is FunctionDescriptor && isInline && skipInlineMethods)
|
||||
|
||||
private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendContext): IrFunction {
|
||||
private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext): IrFunction = with(this.descriptor) {
|
||||
return context.ir.defaultParameterDeclarationsCache.getOrPut(this) {
|
||||
val descriptor = when (this) {
|
||||
is ClassConstructorDescriptor ->
|
||||
@@ -389,8 +354,10 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
}
|
||||
}
|
||||
|
||||
val function = this@generateDefaultsFunction
|
||||
|
||||
val syntheticParameters = MutableList((valueParameters.size + 31) / 32) { i ->
|
||||
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), descriptor.builtIns.intType)
|
||||
valueParameter(descriptor, valueParameters.size + i, parameterMaskName(i), context.irBuiltIns.intType)
|
||||
}
|
||||
if (this is ClassConstructorDescriptor) {
|
||||
syntheticParameters += valueParameter(
|
||||
@@ -402,10 +369,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
syntheticParameters += valueParameter(
|
||||
descriptor, syntheticParameters.last().index + 1,
|
||||
"handler".synthesizedName,
|
||||
context.ir.symbols.any.owner.defaultType
|
||||
context.irBuiltIns.anyType
|
||||
)
|
||||
}
|
||||
|
||||
val newValueParameters = function.valueParameters.map {
|
||||
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
|
||||
index = it.index,
|
||||
annotations = it.descriptor.annotations,
|
||||
name = it.name,
|
||||
outType = it.descriptor.type,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = it.isCrossinline,
|
||||
isNoinline = it.isNoinline,
|
||||
varargElementType = (it.descriptor as ValueParameterDescriptor).varargElementType,
|
||||
source = it.descriptor.source
|
||||
)
|
||||
|
||||
it.copy(parameterDescriptor)
|
||||
|
||||
} + syntheticParameters
|
||||
|
||||
descriptor.initialize(
|
||||
/* receiverParameterType = */ extensionReceiverParameter?.type,
|
||||
/* dispatchReceiverParameter = */ dispatchReceiverParameter,
|
||||
@@ -425,24 +411,11 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
setInitialized()
|
||||
}
|
||||
},
|
||||
/* unsubstitutedValueParameters = */ valueParameters.map {
|
||||
ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null, /* ValueParameterDescriptorImpl::copy do not save original. */
|
||||
index = it.index,
|
||||
annotations = it.annotations,
|
||||
name = it.name,
|
||||
outType = it.type,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = it.isCrossinline,
|
||||
isNoinline = it.isNoinline,
|
||||
varargElementType = it.varargElementType,
|
||||
source = it.source
|
||||
)
|
||||
} + syntheticParameters,
|
||||
/* unsubstitutedValueParameters = */ newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
/* unsubstitutedReturnType = */ returnType,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ this.visibility)
|
||||
/* visibility = */ this.visibility
|
||||
)
|
||||
descriptor.isSuspend = this.isSuspend
|
||||
context.log { "adds to cache[$this] = $descriptor" }
|
||||
|
||||
@@ -463,7 +436,29 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
)
|
||||
}
|
||||
|
||||
result.createParameterDeclarations()
|
||||
result.returnType = function.returnType
|
||||
|
||||
function.typeParameters.mapTo(result.typeParameters) {
|
||||
assert(function.descriptor.typeParameters[it.index] == it.descriptor)
|
||||
IrTypeParameterImpl(
|
||||
startOffset, endOffset, origin, descriptor.typeParameters[it.index]
|
||||
).apply { this.superTypes += it.superTypes }
|
||||
}
|
||||
result.parent = function.parent
|
||||
result.createDispatchReceiverParameter()
|
||||
|
||||
function.extensionReceiverParameter?.let {
|
||||
result.extensionReceiverParameter = IrValueParameterImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
it.origin,
|
||||
descriptor.extensionReceiverParameter!!,
|
||||
it.type,
|
||||
it.varargElementType
|
||||
).apply { parent = result }
|
||||
}
|
||||
|
||||
result.valueParameters += newValueParameters.also { it.forEach { it.parent = result } }
|
||||
|
||||
result
|
||||
}
|
||||
@@ -472,20 +467,28 @@ private fun FunctionDescriptor.generateDefaultsFunction(context: CommonBackendCo
|
||||
object DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER :
|
||||
IrDeclarationOriginImpl("DEFAULT_PARAMETER_EXTENT")
|
||||
|
||||
private fun valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: KotlinType): ValueParameterDescriptor {
|
||||
return ValueParameterDescriptorImpl(
|
||||
private fun IrFunction.valueParameter(descriptor: FunctionDescriptor, index: Int, name: Name, type: IrType): IrValueParameter {
|
||||
val parameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = descriptor,
|
||||
original = null,
|
||||
index = index,
|
||||
annotations = Annotations.EMPTY,
|
||||
name = name,
|
||||
outType = type,
|
||||
outType = type.toKotlinType(),
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
)
|
||||
return IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
parameterDescriptor,
|
||||
type,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
internal val kConstructorMarkerName = "marker".synthesizedName
|
||||
|
||||
@@ -68,7 +68,7 @@ class InitializersLowering(
|
||||
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
|
||||
IrGetValueImpl(
|
||||
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
|
||||
irClass.thisReceiver!!.symbol
|
||||
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
|
||||
)
|
||||
else null
|
||||
val irSetField = IrSetFieldImpl(
|
||||
@@ -76,6 +76,7 @@ class InitializersLowering(
|
||||
declaration.symbol,
|
||||
receiver,
|
||||
irFieldInitializer,
|
||||
context.irBuiltIns.unitType,
|
||||
null, null
|
||||
)
|
||||
|
||||
@@ -93,7 +94,7 @@ class InitializersLowering(
|
||||
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
|
||||
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
||||
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.builtIns.unitType, null,
|
||||
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null,
|
||||
instanceInitializerStatements.map { it.copy(irClass) })
|
||||
}
|
||||
})
|
||||
|
||||
@@ -20,7 +20,10 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
import java.util.*
|
||||
@@ -67,12 +70,14 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
}
|
||||
|
||||
private fun createOuterThisField() {
|
||||
val fieldSymbol = context.descriptorsFactory.getOuterThisFieldSymbol(irClass)
|
||||
irClass.declarations.add(
|
||||
IrFieldImpl(
|
||||
irClass.startOffset, irClass.endOffset,
|
||||
FIELD_FOR_OUTER_THIS,
|
||||
context.descriptorsFactory.getOuterThisFieldSymbol(irClass)
|
||||
).also {
|
||||
fieldSymbol,
|
||||
irClass.defaultType
|
||||
).also {
|
||||
outerThisField = it
|
||||
}
|
||||
)
|
||||
@@ -97,7 +102,10 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
irConstructor.origin, // TODO special origin for lowered inner class constructors?
|
||||
newSymbol,
|
||||
null
|
||||
)
|
||||
).apply {
|
||||
returnType = irConstructor.returnType
|
||||
}
|
||||
|
||||
loweredConstructor.createParameterDeclarations()
|
||||
val outerThisValueParameter = loweredConstructor.valueParameters[0].symbol
|
||||
|
||||
@@ -115,7 +123,8 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset, outerThisField.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
|
||||
IrGetValueImpl(startOffset, endOffset, outerThisValueParameter)
|
||||
IrGetValueImpl(startOffset, endOffset, outerThisValueParameter),
|
||||
context.irBuiltIns.unitType
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@@ -166,7 +175,7 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
}
|
||||
|
||||
val outerThisField = context.descriptorsFactory.getOuterThisFieldSymbol(innerClass)
|
||||
irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, irThis, origin)
|
||||
irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, innerClass.defaultType, irThis, origin)
|
||||
|
||||
val outer = innerClass.parent
|
||||
innerClass = outer as? IrClass ?:
|
||||
@@ -204,8 +213,8 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
|
||||
|
||||
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee.owner)
|
||||
val newCall = IrCallImpl(
|
||||
expression.startOffset, expression.endOffset, newCallee, newCallee.descriptor,
|
||||
null, // TODO type arguments map
|
||||
expression.startOffset, expression.endOffset, expression.type, newCallee, newCallee.descriptor,
|
||||
0, // TODO type arguments map
|
||||
expression.origin
|
||||
)
|
||||
|
||||
@@ -226,7 +235,7 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
|
||||
|
||||
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(classConstructor)
|
||||
val newCall = IrDelegatingConstructorCallImpl(
|
||||
expression.startOffset, expression.endOffset, newCallee, newCallee.descriptor,
|
||||
expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, newCallee, newCallee.descriptor,
|
||||
classConstructor.typeParameters.size
|
||||
).apply { copyTypeArgumentsFrom(expression) }
|
||||
|
||||
|
||||
@@ -16,26 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||
|
||||
@@ -62,155 +44,3 @@ abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||
return builtIr
|
||||
}
|
||||
}
|
||||
|
||||
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
||||
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||
|
||||
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||
PropertyGetterDescriptorImpl(
|
||||
/* correspondingProperty = */ fieldSymbol.descriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PRIVATE,
|
||||
/* isDefault = */ false,
|
||||
/* isExternal = */ false,
|
||||
/* isInline = */ false,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||
/* original = */ null,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
override fun doInitialize() {
|
||||
val descriptor = symbol.descriptor as PropertyGetterDescriptorImpl
|
||||
descriptor.apply {
|
||||
initialize(type)
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildIr() = IrFunctionImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = symbol).apply {
|
||||
|
||||
createParameterDeclarations()
|
||||
|
||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
||||
+irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
||||
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||
|
||||
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||
PropertySetterDescriptorImpl(
|
||||
/* correspondingProperty = */ fieldSymbol.descriptor,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PRIVATE,
|
||||
/* isDefault = */ false,
|
||||
/* isExternal = */ false,
|
||||
/* isInline = */ false,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||
/* original = */ null,
|
||||
/* source = */ SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
lateinit var valueParameterDescriptor: ValueParameterDescriptor
|
||||
|
||||
override fun doInitialize() {
|
||||
val descriptor = symbol.descriptor as PropertySetterDescriptorImpl
|
||||
descriptor.apply {
|
||||
valueParameterDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration = this,
|
||||
original = null,
|
||||
index = 0,
|
||||
annotations = Annotations.EMPTY,
|
||||
name = Name.identifier("value"),
|
||||
outType = type,
|
||||
declaresDefaultValue = false,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
varargElementType = null,
|
||||
source = SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
initialize(valueParameterDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildIr() = IrFunctionImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = symbol).apply {
|
||||
|
||||
createParameterDeclarations()
|
||||
|
||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
||||
+irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol, irGet(this@apply.valueParameters.single().symbol))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
|
||||
= object: SymbolWithIrBuilder<IrFieldSymbol, IrProperty>() {
|
||||
|
||||
private lateinit var getterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>
|
||||
private var setterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
|
||||
|
||||
override fun buildSymbol() = IrFieldSymbolImpl(
|
||||
PropertyDescriptorImpl.create(
|
||||
/* containingDeclaration = */ owner,
|
||||
/* annotations = */ Annotations.EMPTY,
|
||||
/* modality = */ Modality.FINAL,
|
||||
/* visibility = */ Visibilities.PRIVATE,
|
||||
/* isVar = */ isMutable,
|
||||
/* name = */ name,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||
/* source = */ SourceElement.NO_SOURCE,
|
||||
/* lateInit = */ false,
|
||||
/* isConst = */ false,
|
||||
/* isExpect = */ false,
|
||||
/* isActual = */ false,
|
||||
/* isExternal = */ false,
|
||||
/* isDelegated = */ false
|
||||
)
|
||||
)
|
||||
|
||||
override fun doInitialize() {
|
||||
val descriptor = symbol.descriptor as PropertyDescriptorImpl
|
||||
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
||||
if (isMutable)
|
||||
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
||||
descriptor.initialize(
|
||||
/* getter = */ getterBuilder.symbol.descriptor as PropertyGetterDescriptorImpl,
|
||||
/* setter = */ setterBuilder?.symbol?.descriptor as? PropertySetterDescriptorImpl)
|
||||
val receiverType: KotlinType? = null
|
||||
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
|
||||
}
|
||||
|
||||
override fun buildIr(): IrProperty {
|
||||
val backingField = IrFieldImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
symbol = symbol)
|
||||
return IrPropertyImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
origin = origin,
|
||||
isDelegated = false,
|
||||
descriptor = symbol.descriptor,
|
||||
backingField = backingField,
|
||||
getter = getterBuilder.ir,
|
||||
setter = setterBuilder?.ir)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
@@ -58,7 +58,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
|
||||
return lower.context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).run {
|
||||
|
||||
IrCompositeImpl(startOffset, endOffset, context.builtIns.stringType).apply {
|
||||
IrCompositeImpl(startOffset, endOffset, context.irBuiltIns.stringType).apply {
|
||||
receiver?.let {
|
||||
//put receiver for bound callable reference
|
||||
statements.add(it)
|
||||
@@ -68,7 +68,7 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
IrConstImpl.string(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.builtIns.stringType,
|
||||
context.irBuiltIns.stringType,
|
||||
callableReference.descriptor.name.asString()
|
||||
)
|
||||
)
|
||||
@@ -104,5 +104,5 @@ private class KCallableNamePropertyTransformer(val lower: KCallableNamePropertyL
|
||||
endOffset
|
||||
)
|
||||
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -45,20 +47,20 @@ class LateinitLowering(
|
||||
|
||||
private fun transformGetter(backingField: IrField, getter: IrFunction) {
|
||||
val type = backingField.type
|
||||
assert(!KotlinBuiltIns.isPrimitiveType(type)) { "'lateinit' modifier is not allowed on primitive types" }
|
||||
assert(!type.isPrimitiveType()) { "'lateinit' modifier is not allowed on primitive types" }
|
||||
val startOffset = getter.startOffset
|
||||
val endOffset = getter.endOffset
|
||||
val irBuilder = context.createIrBuilder(getter.symbol, startOffset, endOffset)
|
||||
irBuilder.run {
|
||||
val block = irBlock(type)
|
||||
val resultVar = scope.createTemporaryVariable(
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it.symbol) }, backingField.symbol)
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it) }, backingField)
|
||||
)
|
||||
block.statements.add(resultVar)
|
||||
val throwIfNull = irIfThenElse(
|
||||
context.builtIns.nothingType,
|
||||
irNotEquals(irGet(resultVar.symbol), irNull()),
|
||||
irReturn(irGet(resultVar.symbol)),
|
||||
context.irBuiltIns.nothingType,
|
||||
irNotEquals(irGet(resultVar), irNull()),
|
||||
irReturn(irGet(resultVar)),
|
||||
throwUninitializedPropertyAccessException(backingField)
|
||||
)
|
||||
block.statements.add(throwIfNull)
|
||||
@@ -76,15 +78,15 @@ class LateinitLowering(
|
||||
IrConstImpl.string(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
context.builtIns.stringType,
|
||||
context.irBuiltIns.stringType,
|
||||
backingField.name.asString()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException
|
||||
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException.owner
|
||||
|
||||
private fun IrBuilderWithScope.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private fun IrBuilderWithScope.irBlock(type: IrType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.common.lower
|
||||
@@ -21,21 +10,25 @@ import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface LocalNameProvider {
|
||||
@@ -99,12 +92,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
abstract val transformedDescriptor: FunctionDescriptor
|
||||
abstract val transformedDeclaration: IrFunction
|
||||
|
||||
val capturedValueToParameter: MutableMap<ValueDescriptor, IrValueParameterSymbol> = HashMap()
|
||||
val capturedValueToParameter: MutableMap<ValueDescriptor, IrValueParameter> = HashMap()
|
||||
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val newSymbol = capturedValueToParameter[descriptor] ?: return null
|
||||
val parameter = capturedValueToParameter[descriptor] ?: return null
|
||||
|
||||
return IrGetValueImpl(startOffset, endOffset, newSymbol)
|
||||
return IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +135,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val field = capturedValueToField[descriptor] ?: return null
|
||||
|
||||
val receiver = declaration.thisReceiver!!
|
||||
return IrGetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, declaration.thisReceiver!!.symbol)
|
||||
startOffset, endOffset, field.symbol, field.type,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -156,9 +150,10 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun irGet(startOffset: Int, endOffset: Int, descriptor: ValueDescriptor): IrExpression? {
|
||||
val field = classContext.capturedValueToField[descriptor] ?: return null
|
||||
|
||||
val receiver = member.dispatchReceiverParameter!!
|
||||
return IrGetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, member.dispatchReceiverParameter!!.symbol)
|
||||
startOffset, endOffset, field.symbol, field.type,
|
||||
receiver = IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -169,12 +164,12 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val localClasses: MutableMap<ClassDescriptor, LocalClassContext> = LinkedHashMap()
|
||||
val localClassConstructors: MutableMap<ClassConstructorDescriptor, LocalClassConstructorContext> = LinkedHashMap()
|
||||
|
||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrSymbol>()
|
||||
val transformedDeclarations = mutableMapOf<DeclarationDescriptor, IrDeclaration>()
|
||||
|
||||
val FunctionDescriptor.transformed: IrFunctionSymbol?
|
||||
get() = transformedDeclarations[this] as IrFunctionSymbol?
|
||||
val FunctionDescriptor.transformed: IrFunction?
|
||||
get() = transformedDeclarations[this] as IrFunction?
|
||||
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameterSymbol> = HashMap()
|
||||
val oldParameterToNew: MutableMap<ParameterDescriptor, IrValueParameter> = HashMap()
|
||||
val newParameterToOld: MutableMap<ParameterDescriptor, ParameterDescriptor> = HashMap()
|
||||
val newParameterToCaptured: MutableMap<ValueParameterDescriptor, IrValueSymbol> = HashMap()
|
||||
|
||||
@@ -201,7 +196,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
|
||||
original.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||
val body = original.getDefault(argument)!!
|
||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
||||
oldParameterToNew[argument]!!.defaultValue = body
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +214,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
if (declaration.descriptor in localClasses) {
|
||||
// Replace local class definition with an empty composite.
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
|
||||
} else {
|
||||
return super.visitClass(declaration)
|
||||
}
|
||||
@@ -228,7 +223,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
if (declaration.descriptor in localFunctions) {
|
||||
// Replace local function definition with an empty composite.
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType)
|
||||
} else {
|
||||
if (localContext is LocalClassContext && declaration.parent == localContext.declaration) {
|
||||
return declaration.apply {
|
||||
@@ -251,7 +246,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
|
||||
declaration.descriptor.valueParameters.filter { it.declaresDefaultValue() }.forEach { argument ->
|
||||
val body = declaration.getDefault(argument)!!
|
||||
oldParameterToNew[argument]!!.owner.defaultValue = body
|
||||
oldParameterToNew[argument]!!.defaultValue = body
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -267,7 +262,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
|
||||
oldParameterToNew[descriptor]?.let {
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it)
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol)
|
||||
}
|
||||
|
||||
return expression
|
||||
@@ -288,14 +283,18 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructorSymbol? ?: return expression
|
||||
val newCallee = transformedDeclarations[oldCallee] as IrConstructor? ?: return expression
|
||||
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
newCallee,
|
||||
context.irBuiltIns.unitType,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(expression, newCallee.descriptor)
|
||||
).fillArguments(expression)
|
||||
expression.typeArgumentsCount
|
||||
).also {
|
||||
it.fillArguments(expression)
|
||||
it.copyTypeArgumentsFrom(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(oldExpression: IrMemberAccessExpression): T {
|
||||
@@ -311,16 +310,17 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
newParameterToCaptured[newValueParameterDescriptor]
|
||||
?: throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
|
||||
val capturedValue = capturedValueSymbol.owner
|
||||
|
||||
val capturedValueDescriptor = capturedValueSymbol.descriptor
|
||||
localContext?.irGet(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
capturedValueDescriptor
|
||||
) ?:
|
||||
// Captured value is directly available for the caller.
|
||||
IrGetValueImpl(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
oldParameterToNew[capturedValueDescriptor] ?: capturedValueSymbol
|
||||
)
|
||||
) ?: run {
|
||||
// Captured value is directly available for the caller.
|
||||
val value = oldParameterToNew[capturedValueDescriptor] ?: capturedValue
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset, value.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -340,11 +340,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val newCallableReference = IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, // TODO functional type for transformed descriptor
|
||||
newCallee,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(expression, newCallee.descriptor),
|
||||
expression.typeArgumentsCount,
|
||||
expression.origin
|
||||
).fillArguments(expression)
|
||||
).also {
|
||||
it.fillArguments(expression)
|
||||
it.copyTypeArgumentsFrom(expression)
|
||||
}
|
||||
|
||||
return newCallableReference
|
||||
}
|
||||
@@ -355,7 +358,11 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val oldReturnTarget = expression.returnTarget
|
||||
val newReturnTarget = oldReturnTarget.transformed ?: return expression
|
||||
|
||||
return IrReturnImpl(expression.startOffset, expression.endOffset, newReturnTarget, expression.value)
|
||||
return IrReturnImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
context.irBuiltIns.nothingType,
|
||||
newReturnTarget.symbol, expression.value
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitDeclarationReference(expression: IrDeclarationReference): IrExpression {
|
||||
@@ -400,7 +407,9 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
|
||||
capturedValueExpression, STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||
capturedValueExpression,
|
||||
context.irBuiltIns.unitType,
|
||||
STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -423,31 +432,20 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
rewriteFunctionBody(memberDeclaration, null)
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunctionSymbol) =
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: IrFunction) =
|
||||
if (oldCall is IrCallWithShallowCopy)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifierSymbol)
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee.symbol, oldCall.superQualifierSymbol)
|
||||
else
|
||||
IrCallImpl(
|
||||
oldCall.startOffset, oldCall.endOffset,
|
||||
newCallee,
|
||||
newCallee.returnType,
|
||||
newCallee.symbol,
|
||||
newCallee.descriptor,
|
||||
remapTypeArguments(oldCall, newCallee.descriptor),
|
||||
oldCall.typeArgumentsCount,
|
||||
oldCall.origin, oldCall.superQualifierSymbol
|
||||
)
|
||||
|
||||
private fun remapTypeArguments(
|
||||
oldExpression: IrMemberAccessExpression,
|
||||
newCallee: CallableDescriptor
|
||||
): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
val oldCallee = oldExpression.descriptor.original
|
||||
|
||||
return if (oldCallee.typeParameters.isEmpty())
|
||||
null
|
||||
else oldCallee.typeParameters.associateBy(
|
||||
{ newCallee.typeParameters[it.index] },
|
||||
{ oldExpression.getTypeArgumentOrDefault(it) }
|
||||
)
|
||||
}
|
||||
).also {
|
||||
it.copyTypeArgumentsFrom(oldCall)
|
||||
}
|
||||
|
||||
private fun transformDescriptors() {
|
||||
localFunctions.values.forEach {
|
||||
@@ -520,7 +518,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
newDispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
oldDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE
|
||||
@@ -534,9 +532,26 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
IrFunctionImpl(startOffset, endOffset, origin, newDescriptor)
|
||||
}.apply {
|
||||
parent = memberDeclaration.parent
|
||||
createParameterDeclarations()
|
||||
returnType = localFunctionContext.declaration.returnType
|
||||
|
||||
localFunctionContext.declaration.typeParameters.mapTo(this.typeParameters) {
|
||||
IrTypeParameterImpl(it.startOffset, it.endOffset, it.origin, it.descriptor)
|
||||
.apply { superTypes += it.superTypes }
|
||||
}
|
||||
|
||||
localFunctionContext.declaration.extensionReceiverParameter?.let {
|
||||
this.extensionReceiverParameter = IrValueParameterImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
it.origin,
|
||||
descriptor.extensionReceiverParameter!!,
|
||||
it.type,
|
||||
null
|
||||
)
|
||||
}
|
||||
this.valueParameters += newValueParameters
|
||||
recordTransformedValueParameters(localFunctionContext)
|
||||
transformedDeclarations[oldDescriptor] = this.symbol
|
||||
transformedDeclarations[oldDescriptor] = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,7 +559,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
localContext: LocalContextWithClosureAsParameters,
|
||||
capturedValues: List<IrValueSymbol>
|
||||
)
|
||||
: List<ValueParameterDescriptor> {
|
||||
: List<IrValueParameter> {
|
||||
|
||||
val oldDescriptor = localContext.descriptor
|
||||
val newDescriptor = localContext.transformedDescriptor
|
||||
@@ -552,17 +567,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val closureParametersCount = capturedValues.size
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
val newValueParameters = ArrayList<IrValueParameter>(newValueParametersCount).apply {
|
||||
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||
val parameterDescriptor = createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValue.descriptor, i).apply {
|
||||
newParameterToCaptured[this] = capturedValue
|
||||
}
|
||||
capturedValue.owner.copy(parameterDescriptor)
|
||||
}
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
newParameterToOld.putAbsentOrSame(this, oldValueParameterDescriptor)
|
||||
localContext.declaration.valueParameters.mapIndexedTo(this) { i, oldValueParameter ->
|
||||
val parameterDescriptor = createUnsubstitutedParameter(
|
||||
newDescriptor,
|
||||
oldValueParameter.descriptor as ValueParameterDescriptor,
|
||||
closureParametersCount + i
|
||||
).apply {
|
||||
newParameterToOld.putAbsentOrSame(this, oldValueParameter.descriptor)
|
||||
}
|
||||
oldValueParameter.copy(parameterDescriptor)
|
||||
}
|
||||
}
|
||||
return newValueParameters
|
||||
@@ -573,14 +594,14 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
valueParameters.forEach {
|
||||
val capturedValue = newParameterToCaptured[it.descriptor]
|
||||
if (capturedValue != null) {
|
||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it.symbol
|
||||
localContext.capturedValueToParameter[capturedValue.descriptor] = it
|
||||
}
|
||||
}
|
||||
|
||||
(listOfNotNull(dispatchReceiverParameter, extensionReceiverParameter) + valueParameters).forEach {
|
||||
val oldParameter = newParameterToOld[it.descriptor]
|
||||
if (oldParameter != null) {
|
||||
oldParameterToNew.putAbsentOrSame(oldParameter, it.symbol)
|
||||
oldParameterToNew.putAbsentOrSame(oldParameter, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,7 +625,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
val newValueParameters = createTransformedValueParameters(constructorContext, capturedValues)
|
||||
|
||||
newDescriptor.initialize(
|
||||
newValueParameters,
|
||||
newValueParameters.map { it.descriptor as ValueParameterDescriptor },
|
||||
Visibilities.PRIVATE,
|
||||
newTypeParameters
|
||||
)
|
||||
@@ -619,12 +640,23 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
|
||||
constructorContext.transformedDeclaration = with(constructorContext.declaration) {
|
||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor)
|
||||
IrConstructorImpl(startOffset, endOffset, origin, newDescriptor).also { it.returnType = returnType }
|
||||
}.apply {
|
||||
parent = constructorContext.declaration.parent
|
||||
createParameterDeclarations()
|
||||
constructorContext.declaration.dispatchReceiverParameter?.let {
|
||||
this.dispatchReceiverParameter = IrValueParameterImpl(
|
||||
it.startOffset,
|
||||
it.endOffset,
|
||||
it.origin,
|
||||
descriptor.dispatchReceiverParameter!!,
|
||||
it.type,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
this.valueParameters += newValueParameters
|
||||
recordTransformedValueParameters(constructorContext)
|
||||
transformedDeclarations[oldDescriptor] = this.symbol
|
||||
transformedDeclarations[oldDescriptor] = this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,7 +695,7 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
localClassContext.capturedValueToField[capturedValue.descriptor] = IrFieldImpl(
|
||||
localClassContext.declaration.startOffset, localClassContext.declaration.endOffset,
|
||||
DECLARATION_ORIGIN_FIELD_FOR_CAPTURED_VALUE,
|
||||
fieldDescriptor
|
||||
fieldDescriptor, capturedValue.owner.type
|
||||
).apply {
|
||||
parent = localClassContext.declaration
|
||||
}
|
||||
@@ -776,4 +808,13 @@ class LocalDeclarationsLowering(val context: BackendContext, val localNameProvid
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrValueDeclaration.copy(newDescriptor: ParameterDescriptor): IrValueParameter = IrValueParameterImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
newDescriptor,
|
||||
type,
|
||||
(this as? IrValueParameter)?.varargElementType
|
||||
)
|
||||
|
||||
@@ -1,372 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.AbstractClosureAnnotator
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.Closure
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerLoweringPass {
|
||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||
irDeclarationContainer.declarations.transformFlat { memberDeclaration ->
|
||||
if (memberDeclaration is IrFunction)
|
||||
LocalFunctionsTransformer(memberDeclaration).lowerLocalFunctions()
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalFunctionContext(val declaration: IrFunction) {
|
||||
lateinit var closure: Closure
|
||||
|
||||
val closureParametersCount: Int get() = closure.capturedValues.size
|
||||
|
||||
lateinit var transformedDescriptor: FunctionDescriptor
|
||||
|
||||
val old2new: MutableMap<ValueDescriptor, ParameterDescriptor> = HashMap()
|
||||
|
||||
var index: Int = -1
|
||||
|
||||
override fun toString(): String =
|
||||
"LocalFunctionContext for ${declaration.descriptor}"
|
||||
}
|
||||
|
||||
private inner class LocalFunctionsTransformer(val memberFunction: IrFunction) {
|
||||
val localFunctions: MutableMap<FunctionDescriptor, LocalFunctionContext> = LinkedHashMap()
|
||||
val new2old: MutableMap<ParameterDescriptor, ValueDescriptor> = HashMap()
|
||||
|
||||
fun lowerLocalFunctions(): List<IrDeclaration>? {
|
||||
collectLocalFunctions()
|
||||
if (localFunctions.isEmpty()) return null
|
||||
|
||||
collectClosures()
|
||||
|
||||
transformDescriptors()
|
||||
|
||||
rewriteBodies()
|
||||
|
||||
return collectRewrittenDeclarations()
|
||||
}
|
||||
|
||||
private fun collectRewrittenDeclarations(): ArrayList<IrDeclaration> =
|
||||
ArrayList<IrDeclaration>(localFunctions.size + 1).apply {
|
||||
add(memberFunction)
|
||||
|
||||
localFunctions.values.mapTo(this) {
|
||||
val original = it.declaration
|
||||
IrFunctionImpl(
|
||||
original.startOffset, original.endOffset, original.origin,
|
||||
it.transformedDescriptor,
|
||||
original.body
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class FunctionBodiesRewriter(val localFunctionContext: LocalFunctionContext?) : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
// ignore local classes for now
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
// replace local function definition with an empty composite
|
||||
return IrCompositeImpl(declaration.startOffset, declaration.endOffset, context.builtIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
val remapped = localFunctionContext?.let { it.old2new[expression.descriptor] }
|
||||
return if (remapped == null)
|
||||
expression
|
||||
else
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, remapped, expression.origin)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
||||
|
||||
val newCallee = localFunctionData.transformedDescriptor
|
||||
|
||||
return createNewCall(expression, newCallee).fillArguments(localFunctionData, expression)
|
||||
}
|
||||
|
||||
private fun <T : IrMemberAccessExpression> T.fillArguments(calleeContext: LocalFunctionContext, oldExpression: IrMemberAccessExpression): T {
|
||||
val closureParametersCount = calleeContext.closureParametersCount
|
||||
|
||||
mapValueParametersIndexed { index, newValueParameterDescriptor ->
|
||||
val capturedValueDescriptor = new2old[newValueParameterDescriptor] ?:
|
||||
throw AssertionError("Non-mapped parameter $newValueParameterDescriptor")
|
||||
if (index >= closureParametersCount)
|
||||
oldExpression.getValueArgument(capturedValueDescriptor as ValueParameterDescriptor)
|
||||
else {
|
||||
val remappedValueDescriptor = localFunctionContext?.let { it.old2new[capturedValueDescriptor] }
|
||||
IrGetValueImpl(oldExpression.startOffset, oldExpression.endOffset,
|
||||
remappedValueDescriptor ?: capturedValueDescriptor)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispatchReceiver = oldExpression.dispatchReceiver
|
||||
extensionReceiver = oldExpression.extensionReceiver
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldCallee = expression.descriptor.original
|
||||
val localFunctionData = localFunctions[oldCallee] ?: return expression
|
||||
val newCallee = localFunctionData.transformedDescriptor
|
||||
|
||||
return IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, // TODO functional type for transformed descriptor
|
||||
newCallee,
|
||||
remapTypeArguments(expression, newCallee),
|
||||
expression.origin
|
||||
).fillArguments(localFunctionData, expression)
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val oldReturnTarget = expression.returnTarget
|
||||
val localFunctionData = localFunctions[oldReturnTarget] ?: return expression
|
||||
val newReturnTarget = localFunctionData.transformedDescriptor
|
||||
|
||||
return IrReturnImpl(expression.startOffset, expression.endOffset,
|
||||
newReturnTarget,
|
||||
expression.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun rewriteFunctionDeclaration(irFunction: IrFunction, localFunctionContext: LocalFunctionContext?) {
|
||||
irFunction.transformChildrenVoid(FunctionBodiesRewriter(localFunctionContext))
|
||||
}
|
||||
|
||||
private fun rewriteBodies() {
|
||||
localFunctions.values.forEach {
|
||||
rewriteFunctionDeclaration(it.declaration, it)
|
||||
}
|
||||
|
||||
rewriteFunctionDeclaration(memberFunction, null)
|
||||
}
|
||||
|
||||
private fun createNewCall(oldCall: IrCall, newCallee: FunctionDescriptor) =
|
||||
when (oldCall) {
|
||||
is IrCallWithShallowCopy ->
|
||||
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifier)
|
||||
else ->
|
||||
IrCallImpl(
|
||||
oldCall.startOffset, oldCall.endOffset,
|
||||
newCallee,
|
||||
remapTypeArguments(oldCall, newCallee),
|
||||
oldCall.origin, oldCall.superQualifier
|
||||
)
|
||||
}
|
||||
|
||||
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: FunctionDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
val oldCallee = oldExpression.descriptor
|
||||
|
||||
return if (oldCallee.typeParameters.isEmpty())
|
||||
null
|
||||
else oldCallee.original.typeParameters.associateBy(
|
||||
{ newCallee.typeParameters[it.index] },
|
||||
{ oldExpression.getTypeArgument(it)!! }
|
||||
)
|
||||
}
|
||||
|
||||
private fun transformDescriptors() {
|
||||
localFunctions.values.forEach {
|
||||
it.transformedDescriptor = createTransformedDescriptor(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun suggestLocalName(descriptor: DeclarationDescriptor): String {
|
||||
val localFunctionContext = localFunctions[descriptor]
|
||||
return if (localFunctionContext != null && localFunctionContext.index >= 0)
|
||||
"lambda-${localFunctionContext.index}"
|
||||
else
|
||||
descriptor.name.asString()
|
||||
}
|
||||
|
||||
private fun generateNameForLiftedFunction(functionDescriptor: FunctionDescriptor): Name =
|
||||
Name.identifier(
|
||||
functionDescriptor.parentsWithSelf
|
||||
.takeWhile { it is FunctionDescriptor }
|
||||
.toList().reversed()
|
||||
.joinToString(separator = "$") { suggestLocalName(it) }
|
||||
)
|
||||
|
||||
private fun createTransformedDescriptor(localFunctionContext: LocalFunctionContext): FunctionDescriptor {
|
||||
val oldDescriptor = localFunctionContext.declaration.descriptor
|
||||
|
||||
val memberOwner = memberFunction.descriptor.containingDeclaration
|
||||
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
memberOwner,
|
||||
oldDescriptor.annotations,
|
||||
generateNameForLiftedFunction(oldDescriptor),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
oldDescriptor.source
|
||||
)
|
||||
|
||||
val closureParametersCount = localFunctionContext.closureParametersCount
|
||||
val newValueParametersCount = closureParametersCount + oldDescriptor.valueParameters.size
|
||||
|
||||
val newDispatchReceiverParameter =
|
||||
if (memberOwner is ClassDescriptor && oldDescriptor.dispatchReceiverParameter != null)
|
||||
memberOwner.thisAsReceiverParameter
|
||||
else
|
||||
null
|
||||
|
||||
// Do not substitute type parameters for now.
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
|
||||
val newValueParameters = ArrayList<ValueParameterDescriptor>(newValueParametersCount).apply {
|
||||
localFunctionContext.closure.capturedValues.mapIndexedTo(this) { i, capturedValueDescriptor ->
|
||||
createUnsubstitutedCapturedValueParameter(newDescriptor, capturedValueDescriptor, i).apply {
|
||||
localFunctionContext.recordRemapped(capturedValueDescriptor, this)
|
||||
}
|
||||
}
|
||||
|
||||
oldDescriptor.valueParameters.mapIndexedTo(this) { i, oldValueParameterDescriptor ->
|
||||
createUnsubstitutedParameter(newDescriptor, oldValueParameterDescriptor, closureParametersCount + i).apply {
|
||||
localFunctionContext.recordRemapped(oldValueParameterDescriptor, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDescriptor.initialize(
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
newDispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
oldDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
Visibilities.PRIVATE
|
||||
)
|
||||
|
||||
oldDescriptor.extensionReceiverParameter?.let {
|
||||
localFunctionContext.recordRemapped(it, newDescriptor.extensionReceiverParameter!!)
|
||||
}
|
||||
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
private fun LocalFunctionContext.recordRemapped(oldDescriptor: ValueDescriptor, newDescriptor: ParameterDescriptor): ParameterDescriptor {
|
||||
old2new[oldDescriptor] = newDescriptor
|
||||
new2old[newDescriptor] = oldDescriptor
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
private fun suggestNameForCapturedValueParameter(valueDescriptor: ValueDescriptor): Name =
|
||||
if (valueDescriptor.name.isSpecial) {
|
||||
val oldNameStr = valueDescriptor.name.asString()
|
||||
Name.identifier("$" + oldNameStr.substring(1, oldNameStr.length - 1))
|
||||
}
|
||||
else
|
||||
valueDescriptor.name
|
||||
|
||||
private fun createUnsubstitutedCapturedValueParameter(
|
||||
newParameterOwner: CallableMemberDescriptor,
|
||||
valueDescriptor: ValueDescriptor,
|
||||
index: Int
|
||||
): ValueParameterDescriptor =
|
||||
ValueParameterDescriptorImpl(
|
||||
newParameterOwner, null, index,
|
||||
valueDescriptor.annotations,
|
||||
suggestNameForCapturedValueParameter(valueDescriptor),
|
||||
valueDescriptor.type,
|
||||
false, false, false, null, valueDescriptor.source
|
||||
)
|
||||
|
||||
private fun createUnsubstitutedParameter(
|
||||
newParameterOwner: CallableMemberDescriptor,
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
newIndex: Int
|
||||
): ValueParameterDescriptor =
|
||||
valueParameterDescriptor.copy(newParameterOwner, valueParameterDescriptor.name, newIndex)
|
||||
|
||||
|
||||
private fun collectClosures() {
|
||||
memberFunction.acceptChildrenVoid(object : AbstractClosureAnnotator() {
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
// ignore local classes for now
|
||||
return
|
||||
}
|
||||
|
||||
override fun recordFunctionClosure(functionDescriptor: FunctionDescriptor, closure: Closure) {
|
||||
localFunctions[functionDescriptor]?.closure = closure
|
||||
}
|
||||
|
||||
override fun recordClassClosure(classDescriptor: ClassDescriptor, closure: Closure) {
|
||||
// ignore local classes for now
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun collectLocalFunctions() {
|
||||
memberFunction.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||
var lambdasCount = 0
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
val localFunctionContext = LocalFunctionContext(declaration)
|
||||
localFunctions[declaration.descriptor] = localFunctionContext
|
||||
if (declaration.descriptor.name.isSpecial) {
|
||||
localFunctionContext.index = lambdasCount++
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
// ignore local classes for now
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,8 +28,8 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -39,10 +39,9 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContext(backendContext.irBuiltIns)
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns)
|
||||
|
||||
class DeclarationIrBuilder(
|
||||
backendContext: BackendContext,
|
||||
@@ -60,7 +59,7 @@ abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
||||
remapVariable(expression.descriptor)?.let {
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, it.symbol, expression.origin)
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.origin)
|
||||
} ?: expression
|
||||
}
|
||||
|
||||
@@ -84,7 +83,7 @@ fun <T : IrBuilder> T.at(element: IrElement) = this.at(element.startOffset, elem
|
||||
*/
|
||||
inline fun IrGeneratorWithScope.irBlock(
|
||||
expression: IrExpression, origin: IrStatementOrigin? = null,
|
||||
resultType: KotlinType? = expression.type,
|
||||
resultType: IrType? = expression.type,
|
||||
body: IrBlockBuilder.() -> Unit
|
||||
) =
|
||||
this.irBlock(expression.startOffset, expression.endOffset, origin, resultType, body)
|
||||
@@ -93,13 +92,15 @@ inline fun IrGeneratorWithScope.irBlockBody(irElement: IrElement, body: IrBlockB
|
||||
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
||||
|
||||
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
|
||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
|
||||
IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType).apply {
|
||||
branches += IrBranchImpl(condition, thenPart)
|
||||
}
|
||||
|
||||
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, arg)
|
||||
|
||||
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
||||
IrThrowImpl(startOffset, endOffset, context.builtIns.nothingType, arg)
|
||||
IrThrowImpl(startOffset, endOffset, context.irBuiltIns.nothingType, arg)
|
||||
|
||||
fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||
IrCatchImpl(
|
||||
@@ -107,21 +108,12 @@ fun IrBuilderWithScope.irCatch(catchParameter: IrVariable) =
|
||||
catchParameter
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
|
||||
|
||||
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
||||
IrTypeOperatorCallImpl(
|
||||
startOffset, endOffset, context.builtIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg
|
||||
startOffset, endOffset, context.irBuiltIns.unitType,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.irBuiltIns.unitType, context.irBuiltIns.unitClass, arg
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression, symbol: IrFieldSymbol) =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
||||
|
||||
fun IrBuilderWithScope.irSetField(receiver: IrExpression, symbol: IrFieldSymbol, value: IrExpression) =
|
||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value)
|
||||
|
||||
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
|
||||
private var currentBuilder: IrBuilderWithScope? = null
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -60,33 +62,33 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
private val nameToString = Name.identifier("toString")
|
||||
private val nameAppend = Name.identifier("append")
|
||||
|
||||
private val stringBuilder = context.ir.symbols.stringBuilder
|
||||
private val stringBuilder = context.ir.symbols.stringBuilder.owner
|
||||
|
||||
//TODO: calculate and pass string length to the constructor.
|
||||
private val constructor = stringBuilder.constructors.single {
|
||||
it.owner.valueParameters.size == 0
|
||||
it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
private val toStringFunction = stringBuilder.functions.single {
|
||||
it.owner.valueParameters.size == 0 && it.descriptor.name == nameToString
|
||||
it.valueParameters.size == 0 && it.name == nameToString
|
||||
}
|
||||
private val defaultAppendFunction = stringBuilder.functions.single {
|
||||
it.descriptor.name == nameAppend &&
|
||||
it.owner.valueParameters.size == 1 &&
|
||||
it.owner.valueParameters.single().type == builtIns.nullableAnyType
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.isNullableAny()
|
||||
}
|
||||
|
||||
|
||||
private val appendFunctions: Map<KotlinType, IrFunctionSymbol?> =
|
||||
private val appendFunctions: Map<KotlinType, IrSimpleFunction?> =
|
||||
typesWithSpecialAppendFunction.map { type ->
|
||||
type to stringBuilder.functions.toList().atMostOne {
|
||||
it.descriptor.name == nameAppend &&
|
||||
it.owner.valueParameters.size == 1 &&
|
||||
it.owner.valueParameters.single().type == type
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.toKotlinType() == type
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
private fun typeToAppendFunction(type: KotlinType): IrFunctionSymbol {
|
||||
private fun typeToAppendFunction(type: KotlinType): IrSimpleFunction {
|
||||
return appendFunctions[type] ?: defaultAppendFunction
|
||||
}
|
||||
|
||||
@@ -96,9 +98,9 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
expression.transformChildrenVoid(this)
|
||||
val blockBuilder = buildersStack.last()
|
||||
return blockBuilder.irBlock(expression) {
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor)).symbol
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor))
|
||||
expression.arguments.forEach { arg ->
|
||||
val appendFunction = typeToAppendFunction(arg.type)
|
||||
val appendFunction = typeToAppendFunction(arg.type.toKotlinType())
|
||||
+irCall(appendFunction).apply {
|
||||
dispatchReceiver = irGet(stringBuilderImpl)
|
||||
putValueArgument(0, arg)
|
||||
|
||||
@@ -18,14 +18,12 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.util.explicitParameters
|
||||
import org.jetbrains.kotlin.ir.util.getArgumentsWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
@@ -55,7 +53,7 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
irFunction.body = builder.irBlockBody {
|
||||
// Define variables containing current values of parameters:
|
||||
val parameterToVariable = parameters.associate {
|
||||
it to irTemporaryVar(irGet(it), nameHint = it.suggestVariableName()).symbol
|
||||
it to irTemporaryVar(irGet(it), nameHint = it.symbol.suggestVariableName())
|
||||
}
|
||||
// (these variables are to be updated on any tail call).
|
||||
|
||||
@@ -63,11 +61,11 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
val loop = this
|
||||
condition = irTrue()
|
||||
|
||||
body = irBlock(startOffset, endOffset, resultType = context.builtIns.unitType) {
|
||||
body = irBlock(startOffset, endOffset, resultType = context.irBuiltIns.unitType) {
|
||||
// Read variables containing current values of parameters:
|
||||
val parameterToNew = parameters.associate {
|
||||
val variable = parameterToVariable[it]!!
|
||||
it to irTemporary(irGet(variable), nameHint = it.suggestVariableName()).symbol
|
||||
it to irTemporary(irGet(variable), nameHint = it.symbol.suggestVariableName())
|
||||
}
|
||||
|
||||
val transformer = BodyTransformer(
|
||||
@@ -89,8 +87,8 @@ private class BodyTransformer(
|
||||
val builder: IrBuilderWithScope,
|
||||
val irFunction: IrFunction,
|
||||
val loop: IrLoop,
|
||||
val parameterToNew: Map<IrValueParameterSymbol, IrValueSymbol>,
|
||||
val parameterToVariable: Map<IrValueParameterSymbol, IrVariableSymbol>,
|
||||
val parameterToNew: Map<IrValueParameter, IrValueDeclaration>,
|
||||
val parameterToVariable: Map<IrValueParameter, IrVariable>,
|
||||
val tailRecursionCalls: Set<IrCall>
|
||||
) : IrElementTransformerVoid() {
|
||||
|
||||
@@ -98,7 +96,7 @@ private class BodyTransformer(
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val value = parameterToNew[expression.symbol] ?: return expression
|
||||
val value = parameterToNew[expression.symbol.owner] ?: return expression
|
||||
return builder.at(expression).irGet(value)
|
||||
}
|
||||
|
||||
@@ -113,7 +111,7 @@ private class BodyTransformer(
|
||||
|
||||
private fun IrBuilderWithScope.genTailCall(expression: IrCall) = this.irBlock(expression) {
|
||||
// Get all specified arguments:
|
||||
val parameterToArgument = expression.getArgumentsWithSymbols().map { (parameter, argument) ->
|
||||
val parameterToArgument = expression.getArgumentsWithIr().map { (parameter, argument) ->
|
||||
parameter to argument
|
||||
}
|
||||
|
||||
@@ -122,7 +120,7 @@ private class BodyTransformer(
|
||||
at(argument)
|
||||
// Note that argument can use values of parameters, so it is important that
|
||||
// references to parameters are mapped using `parameterToNew`, not `parameterToVariable`.
|
||||
+irSetVar(parameterToVariable[parameter]!!, argument)
|
||||
+irSetVar(parameterToVariable[parameter]!!.symbol, argument)
|
||||
}
|
||||
|
||||
val specifiedParameters = parameterToArgument.map { (parameter, _) -> parameter }.toSet()
|
||||
@@ -130,7 +128,7 @@ private class BodyTransformer(
|
||||
// For each unspecified argument set the corresponding variable to default:
|
||||
parameters.filter { it !in specifiedParameters }.forEach { parameter ->
|
||||
|
||||
val originalDefaultValue = parameter.owner.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
|
||||
val originalDefaultValue = parameter.defaultValue?.expression ?: throw Error("no argument specified for $parameter")
|
||||
|
||||
// Copy default value, mapping parameters to variables containing freshly computed arguments:
|
||||
val defaultValue = originalDefaultValue
|
||||
@@ -140,15 +138,15 @@ private class BodyTransformer(
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val variableSymbol = parameterToVariable[expression.symbol] ?: return expression
|
||||
val variable = parameterToVariable[expression.symbol.owner] ?: return expression
|
||||
return IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
variableSymbol, expression.origin
|
||||
expression.startOffset, expression.endOffset, variable.type,
|
||||
variable.symbol, expression.origin
|
||||
)
|
||||
}
|
||||
}, data = null)
|
||||
|
||||
+irSetVar(parameterToVariable[parameter]!!, defaultValue)
|
||||
+irSetVar(parameterToVariable[parameter]!!.symbol, defaultValue)
|
||||
}
|
||||
|
||||
// Jump to the entry:
|
||||
|
||||
@@ -32,14 +32,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.getPropertyGetter
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
|
||||
@@ -68,20 +64,25 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
element?.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
val transformer = this
|
||||
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrMemberAccessExpression) {
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) {
|
||||
log { "call of: ${expression.descriptor}" }
|
||||
context.createIrBuilder(owner, expression.startOffset, expression.endOffset).apply {
|
||||
expression.descriptor.valueParameters.forEach {
|
||||
log { "varargElementType: ${it.varargElementType} expr: ${ir2string(expression.getValueArgument(it))}" }
|
||||
}
|
||||
expression.descriptor.valueParameters.filter { it.varargElementType != null && expression.getValueArgument(it) == null }.forEach {
|
||||
expression.putValueArgument(it.index,
|
||||
IrVarargImpl(startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
type = it.type,
|
||||
varargElementType = it.varargElementType!!)
|
||||
)
|
||||
}
|
||||
expression.symbol.owner.valueParameters
|
||||
.filter { it.varargElementType != null && expression.getValueArgument(it.index) == null }
|
||||
.forEach {
|
||||
expression.putValueArgument(
|
||||
it.index,
|
||||
IrVarargImpl(
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
type = it.type,
|
||||
varargElementType = it.varargElementType!!
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
expression.transformChildrenVoid(this)
|
||||
}
|
||||
@@ -99,28 +100,27 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
override fun visitVararg(expression: IrVararg): IrExpression {
|
||||
expression.transformChildrenVoid(transformer)
|
||||
val hasSpreadElement = hasSpreadElement(expression)
|
||||
if (!hasSpreadElement && expression.elements.all { it is IrConst<*> && KotlinBuiltIns.isString(it.type) }) {
|
||||
if (!hasSpreadElement && expression.elements.all { it is IrConst<*> && it.type.isString() }) {
|
||||
log { "skipped vararg expression because it's string array literal" }
|
||||
return expression
|
||||
}
|
||||
val irBuilder = context.createIrBuilder(owner, expression.startOffset, expression.endOffset)
|
||||
irBuilder.run {
|
||||
val type = expression.varargElementType
|
||||
log { "$expression: array type:$type, is array of primitives ${!KotlinBuiltIns.isArray(expression.type)}" }
|
||||
log { "$expression: array type:$type, is array of primitives ${!expression.type.isArray()}" }
|
||||
val arrayHandle = arrayType(expression.type)
|
||||
val arrayConstructor = arrayHandle.arraySymbol.constructors.find { it.owner.valueParameters.size == 1 }!!
|
||||
val block = irBlock(arrayHandle.arraySymbol.owner.defaultType)
|
||||
val arrayConstructorCall = if (arrayConstructor.owner.typeParameters.isEmpty()) {
|
||||
irCall(arrayConstructor)
|
||||
} else {
|
||||
irCall(arrayConstructor, listOf(type))
|
||||
}
|
||||
val arrayConstructor = arrayHandle.arraySymbol.owner.constructors.find { it.valueParameters.size == 1 }!!
|
||||
val block = irBlock(expression.type)
|
||||
val arrayConstructorCall = irCall(arrayConstructor)
|
||||
|
||||
if (arrayConstructor.typeParameters.isNotEmpty()) {
|
||||
arrayConstructorCall.putTypeArgument(0, expression.varargElementType)
|
||||
}
|
||||
|
||||
val vars = expression.elements.map {
|
||||
val initVar = scope.createTemporaryVariable(
|
||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||
"elem".synthesizedString, true)
|
||||
(it as? IrSpreadElement)?.expression ?: it as IrExpression,
|
||||
"elem".synthesizedString, true)
|
||||
block.statements.add(initVar)
|
||||
it to initVar
|
||||
}.toMap()
|
||||
@@ -138,32 +138,31 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
log { "element:$i> ${ir2string(element)}" }
|
||||
val dst = vars[element]!!
|
||||
if (element !is IrSpreadElement) {
|
||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol)
|
||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable.symbol)
|
||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable.symbol) else irConstInt(i))
|
||||
setArrayElementCall.putValueArgument(1, irGet(dst.symbol))
|
||||
val setArrayElementCall = irCall(arrayHandle.setMethodSymbol.owner)
|
||||
setArrayElementCall.dispatchReceiver = irGet(arrayTmpVariable)
|
||||
setArrayElementCall.putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable) else irConstInt(i))
|
||||
setArrayElementCall.putValueArgument(1, irGet(dst))
|
||||
block.statements.add(setArrayElementCall)
|
||||
if (hasSpreadElement) {
|
||||
block.statements.add(incrementVariable(indexTmpVariable.symbol, kIntOne))
|
||||
block.statements.add(incrementVariable(indexTmpVariable, kIntOne))
|
||||
}
|
||||
} else {
|
||||
val arraySizeVariable = scope.createTemporaryVariable(irArraySize(arrayHandle, irGet(dst.symbol)), "length".synthesizedString)
|
||||
val arraySizeVariable = scope.createTemporaryVariable(irArraySize(arrayHandle, irGet(dst)), "length".synthesizedString)
|
||||
block.statements.add(arraySizeVariable)
|
||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol).apply {
|
||||
extensionReceiver = irGet(dst.symbol)
|
||||
putValueArgument(0, irGet(arrayTmpVariable.symbol)) /* destination */
|
||||
val copyCall = irCall(arrayHandle.copyRangeToSymbol.owner).apply {
|
||||
extensionReceiver = irGet(dst)
|
||||
putValueArgument(0, irGet(arrayTmpVariable)) /* destination */
|
||||
putValueArgument(1, kIntZero) /* fromIndex */
|
||||
putValueArgument(2, irGet(arraySizeVariable.symbol)) /* toIndex */
|
||||
putValueArgument(3, irGet(indexTmpVariable.symbol)) /* destinationIndex */
|
||||
putValueArgument(2, irGet(arraySizeVariable)) /* toIndex */
|
||||
putValueArgument(3, irGet(indexTmpVariable)) /* destinationIndex */
|
||||
}
|
||||
block.statements.add(copyCall)
|
||||
block.statements.add(incrementVariable(indexTmpVariable.symbol,
|
||||
irGet(arraySizeVariable.symbol)))
|
||||
block.statements.add(incrementVariable(indexTmpVariable, irGet(arraySizeVariable)))
|
||||
log { "element:$i:spread element> ${ir2string(element.expression)}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
block.statements.add(irGet(arrayTmpVariable.symbol))
|
||||
block.statements.add(irGet(arrayTmpVariable))
|
||||
return block
|
||||
}
|
||||
}
|
||||
@@ -171,24 +170,21 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
}
|
||||
|
||||
private val symbols = context.ir.symbols
|
||||
private val intPlusInt = symbols.intPlusInt
|
||||
private val intPlusInt = symbols.intPlusInt.owner
|
||||
|
||||
private fun arrayType(type: KotlinType): ArrayHandle = when {
|
||||
KotlinBuiltIns.isPrimitiveArray(type) -> {
|
||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.constructor.declarationDescriptor!!)
|
||||
when (primitiveType) {
|
||||
PrimitiveType.BYTE -> kByteArrayHandler
|
||||
PrimitiveType.SHORT -> kShortArrayHandler
|
||||
PrimitiveType.CHAR -> kCharArrayHandler
|
||||
PrimitiveType.INT -> kIntArrayHandler
|
||||
PrimitiveType.LONG -> kLongArrayHandler
|
||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||
else -> TODO("unsupported type: $primitiveType")
|
||||
}
|
||||
private fun arrayType(type: IrType): ArrayHandle {
|
||||
val primitiveType = KotlinBuiltIns.getPrimitiveArrayType(type.classifierOrFail.descriptor)
|
||||
return when (primitiveType) {
|
||||
PrimitiveType.BYTE -> kByteArrayHandler
|
||||
PrimitiveType.SHORT -> kShortArrayHandler
|
||||
PrimitiveType.CHAR -> kCharArrayHandler
|
||||
PrimitiveType.INT -> kIntArrayHandler
|
||||
PrimitiveType.LONG -> kLongArrayHandler
|
||||
PrimitiveType.FLOAT -> kFloatArrayHandler
|
||||
PrimitiveType.DOUBLE -> kDoubleArrayHandler
|
||||
PrimitiveType.BOOLEAN -> kBooleanArrayHandler
|
||||
else -> kArrayHandler
|
||||
}
|
||||
else -> kArrayHandler
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.intPlus() = irCall(intPlusInt)
|
||||
@@ -199,9 +195,9 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.incrementVariable(symbol: IrVariableSymbol, value: IrExpression): IrExpression {
|
||||
return irSetVar(symbol, intPlus().apply {
|
||||
dispatchReceiver = irGet(symbol)
|
||||
private fun IrBuilderWithScope.incrementVariable(variable: IrVariable, value: IrExpression): IrExpression {
|
||||
return irSetVar(variable.symbol, intPlus().apply {
|
||||
dispatchReceiver = irGet(variable)
|
||||
putValueArgument(0, value)
|
||||
})
|
||||
}
|
||||
@@ -212,14 +208,14 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
val notSpreadElementCount = expression.elements.filter { it !is IrSpreadElement}.size
|
||||
val initialValue = irConstInt(notSpreadElementCount) as IrExpression
|
||||
return vars.filter{it.key is IrSpreadElement}.toList().fold( initial = initialValue) { result, it ->
|
||||
val arraySize = irArraySize(arrayHandle, irGet(it.second.symbol))
|
||||
val arraySize = irArraySize(arrayHandle, irGet(it.second))
|
||||
increment(result, arraySize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irArraySize(arrayHandle: ArrayHandle, expression: IrExpression): IrExpression {
|
||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol).apply {
|
||||
val arraySize = irCall(arrayHandle.sizeGetterSymbol.owner).apply {
|
||||
dispatchReceiver = expression
|
||||
}
|
||||
return arraySize
|
||||
@@ -256,7 +252,8 @@ class VarargInjectionLowering constructor(val context: CommonBackendContext): De
|
||||
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> = IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
|
||||
private fun IrBuilderWithScope.irBlock(type: KotlinType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private fun IrBuilderWithScope.irConstInt(value: Int): IrConst<Int> =
|
||||
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, value)
|
||||
private fun IrBuilderWithScope.irBlock(type: IrType): IrBlock = IrBlockImpl(startOffset, endOffset, type)
|
||||
private val IrBuilderWithScope.kIntZero get() = irConstInt(0)
|
||||
private val IrBuilderWithScope.kIntOne get() = irConstInt(1)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.common.utils
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.CommonSupertypes
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.isInterface
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
|
||||
fun IrType.isNullable() = toKotlinType().isNullable()
|
||||
|
||||
fun IrType.isInterface() = toKotlinType().isInterface()
|
||||
|
||||
fun IrType.isPrimitiveArray() = KotlinBuiltIns.isPrimitiveArray(toKotlinType())
|
||||
|
||||
fun IrType.isTypeParameter() = toKotlinType().isTypeParameter()
|
||||
|
||||
fun IrType.isFunctionOrKFunction() = toKotlinType().isFunctionOrKFunctionType
|
||||
|
||||
fun IrType.isFunctionTypeOrSubtype() = toKotlinType().isFunctionTypeOrSubtype
|
||||
|
||||
fun List<IrType>.commonSupertype() = CommonSupertypes.commonSupertype(map(IrType::toKotlinType)).toIrType()!!
|
||||
|
||||
fun IrType.isSubtypeOf(superType: IrType) = toKotlinType().isSubtypeOf(superType.toKotlinType())
|
||||
|
||||
fun IrType.isSubtypeOfClass(superClass: IrClassSymbol) = DescriptorUtils.isSubtypeOfClass(toKotlinType(), superClass.descriptor)
|
||||
@@ -16,39 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.substitute
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
|
||||
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.builtIns.unitType, origin)
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||
|
||||
fun IrBuilderWithScope.irBreak(loop: IrLoop) =
|
||||
IrBreakImpl(startOffset, endOffset, context.builtIns.nothingType, loop)
|
||||
IrBreakImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
||||
IrContinueImpl(startOffset, endOffset, context.builtIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irTrue() = IrConstImpl.boolean(startOffset, endOffset, context.builtIns.booleanType, true)
|
||||
|
||||
fun IrBuilderWithScope.irFalse() = IrConstImpl.boolean(startOffset, endOffset, context.builtIns.booleanType, false)
|
||||
|
||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: Map<TypeParameterDescriptor, KotlinType>) =
|
||||
IrCallImpl(this.startOffset, this.endOffset, symbol, symbol.descriptor.substitute(typeArguments), typeArguments)
|
||||
|
||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List<KotlinType>) =
|
||||
irCall(symbol, symbol.descriptor.typeParameters.zip(typeArguments).toMap())
|
||||
IrContinueImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irGetObject(classSymbol: IrClassSymbol) =
|
||||
IrGetObjectValueImpl(startOffset, endOffset, classSymbol.owner.defaultType, classSymbol)
|
||||
|
||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, symbol: IrFieldSymbol) =
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver)
|
||||
IrGetObjectValueImpl(startOffset, endOffset, IrSimpleTypeImpl(classSymbol, false, emptyList(), emptyList()), classSymbol)
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencies {
|
||||
compile(project(":compiler:backend-common"))
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compile(project(":compiler:ir.psi2ir"))
|
||||
compile(project(":compiler:ir.backend.common"))
|
||||
compile(project(":js:js.ast"))
|
||||
compile(project(":js:js.frontend"))
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.js
|
||||
@@ -29,6 +18,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -64,7 +54,7 @@ class JsDescriptorsFactory : DescriptorsFactory {
|
||||
false
|
||||
).apply {
|
||||
setType(
|
||||
outerClass.defaultType,
|
||||
outerClass.defaultType.toKotlinType(),
|
||||
emptyList(),
|
||||
innerClass.descriptor.thisAsReceiverParameter,
|
||||
null as? ReceiverParameterDescriptor
|
||||
|
||||
@@ -25,7 +25,7 @@ class JsIntrinsics(
|
||||
context: JsIrBackendContext
|
||||
) {
|
||||
|
||||
private val stubBuilder = DeclarationStubGenerator(context.symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||
private val stubBuilder = DeclarationStubGenerator(module, context.symbolTable, JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB)
|
||||
|
||||
// Equality operations:
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.ModuleIndex
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -59,7 +61,7 @@ class JsIrBackendContext(
|
||||
|
||||
val secondaryConstructorsMap = mutableMapOf<IrConstructorSymbol, SecondaryCtorPair>()
|
||||
|
||||
fun getOperatorByName(name: Name, type: KotlinType) = operatorMap[name]?.get(type)
|
||||
fun getOperatorByName(name: Name, type: IrType) = operatorMap[name]?.get(type.toKotlinType())
|
||||
|
||||
val originalModuleIndex = ModuleIndex(irModuleFragment)
|
||||
|
||||
@@ -109,6 +111,7 @@ class JsIrBackendContext(
|
||||
}
|
||||
|
||||
private fun referenceOperators() = OperatorNames.ALL.map { name ->
|
||||
// TODO to replace KotlinType with IrType we need right equals on IrType
|
||||
name to irBuiltIns.primitiveTypes.fold(mutableMapOf<KotlinType, IrFunctionSymbol>()) { m, t ->
|
||||
val function = t.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).singleOrNull()
|
||||
function?.let { m.put(t, symbolTable.referenceSimpleFunction(it)) }
|
||||
|
||||
@@ -40,24 +40,28 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
||||
false, false, variableDescriptor.isLateInit, variableDescriptor.source
|
||||
)
|
||||
|
||||
val valueType = originalDeclaration.descriptor.type
|
||||
val valueType = originalDeclaration.type
|
||||
val boxConstructor = closureBoxConstructorTypeDescriptor
|
||||
val boxConstructorSymbol = closureBoxConstructorTypeSymbol
|
||||
val constructorTypeParam = closureBoxConstructorTypeDescriptor.typeParameters[0]
|
||||
val boxConstructorTypeArgument = mapOf(constructorTypeParam to valueType)
|
||||
val initializer = originalDeclaration.initializer ?: IrConstImpl.constNull(
|
||||
originalDeclaration.startOffset,
|
||||
originalDeclaration.endOffset,
|
||||
valueType
|
||||
)
|
||||
// TODO use buildCall?
|
||||
val constructorCall = IrCallImpl(
|
||||
originalDeclaration.startOffset,
|
||||
originalDeclaration.endOffset,
|
||||
// TODO wrong type
|
||||
originalDeclaration.type,
|
||||
boxConstructorSymbol,
|
||||
boxConstructor,
|
||||
boxConstructorTypeArgument,
|
||||
1,
|
||||
JsLoweredDeclarationOrigin.JS_CLOSURE_BOX_CLASS
|
||||
).apply { putValueArgument(0, initializer) }
|
||||
).apply {
|
||||
putTypeArgument(0, valueType)
|
||||
putValueArgument(0, initializer)
|
||||
}
|
||||
|
||||
|
||||
return IrVariableImpl(
|
||||
@@ -65,6 +69,8 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
||||
originalDeclaration.endOffset,
|
||||
originalDeclaration.origin,
|
||||
sharedVariableDescriptor,
|
||||
// TODO wrong type ?
|
||||
originalDeclaration.type,
|
||||
constructorCall
|
||||
)
|
||||
}
|
||||
@@ -75,9 +81,11 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
||||
IrGetFieldImpl(
|
||||
originalGet.startOffset, originalGet.endOffset,
|
||||
closureBoxFieldSymbol,
|
||||
originalGet.type,
|
||||
IrGetValueImpl(
|
||||
originalGet.startOffset,
|
||||
originalGet.endOffset,
|
||||
originalGet.type,
|
||||
sharedVariableSymbol
|
||||
),
|
||||
originalGet.origin
|
||||
@@ -90,9 +98,11 @@ class JsSharedVariablesManager(val builtIns: KotlinBuiltIns, val jsInterinalPack
|
||||
IrGetValueImpl(
|
||||
originalSet.startOffset,
|
||||
originalSet.endOffset,
|
||||
originalSet.type,
|
||||
sharedVariableSymbol
|
||||
),
|
||||
originalSet.value,
|
||||
originalSet.type,
|
||||
originalSet.origin
|
||||
)
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@ fun compile(
|
||||
moduleFragment
|
||||
)
|
||||
|
||||
ExternalDependenciesGenerator(psi2IrContext.symbolTable, psi2IrContext.irBuiltIns).generateUnboundSymbolsAsDependencies(moduleFragment)
|
||||
ExternalDependenciesGenerator(psi2IrContext.moduleDescriptor, psi2IrContext.symbolTable, psi2IrContext.irBuiltIns)
|
||||
.generateUnboundSymbolsAsDependencies(moduleFragment)
|
||||
|
||||
context.performInlining(moduleFragment)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class JsIrArithBuilder(val context: JsIrBackendContext) {
|
||||
fun inv(v: IrExpression): IrExpression = buildUnaryOperator(OperatorNames.INV, v)
|
||||
|
||||
fun andand(l: IrExpression, r: IrExpression) = // if (l) r else false
|
||||
JsIrBuilder.buildIfElse(context.builtIns.booleanType, l, r, JsIrBuilder.buildBoolean(context.builtIns.booleanType, false))
|
||||
JsIrBuilder.buildIfElse(context.irBuiltIns.booleanType, l, r, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false))
|
||||
fun oror(l: IrExpression, r: IrExpression) = // if (l) true else r
|
||||
JsIrBuilder.buildIfElse(context.builtIns.booleanType, l, JsIrBuilder.buildBoolean(context.builtIns.booleanType, true), r)
|
||||
JsIrBuilder.buildIfElse(context.irBuiltIns.booleanType, l, JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true), r)
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.ir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
@@ -15,76 +15,103 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
object JsIrBuilder {
|
||||
|
||||
object SYNTHESIZED_STATEMENT : IrStatementOriginImpl("SYNTHESIZED_STATEMENT")
|
||||
object SYNTHESIZED_DECLARATION : IrDeclarationOriginImpl("SYNTHESIZED_DECLARATION")
|
||||
|
||||
fun buildCall(target: IrFunctionSymbol, type: KotlinType? = null, typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null) =
|
||||
fun buildCall(target: IrFunctionSymbol, type: IrType? = null, typeArguments: List<IrType>? = null): IrCall =
|
||||
IrCallImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
type ?: target.descriptor.returnType!!,
|
||||
type ?: target.owner.returnType,
|
||||
target,
|
||||
target.descriptor,
|
||||
typeArguments,
|
||||
target.owner.typeParameters.size,
|
||||
SYNTHESIZED_STATEMENT
|
||||
)
|
||||
).apply {
|
||||
typeArguments?.let {
|
||||
assert(typeArguments.size == typeArgumentsCount)
|
||||
it.withIndex().forEach { (i, t) -> putTypeArgument(i, t) }
|
||||
}
|
||||
}
|
||||
|
||||
fun buildReturn(targetSymbol: IrFunctionSymbol, value: IrExpression) =
|
||||
IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetSymbol, value)
|
||||
fun buildReturn(targetSymbol: IrFunctionSymbol, value: IrExpression, context: BackendContext) =
|
||||
IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.nothingType, targetSymbol, value)
|
||||
|
||||
fun buildThrow(type: KotlinType, value: IrExpression) = IrThrowImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, value)
|
||||
fun buildThrow(type: IrType, value: IrExpression) = IrThrowImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, value)
|
||||
|
||||
fun buildValueParameter(symbol: IrValueParameterSymbol) =
|
||||
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol)
|
||||
fun buildValueParameter(symbol: IrValueParameterSymbol, type: IrType? = null) =
|
||||
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol, type ?: symbol.owner.type, null)
|
||||
|
||||
fun buildFunction(symbol: IrSimpleFunctionSymbol) = IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol)
|
||||
fun buildFunction(symbol: IrSimpleFunctionSymbol, returnType: IrType) =
|
||||
IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol).apply {
|
||||
this.returnType = returnType
|
||||
}
|
||||
|
||||
fun buildGetObjectValue(type: KotlinType, classSymbol: IrClassSymbol) =
|
||||
fun buildGetObjectValue(type: IrType, classSymbol: IrClassSymbol) =
|
||||
IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, classSymbol)
|
||||
|
||||
fun buildGetClass(expression: IrExpression, type: KotlinType) = IrGetClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, expression)
|
||||
fun buildGetClass(expression: IrExpression, type: IrType) = IrGetClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, expression)
|
||||
|
||||
fun buildGetValue(symbol: IrValueSymbol) = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, SYNTHESIZED_STATEMENT)
|
||||
fun buildSetVariable(symbol: IrVariableSymbol, value: IrExpression) =
|
||||
IrSetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, value, SYNTHESIZED_STATEMENT)
|
||||
fun buildGetValue(symbol: IrValueSymbol) = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol.owner.type, symbol, SYNTHESIZED_STATEMENT)
|
||||
fun buildSetVariable(symbol: IrVariableSymbol, value: IrExpression, type: IrType) =
|
||||
IrSetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, value, SYNTHESIZED_STATEMENT)
|
||||
|
||||
fun buildGetField(symbol: IrFieldSymbol, receiver: IrExpression?, superQualifierSymbol: IrClassSymbol? = null) =
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, symbol.owner.type, receiver, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
|
||||
fun buildSetField(symbol: IrFieldSymbol, receiver: IrExpression?, value: IrExpression, superQualifierSymbol: IrClassSymbol? = null) =
|
||||
IrSetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, value, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
fun buildSetField(symbol: IrFieldSymbol, receiver: IrExpression?, value: IrExpression, type: IrType, superQualifierSymbol: IrClassSymbol? = null) =
|
||||
IrSetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol, receiver, value, type, SYNTHESIZED_STATEMENT, superQualifierSymbol)
|
||||
|
||||
fun buildBlockBody(statements: List<IrStatement>) = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, statements)
|
||||
|
||||
fun buildBlock(type: KotlinType) = IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT)
|
||||
fun buildBlock(type: KotlinType, statements: List<IrStatement>) =
|
||||
fun buildBlock(type: IrType) = IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT)
|
||||
fun buildBlock(type: IrType, statements: List<IrStatement>) =
|
||||
IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT, statements)
|
||||
|
||||
fun buildFunctionReference(type: KotlinType, symbol: IrFunctionSymbol) =
|
||||
IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, symbol.descriptor)
|
||||
fun buildFunctionReference(type: IrType, symbol: IrFunctionSymbol) =
|
||||
IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, symbol.descriptor, 0, null)
|
||||
|
||||
fun buildVar(symbol: IrVariableSymbol, initializer: IrExpression? = null) =
|
||||
IrVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol).apply { this.initializer = initializer }
|
||||
fun buildVar(symbol: IrVariableSymbol, initializer: IrExpression? = null, type: IrType?) =
|
||||
IrVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, SYNTHESIZED_DECLARATION, symbol, type ?: symbol.owner.type).apply { this.initializer = initializer }
|
||||
|
||||
fun buildBreak(type: KotlinType, loop: IrLoop) = IrBreakImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
||||
fun buildContinue(type: KotlinType, loop: IrLoop) = IrContinueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
||||
fun buildBreak(type: IrType, loop: IrLoop) = IrBreakImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
||||
fun buildContinue(type: IrType, loop: IrLoop) = IrContinueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, loop)
|
||||
|
||||
fun buildIfElse(type: KotlinType, cond: IrExpression, thenBranch: IrExpression, elseBranch: IrExpression? = null) = IrIfThenElseImpl(
|
||||
fun buildIfElse(type: IrType, cond: IrExpression, thenBranch: IrExpression, elseBranch: IrExpression? = null): IrWhen = buildIfElse(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, cond, thenBranch, elseBranch, SYNTHESIZED_STATEMENT
|
||||
)
|
||||
|
||||
fun buildWhen(type: KotlinType, branches: List<IrBranch>) =
|
||||
fun buildIfElse(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: IrType,
|
||||
cond: IrExpression,
|
||||
thenBranch: IrExpression,
|
||||
elseBranch: IrExpression? = null,
|
||||
origin: IrStatementOrigin? = null
|
||||
): IrWhen {
|
||||
val element = IrIfThenElseImpl(startOffset, endOffset, type, origin)
|
||||
element.branches.add(IrBranchImpl(cond, thenBranch))
|
||||
if (elseBranch != null) {
|
||||
val irTrue = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cond.type, true)
|
||||
element.branches.add(IrElseBranchImpl(irTrue, elseBranch))
|
||||
}
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
fun buildWhen(type: IrType, branches: List<IrBranch>) =
|
||||
IrWhenImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, SYNTHESIZED_STATEMENT, branches)
|
||||
|
||||
fun buildTypeOperator(type: KotlinType, operator: IrTypeOperator, argument: IrExpression, toType: KotlinType, symbol: IrClassifierSymbol) =
|
||||
IrTypeOperatorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, operator, toType, argument, symbol)
|
||||
fun buildTypeOperator(type: IrType, operator: IrTypeOperator, argument: IrExpression, toType: IrType, symbol: IrClassifierSymbol) =
|
||||
IrTypeOperatorCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, operator, toType, symbol, argument)
|
||||
|
||||
fun buildNull(type: KotlinType) = IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type)
|
||||
fun buildBoolean(type: KotlinType, v: Boolean) = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||
fun buildInt(type: KotlinType, v: Int) = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||
fun buildString(type: KotlinType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s)
|
||||
}
|
||||
fun buildNull(type: IrType) = IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type)
|
||||
fun buildBoolean(type: IrType, v: Boolean) = IrConstImpl.boolean(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||
fun buildInt(type: IrType, v: Int) = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, v)
|
||||
fun buildString(type: IrType, s: String) = IrConstImpl.string(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, s)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
@@ -17,9 +16,11 @@ import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
private typealias VisitData = Nothing?
|
||||
|
||||
@@ -30,15 +31,20 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
private val statementVisitor = StatementVisitor()
|
||||
private val expressionVisitor = ExpressionVisitor()
|
||||
|
||||
private val constTrue = JsIrBuilder.buildBoolean(context.builtIns.booleanType, true)
|
||||
private val constFalse = JsIrBuilder.buildBoolean(context.builtIns.booleanType, false)
|
||||
private val nothingType = context.builtIns.nullableNothingType
|
||||
private val constTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||
private val constFalse = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false)
|
||||
private val nothingType get() = context.irBuiltIns.nothingType
|
||||
private val unitType get() = context.irBuiltIns.unitType
|
||||
|
||||
private val unitType = context.builtIns.unitType
|
||||
private val unitValue = JsIrBuilder.buildGetObjectValue(unitType, context.symbolTable.referenceClass(context.builtIns.unit))
|
||||
|
||||
private val unreachableFunction =
|
||||
JsSymbolBuilder.buildSimpleFunction(context.module, Namer.UNREACHABLE_NAME).initialize(type = nothingType)
|
||||
private val unreachableFunction = JsIrBuilder.buildFunction(
|
||||
JsSymbolBuilder.buildSimpleFunction(
|
||||
context.module,
|
||||
Namer.UNREACHABLE_NAME
|
||||
).initialize(returnType = nothingType),
|
||||
nothingType
|
||||
)
|
||||
|
||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||
irDeclarationContainer.declarations.transformFlat { declaration ->
|
||||
@@ -61,17 +67,18 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
|
||||
fun lower(irField: IrField, container: IrDeclarationContainer): List<IrDeclaration> {
|
||||
irField.initializer?.apply {
|
||||
val returnType = expression.type
|
||||
val initFnSymbol = JsSymbolBuilder.buildSimpleFunction(
|
||||
(container as IrSymbolOwner).symbol.descriptor,
|
||||
irField.name.asString() + "\$init\$"
|
||||
).initialize(type = expression.type)
|
||||
).initialize(returnType = returnType)
|
||||
|
||||
|
||||
val newBody = IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply {
|
||||
statements += JsIrBuilder.buildReturn(initFnSymbol, expression)
|
||||
statements += JsIrBuilder.buildReturn(initFnSymbol, expression, context)
|
||||
}
|
||||
|
||||
val initFn = JsIrBuilder.buildFunction(initFnSymbol).apply {
|
||||
val initFn = JsIrBuilder.buildFunction(initFnSymbol, returnType).apply {
|
||||
body = newBody
|
||||
}
|
||||
|
||||
@@ -314,15 +321,15 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
expression.type,
|
||||
expression.operator,
|
||||
expression.typeOperand,
|
||||
resultValue,
|
||||
expression.typeOperandClassifier
|
||||
expression.typeOperandClassifier,
|
||||
resultValue
|
||||
)
|
||||
|
||||
val resValue: IrExpression
|
||||
|
||||
if (!KotlinBuiltIns.isUnit(expression.type)) {
|
||||
if (!expression.type.isUnit()) {
|
||||
val resVar = makeTempVar(expression.type)
|
||||
statements += JsIrBuilder.buildVar(resVar, newOperator)
|
||||
statements += JsIrBuilder.buildVar(resVar, newOperator, type = expression.type)
|
||||
resValue = JsIrBuilder.buildGetValue(resVar)
|
||||
} else {
|
||||
statements += newOperator
|
||||
@@ -364,7 +371,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
}
|
||||
|
||||
if (needNew) {
|
||||
newStatements += JsIrBuilder.buildSetField(expression.symbol, newReceiver, newValue, expression.superQualifierSymbol)
|
||||
newStatements += JsIrBuilder.buildSetField(expression.symbol, newReceiver, newValue, unitType, expression.superQualifierSymbol)
|
||||
return DecomposedResult(newStatements, unitValue)
|
||||
}
|
||||
|
||||
@@ -375,7 +382,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
val valueResult = expression.value.accept(expressionVisitor, data)
|
||||
|
||||
return valueResult.runIfChanged {
|
||||
statements += JsIrBuilder.buildSetVariable(expression.symbol, resultValue)
|
||||
statements += JsIrBuilder.buildSetVariable(expression.symbol, resultValue, unitType)
|
||||
DecomposedResult(statements, unitValue)
|
||||
}
|
||||
}
|
||||
@@ -400,7 +407,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
// val x = x_tmp
|
||||
override fun visitContainerExpression(expression: IrContainerExpression, data: VisitData): VisitResult {
|
||||
val variable = makeTempVar(expression.type)
|
||||
val varDeclaration = JsIrBuilder.buildVar(variable)
|
||||
val varDeclaration = JsIrBuilder.buildVar(variable, type = expression.type)
|
||||
|
||||
val blockStatements = expression.statements
|
||||
val lastStatement: IrStatement? = blockStatements.lastOrNull()
|
||||
@@ -434,7 +441,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
collectingList += statements
|
||||
resultValue
|
||||
}
|
||||
collectingList += JsIrBuilder.buildSetVariable(variable, result)
|
||||
collectingList += JsIrBuilder.buildSetVariable(variable, result, unitType)
|
||||
if (body is IrComposite) {
|
||||
DecomposedResult(mutableListOf(varDeclaration, *collectingList.toTypedArray()) , JsIrBuilder.buildGetValue(variable))
|
||||
} else {
|
||||
@@ -463,7 +470,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
private fun prepareArgument(arg: IrExpression, needWrap: Boolean, statements: MutableList<IrStatement>): IrExpression {
|
||||
return if (needWrap) {
|
||||
val wrapVar = makeTempVar(arg.type)
|
||||
statements += JsIrBuilder.buildVar(wrapVar, arg)
|
||||
statements += JsIrBuilder.buildVar(wrapVar, arg, type = arg.type)
|
||||
JsIrBuilder.buildGetValue(wrapVar)
|
||||
} else arg
|
||||
}
|
||||
@@ -543,21 +550,21 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
val resultVar = makeTempVar(expression.type)
|
||||
|
||||
// TODO: get rid of temporary variable
|
||||
newStatements += JsIrBuilder.buildVar(resultVar, expression)
|
||||
newStatements += JsIrBuilder.buildVar(resultVar, expression, type = expression.type)
|
||||
|
||||
return DecomposedResult(newStatements, JsIrBuilder.buildGetValue(resultVar))
|
||||
}
|
||||
|
||||
override fun visitWhen(expression: IrWhen, data: VisitData): VisitResult {
|
||||
val collectiveVar = makeTempVar(expression.type)
|
||||
val varDeclaration = JsIrBuilder.buildVar(collectiveVar)
|
||||
val varDeclaration = JsIrBuilder.buildVar(collectiveVar, type = expression.type)
|
||||
val newWhen = processWhen(expression, data, this, this) { visitResult, original ->
|
||||
val resultList = mutableListOf<IrStatement>()
|
||||
val newResult = visitResult.runIfChangedOrDefault(original as IrExpression) {
|
||||
resultList += statements
|
||||
resultValue
|
||||
}
|
||||
resultList.apply { add(JsIrBuilder.buildSetVariable(collectiveVar, newResult)) }
|
||||
resultList.apply { add(JsIrBuilder.buildSetVariable(collectiveVar, newResult, unitType)) }
|
||||
}
|
||||
|
||||
if (newWhen != expression) {
|
||||
@@ -587,7 +594,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
resultValue
|
||||
}
|
||||
val wrapVar = makeTempVar(expression.varargElementType)
|
||||
newStatements += JsIrBuilder.buildVar(wrapVar).apply { initializer = newExpression }
|
||||
newStatements += JsIrBuilder.buildVar(wrapVar, type = expression.type).apply { initializer = newExpression }
|
||||
val newValue = JsIrBuilder.buildGetValue(wrapVar)
|
||||
if (original is IrSpreadElement) {
|
||||
IrSpreadElementImpl(original.startOffset, original.endOffset, newValue)
|
||||
@@ -641,7 +648,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
|
||||
newStatements += instantiater(returnValue)
|
||||
|
||||
return TerminatedResult(newStatements, JsIrBuilder.buildCall(unreachableFunction))
|
||||
return TerminatedResult(newStatements, JsIrBuilder.buildCall(unreachableFunction.symbol))
|
||||
}
|
||||
|
||||
|
||||
@@ -658,7 +665,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
)
|
||||
|
||||
override fun visitBreakContinue(jump: IrBreakContinue, data: VisitData): VisitResult {
|
||||
return DecomposedResult(jump, JsIrBuilder.buildCall(unreachableFunction))
|
||||
return DecomposedResult(jump, JsIrBuilder.buildCall(unreachableFunction.symbol))
|
||||
}
|
||||
|
||||
override fun visitTry(aTry: IrTry, data: VisitData): VisitResult {
|
||||
@@ -669,10 +676,10 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
finallyResult?.run { assert(status == VisitStatus.KEPT) }
|
||||
|
||||
val resultSymbol = makeTempVar(aTry.type)
|
||||
val resultDeclaration = JsIrBuilder.buildVar(resultSymbol)
|
||||
val resultDeclaration = JsIrBuilder.buildVar(resultSymbol, type = aTry.type)
|
||||
|
||||
val newTryValue = tryResult.runIfChangedOrDefault(aTry.tryResult) { resultValue }
|
||||
val trySetResult = JsIrBuilder.buildSetVariable(resultSymbol, newTryValue) as IrStatement
|
||||
val trySetResult = JsIrBuilder.buildSetVariable(resultSymbol, newTryValue, unitType) as IrStatement
|
||||
|
||||
val tryBlock = IrBlockImpl(aTry.tryResult.startOffset, aTry.tryResult.endOffset, unitType).apply {
|
||||
statements += tryResult.runIfChangedOrDefault(listOf(trySetResult)) { statements + trySetResult }
|
||||
@@ -680,7 +687,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
|
||||
val catchBlocks = catchResults.map { (original, result) ->
|
||||
val newCatchResult = result.runIfChangedOrDefault(original.result) { resultValue }
|
||||
val catchSetResult = JsIrBuilder.buildSetVariable(resultSymbol, newCatchResult) as IrStatement
|
||||
val catchSetResult = JsIrBuilder.buildSetVariable(resultSymbol, newCatchResult, unitType) as IrStatement
|
||||
val catchBlock = IrBlockImpl(original.result.startOffset, original.result.endOffset, unitType)
|
||||
catchBlock.statements += result.runIfChangedOrDefault(listOf(catchSetResult)) { statements + catchSetResult }
|
||||
IrCatchImpl(original.startOffset, original.endOffset, original.catchParameter, catchBlock)
|
||||
@@ -713,7 +720,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
}
|
||||
}
|
||||
|
||||
fun makeTempVar(type: KotlinType) =
|
||||
fun makeTempVar(type: IrType) =
|
||||
JsSymbolBuilder.buildTempVar(function.symbol, type, "tmp\$dcms\$${tmpVarCounter++}", true)
|
||||
|
||||
fun makeLoopLabel() = "\$l\$${tmpVarCounter++}"
|
||||
@@ -782,7 +789,7 @@ class BlockDecomposerLowering(val context: JsIrBackendContext) : DeclarationCont
|
||||
JsIrBuilder.buildBlock(unitType).also {
|
||||
val elseBlock = if (originalBranch is IrElseBranch) null else it
|
||||
|
||||
val ifElseNode = IrIfThenElseImpl(
|
||||
val ifElseNode = JsIrBuilder.buildIfElse(
|
||||
originalBranch.startOffset,
|
||||
originalBranch.endOffset,
|
||||
unitType,
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
|
||||
@@ -39,9 +41,9 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
private val callableToGetterFunction = mutableMapOf<CallableReferenceKey, IrFunction>()
|
||||
private val collectedReferenceMap = mutableMapOf<CallableReferenceKey, IrCallableReference>()
|
||||
|
||||
private val callableNameConst = JsIrBuilder.buildString(context.irBuiltIns.string, Namer.KCALLABLE_NAME)
|
||||
private val getterConst = JsIrBuilder.buildString(context.irBuiltIns.string, Namer.KPROPERTY_GET)
|
||||
private val setterConst = JsIrBuilder.buildString(context.irBuiltIns.string, Namer.KPROPERTY_SET)
|
||||
private val callableNameConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KCALLABLE_NAME)
|
||||
private val getterConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_GET)
|
||||
private val setterConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_SET)
|
||||
|
||||
private val newDeclarations = mutableListOf<IrDeclaration>()
|
||||
|
||||
@@ -97,7 +99,13 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
}
|
||||
|
||||
private fun redirectToFunction(callable: IrCallableReference, newTarget: IrFunction) =
|
||||
IrCallImpl(callable.startOffset, callable.endOffset, newTarget.symbol, callable.origin).apply {
|
||||
IrCallImpl(
|
||||
callable.startOffset, callable.endOffset,
|
||||
newTarget.symbol.owner.returnType,
|
||||
newTarget.symbol,
|
||||
newTarget.symbol.descriptor,
|
||||
callable.origin
|
||||
).apply {
|
||||
copyTypeArgumentsFrom(callable)
|
||||
var index = 0
|
||||
callable.dispatchReceiver?.let { putValueArgument(index++, it) }
|
||||
@@ -156,13 +164,13 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
val additionalDeclarations = generateGetterBodyWithGuard(refGetFunction) {
|
||||
val irClosureReference = JsIrBuilder.buildFunctionReference(functionReference.type, refClosureFunction.symbol)
|
||||
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, irClosureReference.type)
|
||||
val irVar = JsIrBuilder.buildVar(irVarSymbol, irClosureReference)
|
||||
val irVar = JsIrBuilder.buildVar(irVarSymbol, irClosureReference, type = irClosureReference.type)
|
||||
|
||||
// TODO: fill other fields of callable reference (returnType, parameters, isFinal, etc.)
|
||||
val irSetName = JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
putValueArgument(1, callableNameConst)
|
||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.string, getReferenceName(declaration.descriptor)))
|
||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.stringType, getReferenceName(declaration.descriptor)))
|
||||
}
|
||||
Pair(listOf(irVar, irSetName), irVarSymbol)
|
||||
}
|
||||
@@ -203,10 +211,11 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
val statements = mutableListOf<IrStatement>()
|
||||
|
||||
val getterFunctionType = context.builtIns.getFunction(getterFunction.valueParameters.size + 1)
|
||||
val irGetReference = JsIrBuilder.buildFunctionReference(getterFunctionType.defaultType, getterFunction.symbol)
|
||||
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, getterFunctionType.defaultType)
|
||||
val type = getterFunctionType.toIrType()
|
||||
val irGetReference = JsIrBuilder.buildFunctionReference(type, getterFunction.symbol)
|
||||
val irVarSymbol = JsSymbolBuilder.buildTempVar(refGetFunction.symbol, type)
|
||||
|
||||
statements += JsIrBuilder.buildVar(irVarSymbol, irGetReference)
|
||||
statements += JsIrBuilder.buildVar(irVarSymbol, irGetReference, type = type)
|
||||
|
||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
@@ -216,7 +225,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
|
||||
if (setterFunction != null) {
|
||||
val setterFunctionType = context.builtIns.getFunction(setterFunction.valueParameters.size + 1)
|
||||
val irSetReference = JsIrBuilder.buildFunctionReference(setterFunctionType.defaultType, setterFunction.symbol)
|
||||
val irSetReference = JsIrBuilder.buildFunctionReference(setterFunctionType.toIrType(), setterFunction.symbol)
|
||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
putValueArgument(1, setterConst)
|
||||
@@ -228,7 +237,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
statements += JsIrBuilder.buildCall(context.intrinsics.jsSetJSField.symbol).apply {
|
||||
putValueArgument(0, JsIrBuilder.buildGetValue(irVarSymbol))
|
||||
putValueArgument(1, callableNameConst)
|
||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.string, getReferenceName(propertyReference.descriptor)))
|
||||
putValueArgument(2, JsIrBuilder.buildString(context.irBuiltIns.stringType, getReferenceName(propertyReference.descriptor)))
|
||||
}
|
||||
|
||||
Pair(statements, irVarSymbol)
|
||||
@@ -255,22 +264,23 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
// }
|
||||
//
|
||||
val cacheName = "${getterFunction.name}_${Namer.KCALLABLE_CACHE_SUFFIX}"
|
||||
val type = getterFunction.returnType
|
||||
val cacheVarSymbol =
|
||||
JsSymbolBuilder.buildVar(getterFunction.descriptor.containingDeclaration, getterFunction.returnType, cacheName, true)
|
||||
val irNull = JsIrBuilder.buildNull(cacheVarSymbol.descriptor.type)
|
||||
val irCacheDeclaration = JsIrBuilder.buildVar(cacheVarSymbol)
|
||||
JsSymbolBuilder.buildVar(getterFunction.descriptor.containingDeclaration, type, cacheName, true)
|
||||
val irNull = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType)
|
||||
val irCacheDeclaration = JsIrBuilder.buildVar(cacheVarSymbol, irNull, type = type)
|
||||
val irCacheValue = JsIrBuilder.buildGetValue(cacheVarSymbol)
|
||||
val irIfCondition = JsIrBuilder.buildCall(context.irBuiltIns.eqeqSymbol).apply {
|
||||
putValueArgument(0, irCacheValue)
|
||||
putValueArgument(1, irNull)
|
||||
}
|
||||
val irSetCache = JsIrBuilder.buildSetVariable(cacheVarSymbol, JsIrBuilder.buildGetValue(varSymbol))
|
||||
val irSetCache = JsIrBuilder.buildSetVariable(cacheVarSymbol, JsIrBuilder.buildGetValue(varSymbol), context.irBuiltIns.unitType)
|
||||
val thenStatements = mutableListOf<IrStatement>().apply {
|
||||
addAll(bodyStatements)
|
||||
add(irSetCache)
|
||||
}
|
||||
val irThenBranch = JsIrBuilder.buildBlock(context.irBuiltIns.unit, thenStatements)
|
||||
val irIfNode = JsIrBuilder.buildIfElse(context.irBuiltIns.unit, irIfCondition, irThenBranch)
|
||||
val irThenBranch = JsIrBuilder.buildBlock(context.irBuiltIns.unitType, thenStatements)
|
||||
val irIfNode = JsIrBuilder.buildIfElse(context.irBuiltIns.unitType, irIfCondition, irThenBranch)
|
||||
statements += irIfNode
|
||||
returnValue = irCacheValue
|
||||
returnStatements = listOf(irCacheDeclaration)
|
||||
@@ -280,7 +290,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
returnStatements = emptyList()
|
||||
}
|
||||
|
||||
statements += JsIrBuilder.buildReturn(getterFunction.symbol, returnValue)
|
||||
statements += JsIrBuilder.buildReturn(getterFunction.symbol, returnValue, context)
|
||||
|
||||
getterFunction.body = JsIrBuilder.buildBlockBody(statements)
|
||||
return returnStatements
|
||||
@@ -314,8 +324,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
private fun buildGetFunction(declaration: IrFunction, reference: IrCallableReference, getterName: String): IrSimpleFunction {
|
||||
|
||||
val callableType = reference.type
|
||||
val closureParams = callableType.arguments.dropLast(1) // drop return type
|
||||
var kFunctionValueParamsCount = closureParams.size
|
||||
var kFunctionValueParamsCount = (callableType as? IrSimpleType)?.arguments?.size?.minus(1) ?: 0
|
||||
|
||||
if (declaration.dispatchReceiverParameter != null && reference.dispatchReceiver == null) {
|
||||
kFunctionValueParamsCount--
|
||||
@@ -342,14 +351,22 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
val refGetSymbol = JsSymbolBuilder.buildSimpleFunction(declaration.descriptor.containingDeclaration, getterName).apply {
|
||||
initialize(
|
||||
valueParameters = getterValueParameters.mapIndexed { i, p -> p.descriptor.copyAsValueParameter(descriptor, i) },
|
||||
type = callableType
|
||||
returnType = callableType
|
||||
)
|
||||
}
|
||||
|
||||
return JsIrBuilder.buildFunction(refGetSymbol).apply {
|
||||
return JsIrBuilder.buildFunction(refGetSymbol, callableType).apply {
|
||||
for (i in 0 until getterValueParameters.size) {
|
||||
val p = getterValueParameters[i]
|
||||
valueParameters += IrValueParameterImpl(p.startOffset, p.endOffset, p.origin, refGetSymbol.descriptor.valueParameters[i])
|
||||
valueParameters +=
|
||||
IrValueParameterImpl(
|
||||
p.startOffset,
|
||||
p.endOffset,
|
||||
p.origin,
|
||||
refGetSymbol.descriptor.valueParameters[i],
|
||||
p.type,
|
||||
p.varargElementType
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,15 +383,18 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
val closureParamSymbols = generateSignatureForClosure(declaration, refGetFunction, refClosureSymbol, reference)
|
||||
val closureParamDescriptors = closureParamSymbols.map { it.descriptor as ValueParameterDescriptor }
|
||||
|
||||
refClosureSymbol.initialize(valueParameters = closureParamDescriptors, type = declaration.returnType)
|
||||
val returnType = declaration.returnType
|
||||
refClosureSymbol.initialize(valueParameters = closureParamDescriptors, returnType = returnType)
|
||||
|
||||
val closureFunction = JsIrBuilder.buildFunction(refClosureSymbol)
|
||||
val closureFunction = JsIrBuilder.buildFunction(refClosureSymbol, returnType)
|
||||
|
||||
for (it in closureParamSymbols) {
|
||||
closureFunction.valueParameters += JsIrBuilder.buildValueParameter(it)
|
||||
for (param in closureParamSymbols) {
|
||||
// TODO always take type from param
|
||||
val type = if (param.isBound) param.owner.type else context.irBuiltIns.anyType
|
||||
closureFunction.valueParameters += JsIrBuilder.buildValueParameter(param, type)
|
||||
}
|
||||
|
||||
val irCall = JsIrBuilder.buildCall(declaration.symbol)
|
||||
val irCall = JsIrBuilder.buildCall(declaration.symbol, type = returnType)
|
||||
|
||||
var cp = 0
|
||||
var gp = 0
|
||||
@@ -401,7 +421,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP
|
||||
irCall.putValueArgument(j++, JsIrBuilder.buildGetValue(closureParamSymbols[i]))
|
||||
}
|
||||
|
||||
val irClosureReturn = JsIrBuilder.buildReturn(closureFunction.symbol, irCall)
|
||||
val irClosureReturn = JsIrBuilder.buildReturn(closureFunction.symbol, irCall, context)
|
||||
|
||||
closureFunction.body = JsIrBuilder.buildBlockBody(listOf(irClosureReturn))
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOfClass
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
@@ -19,10 +19,10 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
|
||||
class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
||||
@@ -33,16 +33,13 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
private val symbolToIrFunction: Map<IrFunctionSymbol, IrSimpleFunction>
|
||||
private val nameToIrTransformer: Map<Name, (IrCall) -> IrCall>
|
||||
|
||||
val kCallable = context.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.kCallable.toSafe())
|
||||
val kProperty = context.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.kProperty.asSingleFqName())
|
||||
|
||||
init {
|
||||
memberToIrFunction = mutableMapOf()
|
||||
symbolToIrFunction = mutableMapOf()
|
||||
memberToTransformer = mutableMapOf()
|
||||
nameToIrTransformer = mutableMapOf()
|
||||
|
||||
val primitiveNumbers = context.irBuiltIns.run { listOf(int, short, byte, float, double) }
|
||||
val primitiveNumbers = context.irBuiltIns.run { listOf(intType, shortType, byteType, floatType, doubleType) }
|
||||
|
||||
memberToIrFunction.run {
|
||||
for (type in primitiveNumbers) {
|
||||
@@ -57,11 +54,11 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
op(type, OperatorNames.REM, context.intrinsics.jsMod)
|
||||
}
|
||||
|
||||
context.irBuiltIns.string.let {
|
||||
context.irBuiltIns.stringType.let {
|
||||
op(it, OperatorNames.ADD, context.intrinsics.jsPlus)
|
||||
}
|
||||
|
||||
context.irBuiltIns.int.let {
|
||||
context.irBuiltIns.intType.let {
|
||||
op(it, OperatorNames.SHL, context.intrinsics.jsBitShiftL)
|
||||
op(it, OperatorNames.SHR, context.intrinsics.jsBitShiftR)
|
||||
op(it, OperatorNames.SHRU, context.intrinsics.jsBitShiftRU)
|
||||
@@ -71,7 +68,7 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
op(it, OperatorNames.INV, context.intrinsics.jsBitNot)
|
||||
}
|
||||
|
||||
context.irBuiltIns.bool.let {
|
||||
context.irBuiltIns.booleanType.let {
|
||||
op(it, OperatorNames.AND, context.intrinsics.jsBitAnd)
|
||||
op(it, OperatorNames.OR, context.intrinsics.jsBitOr)
|
||||
op(it, OperatorNames.NOT, context.intrinsics.jsNot)
|
||||
@@ -99,12 +96,12 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
// TODO: use increment and decrement when it's possible
|
||||
op(type, OperatorNames.INC) {
|
||||
irCall(it, context.intrinsics.jsPlus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.int, 1))
|
||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, 1))
|
||||
}
|
||||
}
|
||||
op(type, OperatorNames.DEC) {
|
||||
irCall(it, context.intrinsics.jsMinus.symbol, dispatchReceiverAsFirstArgument = true).apply {
|
||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.int, 1))
|
||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,18 +110,18 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
||||
nameToIrTransformer.run {
|
||||
addWithPredicate(
|
||||
Name.special(Namer.KCALLABLE_GET_NAME),
|
||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { DescriptorUtils.isSubtypeOfClass(type, kCallable) } ?: false },
|
||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kCallableClass) } ?: false },
|
||||
{ call -> irCall(call, context.intrinsics.jsName.symbol, dispatchReceiverAsFirstArgument = true) })
|
||||
|
||||
addWithPredicate(
|
||||
Name.identifier(Namer.KPROPERTY_GET),
|
||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { DescriptorUtils.isSubtypeOfClass(type, kProperty) } ?: false },
|
||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false },
|
||||
{ call -> irCall(call, context.intrinsics.jsPropertyGet.symbol, dispatchReceiverAsFirstArgument = true)}
|
||||
)
|
||||
|
||||
addWithPredicate(
|
||||
Name.identifier(Namer.KPROPERTY_SET),
|
||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { DescriptorUtils.isSubtypeOfClass(type, kProperty) } ?: false},
|
||||
{ call -> call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false},
|
||||
{ call -> irCall(call, context.intrinsics.jsPropertySet.symbol, dispatchReceiverAsFirstArgument = true)}
|
||||
)
|
||||
}
|
||||
@@ -207,12 +204,11 @@ private fun IrCall.copyTypeAndValueArgumentsFrom(call: IrCall, dispatchReceiverA
|
||||
}
|
||||
}
|
||||
|
||||
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: KotlinType, name: Name, v: V) {
|
||||
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: IrType, name: Name, v: V) {
|
||||
put(SimpleMemberKey(type, name), v)
|
||||
}
|
||||
|
||||
// TODO issue: marked as unused, but used; rename works wrongly.
|
||||
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: KotlinType, name: String, v: V) {
|
||||
private fun <V> MutableMap<SimpleMemberKey, V>.op(type: IrType, name: String, v: V) {
|
||||
put(SimpleMemberKey(type, Name.identifier(name)), v)
|
||||
}
|
||||
|
||||
@@ -232,4 +228,23 @@ private fun <K> MutableMap<K, (IrCall) -> IrCall>.addWithPredicate(from: K, pred
|
||||
|
||||
private inline fun <T> select(crossinline predicate: () -> Boolean, crossinline ifTrue: () -> T, crossinline ifFalse: () -> T): T = if (predicate()) ifTrue() else ifFalse()
|
||||
|
||||
private data class SimpleMemberKey(val klass: KotlinType, val name: Name)
|
||||
private class SimpleMemberKey(val klass: IrType, val name: Name) {
|
||||
// TODO drop custom equals and hashCode when IrTypes will have right equals
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as SimpleMemberKey
|
||||
|
||||
if (name != other.name) return false
|
||||
if (klass.originalKotlinType != other.klass.originalKotlinType) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = klass.originalKotlinType?.hashCode() ?: 0
|
||||
result = 31 * result + name.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.utils.commonSupertype
|
||||
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
@@ -18,11 +20,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCatchImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrElseBranchImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.types.CommonSupertypes
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
|
||||
/**
|
||||
* Since JS does not support multiple catch blocks by default we should replace them with similar `when` statement, so
|
||||
@@ -49,9 +50,9 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
*/
|
||||
|
||||
class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
val litTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.bool, true)
|
||||
val unitType = context.irBuiltIns.unit
|
||||
val nothingType = context.irBuiltIns.nothing
|
||||
val litTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||
val unitType = context.irBuiltIns.unitType
|
||||
val nothingType = context.irBuiltIns.nothingType
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildren(object : IrElementTransformer<IrDeclaration?> {
|
||||
@@ -67,7 +68,7 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
||||
val commonType = mergeTypes(aTry.catches.map { it.catchParameter.type })
|
||||
|
||||
val pendingExceptionSymbol = JsSymbolBuilder.buildVar(data!!.descriptor, commonType, "\$pending\$", false)
|
||||
val pendingExceptionDeclaration = JsIrBuilder.buildVar(pendingExceptionSymbol)
|
||||
val pendingExceptionDeclaration = JsIrBuilder.buildVar(pendingExceptionSymbol, type = commonType)
|
||||
val pendingException = JsIrBuilder.buildGetValue(pendingExceptionSymbol)
|
||||
|
||||
val branches = mutableListOf<IrBranch>()
|
||||
@@ -75,24 +76,27 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
||||
for (catch in aTry.catches) {
|
||||
assert(!catch.catchParameter.isVar) { "caught exception parameter has to immutable" }
|
||||
val type = catch.catchParameter.type
|
||||
val typeSymbol = context.symbolTable.referenceClassifier(type.constructor.declarationDescriptor!!)
|
||||
val castedPendingException = buildImplicitCast(pendingException, type, typeSymbol)
|
||||
val typeSymbol = type.classifierOrNull
|
||||
val catchBody = catch.result.transform(object : IrElementTransformer<VariableDescriptor> {
|
||||
override fun visitGetValue(expression: IrGetValue, data: VariableDescriptor) =
|
||||
if (expression.descriptor == data) castedPendingException else expression
|
||||
if (typeSymbol != null && expression.descriptor == data)
|
||||
// TODO how is it good to generate implicit cast for each access?
|
||||
buildImplicitCast(pendingException, type, typeSymbol)
|
||||
else
|
||||
expression
|
||||
}, catch.parameter)
|
||||
|
||||
if (type.isDynamic()) {
|
||||
if (type is IrDynamicType) {
|
||||
branches += IrElseBranchImpl(catch.startOffset, catch.endOffset, litTrue, catchBody)
|
||||
break
|
||||
} else {
|
||||
val typeCheck = buildIsCheck(pendingException, type, typeSymbol)
|
||||
val typeCheck = buildIsCheck(pendingException, type, typeSymbol!!)
|
||||
branches += IrBranchImpl(catch.startOffset, catch.endOffset, typeCheck, catchBody)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!commonType.isDynamic()) {
|
||||
if (commonType !is IrDynamicType) {
|
||||
val throwStatement = JsIrBuilder.buildThrow(nothingType, pendingException)
|
||||
branches += IrElseBranchImpl(litTrue, JsIrBuilder.buildBlock(nothingType, listOf(throwStatement)))
|
||||
}
|
||||
@@ -106,14 +110,14 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
||||
return aTry.run { IrTryImpl(startOffset, endOffset, type, tryResult, listOf(newCatch), finallyExpression) }
|
||||
}
|
||||
|
||||
private fun buildIsCheck(value: IrExpression, toType: KotlinType, toTypeSymbol: IrClassifierSymbol) =
|
||||
JsIrBuilder.buildTypeOperator(context.irBuiltIns.bool, IrTypeOperator.INSTANCEOF, value, toType, toTypeSymbol)
|
||||
private fun buildIsCheck(value: IrExpression, toType: IrType, toTypeSymbol: IrClassifierSymbol) =
|
||||
JsIrBuilder.buildTypeOperator(context.irBuiltIns.booleanType, IrTypeOperator.INSTANCEOF, value, toType, toTypeSymbol)
|
||||
|
||||
private fun buildImplicitCast(value: IrExpression, toType: KotlinType, toTypeSymbol: IrClassifierSymbol) =
|
||||
private fun buildImplicitCast(value: IrExpression, toType: IrType, toTypeSymbol: IrClassifierSymbol) =
|
||||
JsIrBuilder.buildTypeOperator(toType, IrTypeOperator.IMPLICIT_CAST, value, toType, toTypeSymbol)
|
||||
|
||||
private fun mergeTypes(types: List<KotlinType>) = CommonSupertypes.commonSupertype(types).also {
|
||||
assert(it.isSubtypeOf(context.builtIns.throwable.defaultType) || it.isDynamic())
|
||||
private fun mergeTypes(types: List<IrType>) = types.commonSupertype().also {
|
||||
assert(it.isSubtypeOf(context.irBuiltIns.throwableType) || it is IrDynamicType)
|
||||
}
|
||||
|
||||
}, null)
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -72,8 +74,9 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
// val t = Object.create(Foo.prototype);
|
||||
// return Foo_init_$Init$(..., t)
|
||||
// }
|
||||
val newInitConstructor = createInitConstructor(declaration, constructorName)
|
||||
val newCreateConstructor = createCreateConstructor(declaration, newInitConstructor, constructorName)
|
||||
|
||||
val newInitConstructor = createInitConstructor(declaration, constructorName, irClass.defaultType)
|
||||
val newCreateConstructor = createCreateConstructor(declaration, newInitConstructor, constructorName, irClass.defaultType)
|
||||
|
||||
oldCtorToNewMap[declaration.symbol] =
|
||||
JsIrBackendContext.SecondaryCtorPair(newInitConstructor.symbol, newCreateConstructor.symbol)
|
||||
@@ -95,14 +98,16 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
override fun visitReturn(expression: IrReturn): IrExpression = IrReturnImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
expression.type,
|
||||
function,
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, thisSymbol)
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, thisSymbol.owner.type, thisSymbol)
|
||||
)
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression =
|
||||
if (expression.descriptor.name.isSpecial && expression.descriptor.name.asString() == Namer.THIS_SPECIAL_NAME) IrGetValueImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
expression.type,
|
||||
thisSymbol,
|
||||
expression.origin
|
||||
) else {
|
||||
@@ -110,28 +115,32 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInitConstructor(declaration: IrConstructor, name: String): IrSimpleFunction =
|
||||
private fun createInitConstructor(
|
||||
declaration: IrConstructor,
|
||||
name: String,
|
||||
type: IrType
|
||||
): IrSimpleFunction =
|
||||
JsSymbolBuilder.copyFunctionSymbol(declaration.symbol, "${name}_\$Init\$").let {
|
||||
|
||||
val thisSymbol =
|
||||
JsSymbolBuilder.buildValueParameter(it, declaration.valueParameters.size, declaration.returnType, "\$this")
|
||||
JsSymbolBuilder.buildValueParameter(it, declaration.valueParameters.size, type, "\$this")
|
||||
|
||||
it.initialize(
|
||||
dispatchParameterDescriptor = declaration.descriptor.dispatchReceiverParameter,
|
||||
typeParameters = declaration.descriptor.typeParameters,
|
||||
valueParameters = declaration.descriptor.valueParameters + thisSymbol.descriptor as ValueParameterDescriptor,
|
||||
type = declaration.descriptor.returnType,
|
||||
returnType = type,
|
||||
modality = declaration.descriptor.modality,
|
||||
visibility = declaration.descriptor.visibility
|
||||
)
|
||||
|
||||
val thisParam = JsIrBuilder.buildValueParameter(thisSymbol)
|
||||
val thisParam = JsIrBuilder.buildValueParameter(thisSymbol, type)
|
||||
|
||||
return IrFunctionImpl(
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
declaration.origin, it
|
||||
).apply {
|
||||
val retStmt = JsIrBuilder.buildReturn(it, JsIrBuilder.buildGetValue(thisSymbol))
|
||||
val retStmt = JsIrBuilder.buildReturn(it, JsIrBuilder.buildGetValue(thisSymbol), context)
|
||||
val statements = (declaration.body as IrStatementContainer).statements
|
||||
|
||||
valueParameters += (declaration.valueParameters + thisParam)
|
||||
@@ -145,13 +154,13 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
}
|
||||
|
||||
|
||||
private fun createCreateConstructor(ctorOrig: IrConstructor, ctorImpl: IrSimpleFunction, name: String): IrSimpleFunction =
|
||||
private fun createCreateConstructor(ctorOrig: IrConstructor, ctorImpl: IrSimpleFunction, name: String, type: IrType): IrSimpleFunction =
|
||||
JsSymbolBuilder.copyFunctionSymbol(ctorOrig.symbol, "${name}_\$Create\$").let {
|
||||
it.initialize(
|
||||
dispatchParameterDescriptor = ctorOrig.descriptor.dispatchReceiverParameter,
|
||||
typeParameters = ctorOrig.descriptor.typeParameters,
|
||||
valueParameters = ctorOrig.descriptor.valueParameters,
|
||||
type = ctorOrig.returnType,
|
||||
returnType = type,
|
||||
modality = ctorOrig.descriptor.modality,
|
||||
visibility = ctorOrig.visibility
|
||||
)
|
||||
@@ -165,14 +174,14 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
typeParameters += ctorOrig.typeParameters
|
||||
// parent = ctorOrig.parent
|
||||
|
||||
val returnType = ctorOrig.returnType
|
||||
val returnType = type
|
||||
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
||||
val irCreateCall = JsIrBuilder.buildCall(
|
||||
createFunctionIntrinsic.symbol,
|
||||
returnType,
|
||||
mapOf(createFunctionIntrinsic.typeParameters[0].descriptor to returnType)
|
||||
listOf(returnType)
|
||||
)
|
||||
val irDelegateCall = JsIrBuilder.buildCall(ctorImpl.symbol).also {
|
||||
val irDelegateCall = JsIrBuilder.buildCall(ctorImpl.symbol, type).also {
|
||||
for (i in 0 until valueParameters.size) {
|
||||
it.putValueArgument(i, JsIrBuilder.buildGetValue(valueParameters[i].symbol))
|
||||
}
|
||||
@@ -181,7 +190,7 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
|
||||
// typeParameters.mapIndexed { i, t -> ctorImpl.typeParameters[i].descriptor -> }
|
||||
}
|
||||
val irReturn = JsIrBuilder.buildReturn(it, irDelegateCall)
|
||||
val irReturn = JsIrBuilder.buildReturn(it, irDelegateCall, context)
|
||||
|
||||
|
||||
body = JsIrBuilder.buildBlockBody(listOf(irReturn))
|
||||
@@ -233,10 +242,11 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
IrGetValueImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
expression.type,
|
||||
IrValueParameterSymbolImpl(LazyClassReceiverParameterDescriptor(target.descriptor.containingDeclaration))
|
||||
)
|
||||
} else {
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, ownerFunc.valueParameters.last().symbol)
|
||||
IrGetValueImpl(expression.startOffset, expression.endOffset, expression.type, ownerFunc.valueParameters.last().symbol)
|
||||
}
|
||||
|
||||
newCall.putValueArgument(expression.valueArgumentsCount, readThis)
|
||||
@@ -247,7 +257,7 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
private fun redirectCall(
|
||||
call: IrFunctionAccessExpression,
|
||||
newTarget: IrSimpleFunctionSymbol
|
||||
) = IrCallImpl(call.startOffset, call.endOffset, newTarget).apply {
|
||||
) = IrCallImpl(call.startOffset, call.endOffset, call.type, newTarget).apply {
|
||||
|
||||
copyTypeArgumentsFrom(call)
|
||||
|
||||
|
||||
@@ -6,35 +6,34 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.isFunctionOrKFunctionType
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.backend.common.utils.*
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.symbols.JsSymbolBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isReified
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
|
||||
class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
private val unit = context.builtIns.unit
|
||||
private val unitValue = JsIrBuilder.buildGetObjectValue(unit.defaultType, context.symbolTable.referenceClass(unit))
|
||||
private val unit = context.irBuiltIns.unitType
|
||||
private val unitValue = JsIrBuilder.buildGetObjectValue(unit, unit.classifierOrFail as IrClassSymbol)
|
||||
|
||||
private val lit24 = JsIrBuilder.buildInt(context.builtIns.intType, 24)
|
||||
private val lit16 = JsIrBuilder.buildInt(context.builtIns.intType, 16)
|
||||
private val lit24 = JsIrBuilder.buildInt(context.irBuiltIns.intType, 24)
|
||||
private val lit16 = JsIrBuilder.buildInt(context.irBuiltIns.intType, 16)
|
||||
|
||||
private val byteMask = JsIrBuilder.buildInt(context.builtIns.intType, 0xFF)
|
||||
private val shortMask = JsIrBuilder.buildInt(context.builtIns.intType, 0xFFFF)
|
||||
private val byteMask = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFF)
|
||||
private val shortMask = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFFFF)
|
||||
|
||||
private val calculator = JsIrArithBuilder(context)
|
||||
|
||||
@@ -53,13 +52,13 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol
|
||||
private val toJSTypeIntrinsicSymbol = context.intrinsics.jsToJsType.symbol
|
||||
|
||||
private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "string")
|
||||
private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "boolean")
|
||||
private val functionMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "function")
|
||||
private val numberMarker = JsIrBuilder.buildString(context.irBuiltIns.string, "number")
|
||||
private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string")
|
||||
private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "boolean")
|
||||
private val functionMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "function")
|
||||
private val numberMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "number")
|
||||
|
||||
private val litTrue: IrExpression = JsIrBuilder.buildBoolean(context.irBuiltIns.bool, true)
|
||||
private val litNull: IrExpression = JsIrBuilder.buildNull(context.builtIns.nullableNothingType)
|
||||
private val litTrue: IrExpression = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||
private val litNull: IrExpression = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType)
|
||||
|
||||
private fun getInternalFunction(name: String) = context.symbolTable.referenceSimpleFunction(context.getInternalFunctions(name).single())
|
||||
|
||||
@@ -126,16 +125,21 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
}
|
||||
|
||||
// Note: native `instanceOf` is not used which is important because of null-behaviour
|
||||
private fun advancedCheckRequired(type: KotlinType) = type.isInterface() ||
|
||||
KotlinBuiltIns.isArray(type) ||
|
||||
KotlinBuiltIns.isPrimitiveArray(type) ||
|
||||
private fun advancedCheckRequired(type: IrType) = type.isInterface() ||
|
||||
type.isArray() ||
|
||||
type.isPrimitiveArray() ||
|
||||
isTypeOfCheckingType(type)
|
||||
|
||||
private fun isTypeOfCheckingType(type: KotlinType) =
|
||||
((type.isPrimitiveNumberType() || KotlinBuiltIns.isNumber(type)) && !type.isLong() && !type.isChar()) ||
|
||||
private fun isTypeOfCheckingType(type: IrType) =
|
||||
type.isByte() ||
|
||||
type.isShort() ||
|
||||
type.isInt() ||
|
||||
type.isFloat() ||
|
||||
type.isDouble() ||
|
||||
type.isNumber() ||
|
||||
type.isBoolean() ||
|
||||
type.isFunctionOrKFunctionType ||
|
||||
KotlinBuiltIns.isString(type)
|
||||
type.isFunctionOrKFunction() ||
|
||||
type.isString()
|
||||
|
||||
fun lowerInstanceOf(
|
||||
expression: IrTypeOperatorCall,
|
||||
@@ -146,7 +150,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
assert((expression.operator == IrTypeOperator.NOT_INSTANCEOF) == inverted)
|
||||
|
||||
val toType = expression.typeOperand
|
||||
val isCopyRequired = expression.argument.type.isNullable() && advancedCheckRequired(toType.makeNotNullable())
|
||||
val isCopyRequired = expression.argument.type.isNullable() && advancedCheckRequired(toType.makeNotNull())
|
||||
val newStatements = mutableListOf<IrStatement>()
|
||||
|
||||
val argument =
|
||||
@@ -167,12 +171,12 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
|
||||
private fun cacheValue(value: IrExpression, newStatements: MutableList<IrStatement>, cd: DeclarationDescriptor): IrExpression {
|
||||
val varSymbol = JsSymbolBuilder.buildTempVar(cd, value.type, mutable = false)
|
||||
newStatements += JsIrBuilder.buildVar(varSymbol, value)
|
||||
newStatements += JsIrBuilder.buildVar(varSymbol, value, value.type)
|
||||
return JsIrBuilder.buildGetValue(varSymbol)
|
||||
}
|
||||
|
||||
private fun generateTypeCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
val toNotNullable = toType.makeNotNullable()
|
||||
private fun generateTypeCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||
val toNotNullable = toType.makeNotNull()
|
||||
val instanceCheck = generateTypeCheckNonNull(argument, toNotNullable)
|
||||
val isFromNullable = argument.type.isNullable()
|
||||
val isToNullable = toType.isNullable()
|
||||
@@ -190,14 +194,14 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateTypeCheckNonNull(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
assert(!toType.isMarkedNullable)
|
||||
private fun generateTypeCheckNonNull(argument: IrExpression, toType: IrType): IrExpression {
|
||||
assert(!toType.isMarkedNullable())
|
||||
return when {
|
||||
KotlinBuiltIns.isAny(toType) -> generateIsObjectCheck(argument)
|
||||
toType.isAny() -> generateIsObjectCheck(argument)
|
||||
isTypeOfCheckingType(toType) -> generateTypeOfCheck(argument, toType)
|
||||
toType.isChar() -> generateCheckForChar(argument)
|
||||
KotlinBuiltIns.isArray(toType) -> generateGenericArrayCheck(argument)
|
||||
KotlinBuiltIns.isPrimitiveArray(toType) -> generatePrimitiveArrayTypeCheck(argument, toType)
|
||||
toType.isArray() -> generateGenericArrayCheck(argument)
|
||||
toType.isPrimitiveArray() -> generatePrimitiveArrayTypeCheck(argument, toType)
|
||||
toType.isTypeParameter() -> generateTypeCheckWithTypeParameter(argument, toType)
|
||||
toType.isInterface() -> generateInterfaceCheck(argument, toType)
|
||||
else -> generateNativeInstanceOf(argument, toType)
|
||||
@@ -208,12 +212,14 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
putValueArgument(0, argument)
|
||||
}
|
||||
|
||||
private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
val typeParameterDescriptor = toType.constructor.declarationDescriptor as TypeParameterDescriptor
|
||||
assert(!typeParameterDescriptor.isReified) { "reified parameters have to be lowered before" }
|
||||
private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: IrType): IrExpression {
|
||||
val typeParameter =
|
||||
(toType.classifierOrNull as? IrTypeParameterSymbol)?.owner ?: error("expected type parameter, but $toType")
|
||||
|
||||
return typeParameterDescriptor.upperBounds.fold(litTrue) { r, t ->
|
||||
val check = generateTypeCheckNonNull(argument, t.makeNotNullable())
|
||||
assert(!typeParameter.isReified) { "reified parameters have to be lowered before" }
|
||||
|
||||
return typeParameter.superTypes.fold(litTrue) { r, t ->
|
||||
val check = generateTypeCheckNonNull(argument, t.makeNotNull())
|
||||
calculator.and(r, check)
|
||||
}
|
||||
}
|
||||
@@ -221,11 +227,11 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
private fun generateCheckForChar(argument: IrExpression) =
|
||||
JsIrBuilder.buildCall(isCharSymbol).apply { dispatchReceiver = argument }
|
||||
|
||||
private fun generateTypeOfCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
private fun generateTypeOfCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||
val marker = when {
|
||||
toType.isFunctionOrKFunctionType -> functionMarker
|
||||
toType.isFunctionOrKFunction() -> functionMarker
|
||||
toType.isBoolean() -> booleanMarker
|
||||
KotlinBuiltIns.isString(toType) -> stringMarker
|
||||
toType.isString() -> stringMarker
|
||||
else -> numberMarker
|
||||
}
|
||||
|
||||
@@ -236,17 +242,17 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
}
|
||||
}
|
||||
|
||||
private fun wrapTypeReference(toType: KotlinType) =
|
||||
private fun wrapTypeReference(toType: IrType) =
|
||||
JsIrBuilder.buildCall(toJSTypeIntrinsicSymbol).apply { putTypeArgument(0, toType) }
|
||||
|
||||
private fun generateGenericArrayCheck(argument: IrExpression) =
|
||||
JsIrBuilder.buildCall(isArraySymbol).apply { putValueArgument(0, argument) }
|
||||
|
||||
private fun generatePrimitiveArrayTypeCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
private fun generatePrimitiveArrayTypeCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||
TODO("Implement Typed Array check")
|
||||
}
|
||||
|
||||
private fun generateInterfaceCheck(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
private fun generateInterfaceCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||
val irType = wrapTypeReference(toType)
|
||||
return JsIrBuilder.buildCall(isInterfaceSymbol).apply {
|
||||
putValueArgument(0, argument)
|
||||
@@ -254,7 +260,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateNativeInstanceOf(argument: IrExpression, toType: KotlinType): IrExpression {
|
||||
private fun generateNativeInstanceOf(argument: IrExpression, toType: IrType): IrExpression {
|
||||
val irType = wrapTypeReference(toType)
|
||||
return JsIrBuilder.buildCall(instanceOfIntrinsicSymbol).apply {
|
||||
putValueArgument(0, argument)
|
||||
@@ -264,12 +270,12 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
|
||||
private fun lowerCoercionToUnit(expression: IrTypeOperatorCall): IrExpression {
|
||||
assert(expression.operator === IrTypeOperator.IMPLICIT_COERCION_TO_UNIT)
|
||||
return expression.run { IrCompositeImpl(startOffset, endOffset, unit.defaultType, null, listOf(argument, unitValue)) }
|
||||
return expression.run { IrCompositeImpl(startOffset, endOffset, unit, null, listOf(argument, unitValue)) }
|
||||
}
|
||||
|
||||
private fun lowerIntegerCoercion(expression: IrTypeOperatorCall, containingDeclaration: DeclarationDescriptor): IrExpression {
|
||||
assert(expression.operator === IrTypeOperator.IMPLICIT_INTEGER_COERCION)
|
||||
assert(KotlinBuiltIns.isInt(expression.argument.type))
|
||||
assert(expression.argument.type.isInt())
|
||||
|
||||
val isNullable = expression.argument.type.isNullable()
|
||||
val toType = expression.typeOperand
|
||||
@@ -284,9 +290,9 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||
if (isNullable) cacheValue(expression.argument, newStatements, containingDeclaration) else expression.argument
|
||||
|
||||
val casted = when {
|
||||
KotlinBuiltIns.isByte(toType) -> maskOp(argument, byteMask, lit24)
|
||||
KotlinBuiltIns.isShort(toType) -> maskOp(argument, shortMask, lit16)
|
||||
KotlinBuiltIns.isLong(toType) -> TODO("Long coercion")
|
||||
toType.isByte() -> maskOp(argument, byteMask, lit24)
|
||||
toType.isShort() -> maskOp(argument, shortMask, lit16)
|
||||
toType.isLong() -> TODO("Long coercion")
|
||||
else -> error("Unreachable execution (coercion to non-Integer type")
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -34,7 +35,6 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
|
||||
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DeepCopyIrTreeWithDescriptors.kt
|
||||
@@ -479,7 +479,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
return IrCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = newDescriptor.returnType!!,
|
||||
type = newDescriptor.returnType?.toIrType()!!,
|
||||
descriptor = newDescriptor,
|
||||
typeArgumentsCount = expression.typeArgumentsCount,
|
||||
origin = expression.origin,
|
||||
@@ -517,7 +517,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: KotlinType) : KotlinType {
|
||||
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: IrType) : IrType {
|
||||
return when (operator) {
|
||||
IrTypeOperator.CAST,
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
@@ -526,7 +526,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> type
|
||||
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
||||
IrTypeOperator.INSTANCEOF,
|
||||
IrTypeOperator.NOT_INSTANCEOF -> context.builtIns.booleanType
|
||||
IrTypeOperator.NOT_INSTANCEOF -> context.irBuiltIns.booleanType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,7 +541,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
type = returnType,
|
||||
operator = expression.operator,
|
||||
typeOperand = typeOperand,
|
||||
argument = expression.argument.transform(this, null)
|
||||
argument = expression.argument.transform(this, null),
|
||||
typeOperandClassifier = typeOperand.classifierOrFail
|
||||
)
|
||||
}
|
||||
|
||||
@@ -610,6 +611,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun substituteType(oldType: IrType?): IrType? = substituteType(oldType?.toKotlinType())?.toIrType()
|
||||
|
||||
private fun substituteType(oldType: KotlinType?): KotlinType? {
|
||||
if (typeSubstitutor == null) return oldType
|
||||
if (oldType == null) return oldType
|
||||
@@ -699,7 +702,8 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
||||
endOffset = declaration.endOffset,
|
||||
origin = declaration.origin,
|
||||
descriptor = newDescriptor,
|
||||
initializer = declaration.initializer
|
||||
initializer = declaration.initializer,
|
||||
type = declaration.type
|
||||
)
|
||||
}
|
||||
|
||||
@@ -715,7 +719,8 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
origin = expression.origin,
|
||||
symbol = createValueSymbol(newDescriptor)
|
||||
symbol = createValueSymbol(newDescriptor),
|
||||
type = expression.type
|
||||
)
|
||||
}
|
||||
|
||||
@@ -732,7 +737,7 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
||||
return IrCallImpl(
|
||||
startOffset = oldExpression.startOffset,
|
||||
endOffset = oldExpression.endOffset,
|
||||
type = newDescriptor.returnType!!,
|
||||
type = oldExpression.type,
|
||||
symbol = createFunctionSymbol(newDescriptor),
|
||||
descriptor = newDescriptor,
|
||||
typeArgumentsCount = oldExpression.typeArgumentsCount,
|
||||
@@ -763,4 +768,3 @@ class DescriptorSubstitutorForExternalScope(val globalSubstituteMap: MutableMap<
|
||||
return oldExpression.shallowCopy(oldExpression.origin, createFunctionSymbol(newDescriptor), oldExpression.superQualifierSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,16 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.getDefault
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeProjection
|
||||
@@ -149,8 +151,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
||||
irBuilder.run {
|
||||
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
||||
val constructorCall = irCall(delegatingConstructorCall.symbol,
|
||||
constructorDescriptor.typeParameters.associate { it to delegatingConstructorCall.getTypeArgument(it)!! }).apply {
|
||||
val constructorCall = irCall(delegatingConstructorCall.symbol).apply {
|
||||
constructorDescriptor.typeParameters.forEach() { putTypeArgument(it.index, delegatingConstructorCall.getTypeArgument(it)!!) }
|
||||
constructorDescriptor.valueParameters.forEach { putValueArgument(it, delegatingConstructorCall.getValueArgument(it)) }
|
||||
}
|
||||
val oldThis = delegatingConstructorCall.descriptor.constructedClass.thisAsReceiverParameter
|
||||
@@ -159,12 +161,12 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
nameHint = delegatingConstructorCall.descriptor.fqNameSafe.toString() + ".this"
|
||||
)
|
||||
statements[0] = newThis
|
||||
substituteMap[oldThis] = irGet(newThis.symbol)
|
||||
statements.add(irReturn(irGet(newThis.symbol)))
|
||||
substituteMap[oldThis] = irGet(newThis)
|
||||
statements.add(irReturn(irGet(newThis)))
|
||||
}
|
||||
}
|
||||
|
||||
val returnType = copyFunctionDeclaration.descriptor.returnType!! // Substituted return type.
|
||||
val returnType = copyFunctionDeclaration.returnType // Substituted return type.
|
||||
val sourceFileName = context.originalModuleIndex.declarationToFile[caller.descriptor.original] ?: ""
|
||||
val inlineFunctionBody = IrReturnableBlockImpl( // Create new IR element to replace "call".
|
||||
startOffset = startOffset,
|
||||
@@ -248,7 +250,7 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
val substitutionContext = mutableMapOf<TypeConstructor, TypeProjection>()
|
||||
for (index in 0 until irCall.typeArgumentsCount) {
|
||||
val typeArgument = irCall.getTypeArgument(index) ?: continue
|
||||
substitutionContext[typeParameters[index].typeConstructor] = TypeProjectionImpl(typeArgument)
|
||||
substitutionContext[typeParameters[index].typeConstructor] = TypeProjectionImpl(typeArgument.toKotlinType())
|
||||
}
|
||||
return TypeSubstitutor.create(substitutionContext)
|
||||
}
|
||||
@@ -309,7 +311,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
}
|
||||
|
||||
val parametersWithDefaultToArgument = mutableListOf<ParameterToArgument>()
|
||||
functionDescriptor.valueParameters.forEach { parameterDescriptor -> // Iterate value parameter descriptors.
|
||||
irFunction.valueParameters.forEach { parameter -> // Iterate value parameter descriptors.
|
||||
val parameterDescriptor = parameter.descriptor as ValueParameterDescriptor
|
||||
val argument = valueArguments[parameterDescriptor.index] // Get appropriate argument from call site.
|
||||
when {
|
||||
argument != null -> { // Argument is good enough.
|
||||
@@ -331,8 +334,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
val emptyArray = IrVarargImpl(
|
||||
startOffset = irCall.startOffset,
|
||||
endOffset = irCall.endOffset,
|
||||
type = parameterDescriptor.type,
|
||||
varargElementType = parameterDescriptor.varargElementType!!
|
||||
type = parameter.type,
|
||||
varargElementType = parameter.varargElementType!!
|
||||
)
|
||||
parameterToArgument += ParameterToArgument(
|
||||
parameterDescriptor = parameterDescriptor,
|
||||
@@ -377,7 +380,8 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
val getVal = IrGetValueImpl( // Create new expression, representing access the new variable.
|
||||
startOffset = currentScope.irElement.startOffset,
|
||||
endOffset = currentScope.irElement.endOffset,
|
||||
symbol = createValueSymbol(newVariable.descriptor)
|
||||
type = newVariable.type,
|
||||
symbol = newVariable.symbol
|
||||
)
|
||||
substituteMap[parameterDescriptor] = getVal // Parameter will be replaced with the new variable.
|
||||
}
|
||||
|
||||
@@ -11,12 +11,13 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.addChildren
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
@@ -51,7 +52,11 @@ internal fun IrModuleFragment.replaceUnboundSymbols(context: JsIrBackendContext)
|
||||
// Generate missing external stubs:
|
||||
// TODO: ModuleGenerator::generateUnboundSymbolsAsDependencies(IRModuleFragment) is private function :/
|
||||
@Suppress("DEPRECATION")
|
||||
ExternalDependenciesGenerator(symbolTable = context.symbolTable, irBuiltIns = context.irBuiltIns).generateUnboundSymbolsAsDependencies(this)
|
||||
ExternalDependenciesGenerator(
|
||||
descriptor,
|
||||
symbolTable = context.symbolTable,
|
||||
irBuiltIns = context.irBuiltIns
|
||||
).generateUnboundSymbolsAsDependencies(this)
|
||||
|
||||
// Merge duplicated module and package declarations:
|
||||
this.acceptVoid(object : IrElementVisitorVoid {
|
||||
@@ -161,7 +166,7 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrGetValueImpl(startOffset, endOffset, symbol, origin)
|
||||
IrGetValueImpl(startOffset, endOffset, expression.type, symbol, origin)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,13 +175,13 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrSetVariableImpl(startOffset, endOffset, symbol, value, origin)
|
||||
IrSetVariableImpl(startOffset, endOffset, expression.type, symbol, value, origin)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
||||
val symbol = expression.symbol.replace(SymbolTable::referenceClass) ?:
|
||||
return super.visitGetObjectValue(expression)
|
||||
return super.visitGetObjectValue(expression)
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
@@ -186,7 +191,7 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
|
||||
val symbol = expression.symbol.replace(SymbolTable::referenceEnumEntry) ?:
|
||||
return super.visitGetEnumValue(expression)
|
||||
return super.visitGetEnumValue(expression)
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
@@ -200,17 +205,11 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrClassReferenceImpl(startOffset, endOffset, type, symbol, symbol.descriptor.defaultType)
|
||||
IrClassReferenceImpl(startOffset, endOffset, type, symbol, symbol.descriptor.toIrType())
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
declaration.superClasses.forEachIndexed { index, symbol ->
|
||||
val newSymbol = symbol.replace(SymbolTable::referenceClass)
|
||||
if (newSymbol != null) {
|
||||
declaration.superClasses[index] = newSymbol
|
||||
}
|
||||
}
|
||||
withLocal(declaration.thisReceiver?.symbol) {
|
||||
return super.visitClass(declaration)
|
||||
}
|
||||
@@ -227,7 +226,7 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, receiver, origin, superQualifierSymbol)
|
||||
IrGetFieldImpl(startOffset, endOffset, symbol, type, receiver, origin, superQualifierSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,11 +241,13 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value, origin, superQualifierSymbol)
|
||||
IrSetFieldImpl(startOffset, endOffset, symbol, receiver, value, type /*wrong*/, origin, superQualifierSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.replaceTypeArguments()
|
||||
|
||||
val symbol = expression.symbol.replace(SymbolTable::referenceFunction) ?: expression.symbol
|
||||
|
||||
val superQualifierSymbol = expression.superQualifierSymbol?.replaceOrSame(SymbolTable::referenceClass)
|
||||
@@ -257,17 +258,21 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid()
|
||||
return with(expression) {
|
||||
IrCallImpl(startOffset, endOffset, symbol, descriptor,
|
||||
getTypeArgumentsMap(),
|
||||
origin, superQualifierSymbol).also {
|
||||
IrCallImpl(startOffset, endOffset, type, symbol, descriptor,
|
||||
typeArgumentsCount,
|
||||
origin, superQualifierSymbol).also {
|
||||
|
||||
it.copyArgumentsFrom(this)
|
||||
it.copyTypeArgumentsFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrMemberAccessExpression.getTypeArgumentsMap() =
|
||||
descriptor.original.typeParameters.associate { it to getTypeArgumentOrDefault(it) }
|
||||
private fun IrMemberAccessExpression.replaceTypeArguments() {
|
||||
repeat(typeArgumentsCount) {
|
||||
putTypeArgument(it, getTypeArgument(it)/*?.toKotlinType()?.let { context.ir.translateErased(it) }*/)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrMemberAccessExpressionBase.copyArgumentsFrom(original: IrMemberAccessExpression) {
|
||||
dispatchReceiver = original.dispatchReceiver
|
||||
@@ -279,40 +284,48 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
|
||||
val symbol = expression.symbol.replace(SymbolTable::referenceConstructor) ?:
|
||||
return super.visitEnumConstructorCall(expression)
|
||||
return super.visitEnumConstructorCall(expression)
|
||||
|
||||
return with(expression) {
|
||||
IrEnumConstructorCallImpl(startOffset, endOffset, symbol, null).also {
|
||||
IrEnumConstructorCallImpl(startOffset, endOffset, expression.type, symbol, 0).also {
|
||||
it.copyArgumentsFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||
expression.replaceTypeArguments()
|
||||
|
||||
val symbol = expression.symbol.replace(SymbolTable::referenceConstructor) ?:
|
||||
return super.visitDelegatingConstructorCall(expression)
|
||||
return super.visitDelegatingConstructorCall(expression)
|
||||
|
||||
expression.transformChildrenVoid()
|
||||
return with(expression) {
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, symbol, descriptor, getTypeArgumentsMap()).also {
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, type, symbol, descriptor, typeArgumentsCount).also {
|
||||
it.copyArgumentsFrom(this)
|
||||
it.copyTypeArgumentsFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
expression.replaceTypeArguments()
|
||||
|
||||
val symbol = expression.symbol.replace(SymbolTable::referenceFunction) ?:
|
||||
return super.visitFunctionReference(expression)
|
||||
return super.visitFunctionReference(expression)
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrFunctionReferenceImpl(startOffset, endOffset, type, symbol, descriptor, getTypeArgumentsMap()).also {
|
||||
IrFunctionReferenceImpl(startOffset, endOffset, type, symbol, descriptor, 0).also {
|
||||
it.copyArgumentsFrom(this)
|
||||
it.copyTypeArgumentsFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression {
|
||||
expression.replaceTypeArguments()
|
||||
|
||||
val field = expression.field?.replaceOrSame(SymbolTable::referenceField)
|
||||
val getter = expression.getter?.replace(SymbolTable::referenceFunction) ?: expression.getter
|
||||
val setter = expression.setter?.replace(SymbolTable::referenceFunction) ?: expression.setter
|
||||
@@ -323,13 +336,14 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrPropertyReferenceImpl(startOffset, endOffset, type, descriptor,
|
||||
field,
|
||||
getter,
|
||||
setter,
|
||||
getTypeArgumentsMap(), origin).also {
|
||||
IrPropertyReferenceImpl(startOffset, endOffset, type, descriptor, 0,
|
||||
field,
|
||||
getter,
|
||||
setter,
|
||||
origin).also {
|
||||
|
||||
it.copyArgumentsFrom(this)
|
||||
it.copyTypeArgumentsFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,7 +360,7 @@ private class IrUnboundSymbolReplacer(
|
||||
expression.transformChildrenVoid(this)
|
||||
return with(expression) {
|
||||
IrLocalDelegatedPropertyReferenceImpl(startOffset, endOffset, type, descriptor,
|
||||
delegate, getter, setter, origin).also {
|
||||
delegate, getter, setter, origin).also {
|
||||
|
||||
it.copyArgumentsFrom(this)
|
||||
}
|
||||
@@ -406,12 +420,24 @@ private class IrUnboundSymbolReplacer(
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
|
||||
val classSymbol = expression.classSymbol.replace(SymbolTable::referenceClass) ?:
|
||||
return super.visitInstanceInitializerCall(expression)
|
||||
return super.visitInstanceInitializerCall(expression)
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
return with(expression) {
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, classSymbol)
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, classSymbol, type)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
return with(expression) {
|
||||
val newTypeOperand = typeOperand /*context.ir.translateErased(typeOperand.toKotlinType())*/
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, newTypeOperand).also {
|
||||
it.argument = argument
|
||||
it.typeOperandClassifier = newTypeOperand.classifierOrFail
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.inline
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
@@ -19,21 +20,6 @@ fun IrSimpleFunction.setOverrides(symbolTable: SymbolTable) {
|
||||
this.descriptor.overriddenDescriptors.mapTo(this.overriddenSymbols) {
|
||||
symbolTable.referenceSimpleFunction(it.original)
|
||||
}
|
||||
|
||||
this.typeParameters.forEach { it.setSupers(symbolTable) }
|
||||
}
|
||||
|
||||
fun IrTypeParameter.setSupers(symbolTable: SymbolTable) {
|
||||
assert(this.superClassifiers.isEmpty())
|
||||
this.descriptor.upperBounds.mapNotNullTo(this.superClassifiers) {
|
||||
it.constructor.declarationDescriptor?.let {
|
||||
if (it is TypeParameterDescriptor) {
|
||||
IrTypeParameterSymbolImpl(it) // Workaround for deserialized inline functions
|
||||
} else {
|
||||
symbolTable.referenceClassifier(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun IrDeclarationContainer.addChildren(declarations: List<IrDeclaration>) {
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.getTypeArgumentOrDefault
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -43,6 +45,10 @@ fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTabl
|
||||
}
|
||||
}
|
||||
|
||||
fun IrType.referenceAllClassifiers() {
|
||||
this.toKotlinType().referenceAllClassifiers()
|
||||
}
|
||||
|
||||
val visitor = object : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
@@ -125,4 +131,4 @@ fun IrModuleFragment.referenceAllTypeExternalClassifiers(symbolTable: SymbolTabl
|
||||
it.acceptVoid(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,18 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.symbols.JsSymbolBuilder
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturnableBlock
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
|
||||
/**
|
||||
* Replaces returnable blocks and `return`'s with loops and `break`'s correspondingly.
|
||||
@@ -93,7 +97,7 @@ private class ReturnableBlockTransformer(
|
||||
return super.visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
private val constFalse = JsIrBuilder.buildBoolean(context.builtIns.booleanType, false)
|
||||
private val constFalse = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false)
|
||||
|
||||
override fun visitContainerExpression(expression: IrContainerExpression, data: ReturnableBlockLoweringContext): IrExpression {
|
||||
if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression, data)
|
||||
@@ -111,7 +115,7 @@ private class ReturnableBlockTransformer(
|
||||
IrDoWhileLoopImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.builtIns.unitType,
|
||||
context.irBuiltIns.unitType,
|
||||
expression.origin
|
||||
).apply {
|
||||
label = "l\$ret\$${data.labelCnt++}"
|
||||
@@ -127,10 +131,10 @@ private class ReturnableBlockTransformer(
|
||||
IrCompositeImpl(
|
||||
returnExpression.startOffset,
|
||||
returnExpression.endOffset,
|
||||
context.builtIns.unitType
|
||||
context.irBuiltIns.unitType
|
||||
).apply {
|
||||
statements += JsIrBuilder.buildSetVariable(variable, returnExpression.value)
|
||||
statements += JsIrBuilder.buildBreak(context.builtIns.unitType, loop)
|
||||
statements += JsIrBuilder.buildSetVariable(variable, returnExpression.value, context.irBuiltIns.unitType)
|
||||
statements += JsIrBuilder.buildBreak(context.irBuiltIns.unitType, loop)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +142,7 @@ private class ReturnableBlockTransformer(
|
||||
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
|
||||
s.transformChildren(this, data)
|
||||
if (!hasReturned) s.value else {
|
||||
JsIrBuilder.buildSetVariable(variable, s.value)
|
||||
JsIrBuilder.buildSetVariable(variable, s.value, context.irBuiltIns.unitType)
|
||||
}
|
||||
} else {
|
||||
s.transform(this, data)
|
||||
@@ -159,7 +163,7 @@ private class ReturnableBlockTransformer(
|
||||
loop.body = IrBlockImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
context.builtIns.unitType,
|
||||
context.irBuiltIns.unitType,
|
||||
expression.origin,
|
||||
newStatements
|
||||
)
|
||||
@@ -170,7 +174,7 @@ private class ReturnableBlockTransformer(
|
||||
expression.type,
|
||||
expression.origin
|
||||
).apply {
|
||||
statements += JsIrBuilder.buildVar(variable)
|
||||
statements += JsIrBuilder.buildVar(variable, type = expression.type)
|
||||
statements += loop
|
||||
statements += JsIrBuilder.buildGetValue(variable)
|
||||
}
|
||||
|
||||
@@ -18,12 +18,13 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
object JsSymbolBuilder {
|
||||
fun buildValueParameter(containingSymbol: IrSimpleFunctionSymbol, index: Int, type: KotlinType, name: String? = null) =
|
||||
IrValueParameterSymbolImpl(createValueParameter(containingSymbol.descriptor, index, name ?: "param$index", type))
|
||||
fun buildValueParameter(containingSymbol: IrSimpleFunctionSymbol, index: Int, type: IrType, name: String? = null) =
|
||||
IrValueParameterSymbolImpl(createValueParameter(containingSymbol.descriptor, index, name ?: "param$index", type.toKotlinType()))
|
||||
|
||||
fun buildSimpleFunction(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
@@ -53,7 +54,7 @@ object JsSymbolBuilder {
|
||||
|
||||
fun buildVar(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
type: KotlinType,
|
||||
type: IrType,
|
||||
name: String,
|
||||
mutable: Boolean = false
|
||||
) = IrVariableSymbolImpl(
|
||||
@@ -61,42 +62,42 @@ object JsSymbolBuilder {
|
||||
containingDeclaration,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(name),
|
||||
type,
|
||||
type.toKotlinType(),
|
||||
mutable,
|
||||
false,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
fun buildTempVar(containingSymbol: IrSymbol, type: KotlinType, name: String? = null, mutable: Boolean = false) =
|
||||
fun buildTempVar(containingSymbol: IrSymbol, type: IrType, name: String? = null, mutable: Boolean = false) =
|
||||
buildTempVar(containingSymbol.descriptor, type, name, mutable)
|
||||
|
||||
fun buildTempVar(containingDeclaration: DeclarationDescriptor, type: KotlinType, name: String? = null, mutable: Boolean = false) =
|
||||
fun buildTempVar(containingDeclaration: DeclarationDescriptor, type: IrType, name: String? = null, mutable: Boolean = false) =
|
||||
IrVariableSymbolImpl(
|
||||
IrTemporaryVariableDescriptorImpl(
|
||||
containingDeclaration,
|
||||
Name.identifier(name ?: "tmp"),
|
||||
type, mutable
|
||||
type.toKotlinType(), mutable
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun IrSimpleFunctionSymbol.initialize(
|
||||
receiverParameterType: KotlinType? = null,
|
||||
receiverParameterType: IrType? = null,
|
||||
dispatchParameterDescriptor: ReceiverParameterDescriptor? = null,
|
||||
typeParameters: List<TypeParameterDescriptor> = emptyList(),
|
||||
valueParameters: List<ValueParameterDescriptor> = emptyList(),
|
||||
type: KotlinType? = null,
|
||||
returnType: IrType? = null,
|
||||
modality: Modality = Modality.FINAL,
|
||||
visibility: Visibility = Visibilities.LOCAL
|
||||
) = this.apply {
|
||||
(descriptor as FunctionDescriptorImpl).initialize(
|
||||
receiverParameterType,
|
||||
receiverParameterType?.toKotlinType(),
|
||||
dispatchParameterDescriptor,
|
||||
typeParameters,
|
||||
valueParameters,
|
||||
type,
|
||||
returnType?.toKotlinType(),
|
||||
modality,
|
||||
visibility
|
||||
)
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.backend.common.utils.isFunctionTypeOrSubtype
|
||||
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.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsExpression, JsGenerationContext> {
|
||||
@@ -158,7 +158,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
val arguments = translateCallArguments(expression, context)
|
||||
|
||||
if (dispatchReceiver != null &&
|
||||
dispatchReceiver.type.isFunctionTypeOrSubtype && symbol.owner.name == OperatorNameConventions.INVOKE
|
||||
dispatchReceiver.type.isFunctionTypeOrSubtype() && symbol.owner.name == OperatorNameConventions.INVOKE
|
||||
) {
|
||||
return JsInvocation(jsDispatchReceiver!!, arguments)
|
||||
}
|
||||
|
||||
@@ -11,12 +11,14 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
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.isAny
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.isAny
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.ir.util.isReal
|
||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
@@ -26,8 +28,8 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
|
||||
private val className = context.getNameForSymbol(irClass.symbol)
|
||||
private val classNameRef = className.makeRef()
|
||||
private val baseClass = irClass.superClasses.firstOrNull { !it.owner.isInterface }
|
||||
private val baseClassName = baseClass?.let { context.getNameForSymbol(it) }
|
||||
private val baseClass = irClass.superTypes.firstOrNull { !it.classifierOrFail.isInterface }
|
||||
private val baseClassName = baseClass?.let { context.getNameForSymbol(it.classifierOrFail) }
|
||||
private val classPrototypeRef = prototypeOf(classNameRef)
|
||||
private val classBlock = JsGlobalBlock()
|
||||
private val classModel = JsClassModel(className, baseClassName)
|
||||
@@ -130,7 +132,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
}
|
||||
|
||||
private fun generateInheritanceCode(): List<JsStatement> {
|
||||
if (baseClass == null || baseClass.isAny) {
|
||||
if (baseClass == null || baseClass.isAny()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
@@ -158,7 +160,13 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
|
||||
private fun generateSuperClasses(): JsPropertyInitializer = JsPropertyInitializer(
|
||||
JsNameRef(Namer.METADATA_INTERFACES),
|
||||
JsArrayLiteral(irClass.superClasses.filter { it.owner.isInterface }.map { JsNameRef(context.getNameForSymbol(it.owner.symbol)) })
|
||||
JsArrayLiteral(
|
||||
irClass.superTypes.mapNotNull {
|
||||
val symbol = it.classifierOrFail
|
||||
if (symbol.isInterface) JsNameRef(context.getNameForSymbol(symbol)) else null
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
private val IrClassifierSymbol.isInterface get() = (owner as? IrClass)?.isInterface == true
|
||||
@@ -5,14 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
|
||||
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
|
||||
@@ -69,7 +68,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
||||
|
||||
add(intrinsics.jsObjectCreate) { call, context ->
|
||||
val classToCreate = call.getTypeArgument(0)!!
|
||||
val className = context.getNameForSymbol(IrClassSymbolImpl(classToCreate.constructor.declarationDescriptor as ClassDescriptor))
|
||||
val className = context.getNameForSymbol(classToCreate.classifierOrFail)
|
||||
val prototype = prototypeOf(className.makeRef())
|
||||
JsInvocation(Namer.JS_OBJECT_CREATE_FUNCTION, prototype)
|
||||
}
|
||||
@@ -86,8 +85,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
||||
}
|
||||
|
||||
add(intrinsics.jsToJsType) { call, context ->
|
||||
val typeParameter = call.getTypeArgument(0)!!
|
||||
val typeName = context.getNameForSymbol(IrClassSymbolImpl(typeParameter.constructor.declarationDescriptor as ClassDescriptor))
|
||||
val typeName = context.getNameForSymbol(call.getTypeArgument(0)!!.classifierOrFail)
|
||||
typeName.makeRef()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm
|
||||
@@ -46,7 +35,7 @@ class JvmBackendContext(
|
||||
) : CommonBackendContext {
|
||||
override val builtIns = state.module.builtIns
|
||||
override val descriptorsFactory: JvmDescriptorsFactory = JvmDescriptorsFactory(psiSourceManager, builtIns)
|
||||
override val sharedVariablesManager = JvmSharedVariablesManager(builtIns)
|
||||
override val sharedVariablesManager = JvmSharedVariablesManager(builtIns, irBuiltIns)
|
||||
|
||||
override val reflectionTypes: ReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
ReflectionTypes(state.module, FqName("kotlin.reflect.jvm.internal"))
|
||||
@@ -73,8 +62,8 @@ class JvmBackendContext(
|
||||
context.getInternalFunctions("ThrowTypeCastException").single()
|
||||
)
|
||||
|
||||
override val ThrowUninitializedPropertyAccessException
|
||||
get () = symbolTable.referenceSimpleFunction(
|
||||
override val ThrowUninitializedPropertyAccessException =
|
||||
symbolTable.referenceSimpleFunction(
|
||||
context.getInternalFunctions("ThrowUninitializedPropertyAccessException").single()
|
||||
)
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm
|
||||
@@ -44,7 +33,11 @@ object JvmBackendFacade {
|
||||
state, psi2irContext.sourceManager, psi2irContext.irBuiltIns, irModuleFragment, psi2irContext.symbolTable
|
||||
)
|
||||
//TODO
|
||||
ExternalDependenciesGenerator(psi2irContext.symbolTable, psi2irContext.irBuiltIns).generateUnboundSymbolsAsDependencies(irModuleFragment)
|
||||
ExternalDependenciesGenerator(
|
||||
irModuleFragment.descriptor,
|
||||
psi2irContext.symbolTable,
|
||||
psi2irContext.irBuiltIns
|
||||
).generateUnboundSymbolsAsDependencies(irModuleFragment)
|
||||
|
||||
val jvmBackend = JvmBackend(jvmBackendContext)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -23,9 +23,13 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeAlias
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
@@ -176,7 +180,7 @@ class ExpressionCodegen(
|
||||
//coerceNotToUnit(r.type, Type.VOID_TYPE)
|
||||
exp.accept(this, data)
|
||||
}
|
||||
return coerceNotToUnit(result.type, expression.type)
|
||||
return coerceNotToUnit(result.type, expression.type.toKotlinType())
|
||||
}
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: BlockInfo): StackValue {
|
||||
@@ -212,7 +216,7 @@ class ExpressionCodegen(
|
||||
if (args.size == 1) {
|
||||
val sizeExpression = expression.getValueArgument(0)!!
|
||||
gen(sizeExpression, Type.INT_TYPE, data)
|
||||
newArrayInstruction(expression.type)
|
||||
newArrayInstruction(expression.type.toKotlinType())
|
||||
return expression.onStack
|
||||
}
|
||||
|
||||
@@ -298,6 +302,8 @@ class ExpressionCodegen(
|
||||
mv.athrow()
|
||||
} else if (expression.descriptor !is ConstructorDescriptor) {
|
||||
return returnType?.run { coerceNotToUnit(callable.returnType, this) } ?: onStack(callable.returnType)
|
||||
} else {
|
||||
return none()
|
||||
}
|
||||
|
||||
return expression.onStack
|
||||
@@ -440,7 +446,7 @@ class ExpressionCodegen(
|
||||
val hasSpread = arguments.firstIsInstanceOrNull<IrSpreadElement>() != null
|
||||
|
||||
if (hasSpread) {
|
||||
val arrayOfReferences = KotlinBuiltIns.isArray(outType)
|
||||
val arrayOfReferences = KotlinBuiltIns.isArray(outType.toKotlinType()!!)
|
||||
if (size == 1) {
|
||||
// Arrays.copyOf(receiverValue, newLength)
|
||||
val argument = (arguments[0] as IrSpreadElement).expression
|
||||
@@ -488,7 +494,7 @@ class ExpressionCodegen(
|
||||
if (arrayOfReferences) {
|
||||
mv.dup()
|
||||
mv.invokevirtual(owner, "size", "()I", false)
|
||||
newArrayInstruction(outType)
|
||||
newArrayInstruction(outType.toKotlinType())
|
||||
mv.invokevirtual(owner, "toArray", toArrayDescriptor, false)
|
||||
mv.checkcast(type)
|
||||
} else {
|
||||
@@ -497,8 +503,8 @@ class ExpressionCodegen(
|
||||
}
|
||||
} else {
|
||||
mv.iconst(size)
|
||||
newArrayInstruction(expression.type)
|
||||
val elementKotlinType = outType.constructor.builtIns.getArrayElementType(outType)
|
||||
newArrayInstruction(expression.type.toKotlinType())
|
||||
val elementKotlinType = classCodegen.context.builtIns.getArrayElementType(outType.toKotlinType()!!)
|
||||
for ((i, element) in expression.elements.withIndex()) {
|
||||
mv.dup()
|
||||
StackValue.constant(i, Type.INT_TYPE).put(Type.INT_TYPE, mv)
|
||||
@@ -507,7 +513,7 @@ class ExpressionCodegen(
|
||||
.arrayElement(
|
||||
elementType,
|
||||
elementKotlinType,
|
||||
StackValue.onStack(elementType, outType),
|
||||
StackValue.onStack(elementType, outType.toKotlinType()),
|
||||
StackValue.onStack(Type.INT_TYPE)
|
||||
)
|
||||
.store(rightSide, mv)
|
||||
@@ -547,7 +553,7 @@ class ExpressionCodegen(
|
||||
|
||||
|
||||
override fun visitWhen(expression: IrWhen, data: BlockInfo): StackValue =
|
||||
genIfWithBranches(expression.branches[0], data, expression.type, expression.branches.drop(1))
|
||||
genIfWithBranches(expression.branches[0], data, expression.type.toKotlinType(), expression.branches.drop(1))
|
||||
|
||||
|
||||
private fun genIfWithBranches(branch: IrBranch, data: BlockInfo, type: KotlinType, otherBranches: List<IrBranch>): StackValue {
|
||||
@@ -582,7 +588,7 @@ class ExpressionCodegen(
|
||||
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: BlockInfo): StackValue {
|
||||
val asmType = expression.typeOperand.asmType
|
||||
val asmType = expression.typeOperand.toKotlinType().asmType
|
||||
when (expression.operator) {
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> {
|
||||
val result = expression.argument.accept(this, data)
|
||||
@@ -601,14 +607,14 @@ class ExpressionCodegen(
|
||||
StackValue.putUnitInstance(mv)
|
||||
}
|
||||
val boxedType = boxType(asmType)
|
||||
generateAsCast(mv, expression.typeOperand, boxedType, expression.operator == IrTypeOperator.SAFE_CAST)
|
||||
generateAsCast(mv, expression.typeOperand.toKotlinType(), boxedType, expression.operator == IrTypeOperator.SAFE_CAST)
|
||||
return onStack(boxedType)
|
||||
}
|
||||
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> {
|
||||
gen(expression.argument, OBJECT_TYPE, data)
|
||||
val type = boxType(asmType)
|
||||
generateIsCheck(mv, expression.typeOperand, type)
|
||||
generateIsCheck(mv, expression.typeOperand.toKotlinType(), type)
|
||||
if (IrTypeOperator.NOT_INSTANCEOF == expression.operator) {
|
||||
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(Type.BOOLEAN_TYPE, mv)
|
||||
}
|
||||
@@ -627,7 +633,7 @@ class ExpressionCodegen(
|
||||
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> {
|
||||
gen(expression.argument, Type.INT_TYPE, data)
|
||||
StackValue.coerce(Type.INT_TYPE, typeMapper.mapType(expression.type), mv)
|
||||
StackValue.coerce(Type.INT_TYPE, typeMapper.mapType(expression.type.toKotlinType()), mv)
|
||||
}
|
||||
}
|
||||
return expression.onStack
|
||||
@@ -937,7 +943,7 @@ class ExpressionCodegen(
|
||||
assert(classReference is IrGetClass)
|
||||
JavaClassProperty.generateImpl(mv, gen((classReference as IrGetClass).argument, data))
|
||||
} else {
|
||||
val type = classReference.classType
|
||||
val type = classReference.classType.toKotlinType()
|
||||
if (TypeUtils.isTypeParameter(type)) {
|
||||
assert(TypeUtils.isReifiedTypeParameter(type)) { "Non-reified type parameter under ::class should be rejected by type checker: " + type }
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS, mv, this)
|
||||
@@ -962,7 +968,7 @@ class ExpressionCodegen(
|
||||
}
|
||||
|
||||
val IrExpression.asmType: Type
|
||||
get() = typeMapper.mapType(this.type)
|
||||
get() = typeMapper.mapType(this.type.toKotlinType())
|
||||
|
||||
val IrExpression.onStack: StackValue
|
||||
get() = StackValue.onStack(this.asmType)
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.codegen
|
||||
@@ -25,6 +14,7 @@ import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
@@ -155,7 +145,7 @@ private fun createFrameMapWithReceivers(
|
||||
}
|
||||
|
||||
for (parameter in irFunction.valueParameters) {
|
||||
frameMap.enter(parameter, state.typeMapper.mapType(parameter.type))
|
||||
frameMap.enter(parameter, state.typeMapper.mapType(parameter.type.toKotlinType()))
|
||||
}
|
||||
|
||||
return frameMap
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.descriptors
|
||||
@@ -31,6 +20,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
@@ -74,7 +64,7 @@ class JvmDescriptorsFactory(
|
||||
|
||||
IrFieldSymbolImpl(
|
||||
JvmPropertyDescriptorImpl.createFinalField(
|
||||
Name.identifier("this$0"), outerClass.defaultType, innerClass.descriptor,
|
||||
Name.identifier("this$0"), outerClass.defaultType.toKotlinType(), innerClass.descriptor,
|
||||
Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.descriptors
|
||||
@@ -29,17 +18,22 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesManager {
|
||||
class JvmSharedVariablesManager(
|
||||
val builtIns: KotlinBuiltIns,
|
||||
val irBuiltIns: IrBuiltIns
|
||||
) : SharedVariablesManager {
|
||||
private val kotlinJvmInternalPackage = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.jvm.internal"))
|
||||
private val refNamespaceClass =
|
||||
KnownClassDescriptor.createClass(Name.identifier("Ref"), kotlinJvmInternalPackage, listOf(builtIns.anyType))
|
||||
@@ -148,11 +142,12 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM
|
||||
|
||||
val refConstructorCall = IrCallImpl(
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset,
|
||||
refConstructor, refConstructorTypeArguments
|
||||
refConstructor.constructedClass.defaultType.toIrType()!!,
|
||||
refConstructor, refConstructorTypeArguments?.size ?: 0
|
||||
)
|
||||
return IrVariableImpl(
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin,
|
||||
sharedVariableDescriptor, refConstructorCall
|
||||
sharedVariableDescriptor, sharedVariableDescriptor.type.toIrType()!!, refConstructorCall
|
||||
)
|
||||
}
|
||||
|
||||
@@ -172,11 +167,12 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM
|
||||
initializer.startOffset, initializer.endOffset,
|
||||
elementPropertyDescriptor,
|
||||
IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDeclaration.symbol),
|
||||
initializer
|
||||
initializer,
|
||||
originalDeclaration.type
|
||||
)
|
||||
|
||||
return IrCompositeImpl(
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset, builtIns.unitType, null,
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset, irBuiltIns.unitType, null,
|
||||
listOf(sharedVariableDeclaration, sharedVariableInitialization)
|
||||
)
|
||||
}
|
||||
@@ -196,6 +192,7 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM
|
||||
originalGet.endOffset,
|
||||
sharedVariableSymbol
|
||||
),
|
||||
originalGet.type,
|
||||
originalGet.origin
|
||||
)
|
||||
|
||||
@@ -209,6 +206,7 @@ class JvmSharedVariablesManager(val builtIns: KotlinBuiltIns) : SharedVariablesM
|
||||
sharedVariableSymbol
|
||||
),
|
||||
originalSet.value,
|
||||
originalSet.type,
|
||||
originalSet.origin
|
||||
)
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.intrinsics
|
||||
@@ -24,6 +13,7 @@ import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
@@ -42,8 +32,9 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||
val receiverAndArgs = expression.receiverAndArgs().apply {
|
||||
assert(size == 2) { "Equals expects 2 arguments, but ${joinToString()}" }
|
||||
}
|
||||
var leftType = context.state.typeMapper.mapType(receiverAndArgs.first().type)
|
||||
var rightType = context.state.typeMapper.mapType(receiverAndArgs.last().type)
|
||||
|
||||
var leftType = context.state.typeMapper.mapType(receiverAndArgs.first().type.toKotlinType())
|
||||
var rightType = context.state.typeMapper.mapType(receiverAndArgs.last().type.toKotlinType())
|
||||
|
||||
if (isPrimitive(leftType) != isPrimitive(rightType)) {
|
||||
leftType = boxType(leftType)
|
||||
@@ -90,10 +81,10 @@ class Ieee754Equals(val operandType: Type) : IntrinsicMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
val arg0Type = expression.getValueArgument(0)!!.type
|
||||
val arg0Type = expression.getValueArgument(0)!!.type.toKotlinType()
|
||||
if (!arg0Type.isPrimitiveNumberOrNullableType()) throw AssertionError("Should be primitive or nullable primitive type: $arg0Type")
|
||||
|
||||
val arg1Type = expression.getValueArgument(1)!!.type
|
||||
val arg1Type = expression.getValueArgument(1)!!.type.toKotlinType()
|
||||
if (!arg1Type.isPrimitiveNumberOrNullableType()) throw AssertionError("Should be primitive or nullable primitive type: $arg1Type")
|
||||
|
||||
val arg0isNullable = arg0Type.isMarkedNullable
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.intrinsics
|
||||
@@ -21,6 +10,7 @@ import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
@@ -41,11 +31,11 @@ abstract class IntrinsicMethod {
|
||||
|
||||
companion object {
|
||||
fun calcReceiverType(call: IrMemberAccessExpression, context: JvmBackendContext): Type {
|
||||
return context.state.typeMapper.mapType(call.dispatchReceiver?.type ?: call.extensionReceiver!!.type)
|
||||
return context.state.typeMapper.mapType((call.dispatchReceiver?.type ?: call.extensionReceiver!!.type).toKotlinType())
|
||||
}
|
||||
|
||||
fun expressionType(expression: IrExpression, context: JvmBackendContext): Type {
|
||||
return context.state.typeMapper.mapType(expression.type)
|
||||
return context.state.typeMapper.mapType(expression.type.toKotlinType())
|
||||
}
|
||||
|
||||
fun JvmMethodSignature.newReturnType(type: Type): JvmMethodSignature {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,9 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
@@ -25,7 +28,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.*
|
||||
|
||||
private class IrEmptyVarargExpression(
|
||||
override val type: KotlinType,
|
||||
override val type: IrType,
|
||||
override val startOffset: Int,
|
||||
override val endOffset: Int
|
||||
) : IrExpression {
|
||||
@@ -86,13 +89,13 @@ open class IrIntrinsicFunction(
|
||||
val args = listOfNotNull(expression.dispatchReceiver, expression.extensionReceiver) +
|
||||
expression.descriptor.valueParameters.mapIndexed { i, descriptor ->
|
||||
expression.getValueArgument(i) ?: if (descriptor.isVararg)
|
||||
IrEmptyVarargExpression(descriptor.type, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||
IrEmptyVarargExpression(descriptor.type.toIrType()!!, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||
else error("Unknown parameter: $descriptor in $expression")
|
||||
}
|
||||
|
||||
args.forEachIndexed { i, irExpression ->
|
||||
if (irExpression is IrEmptyVarargExpression) {
|
||||
val parameterType = codegen.typeMapper.mapType(irExpression.type)
|
||||
val parameterType = codegen.typeMapper.mapType(irExpression.type.toKotlinType())
|
||||
StackValue.operation(parameterType) {
|
||||
it.aconst(0)
|
||||
it.newarray(AsmUtil.correctElementType(parameterType))
|
||||
@@ -122,13 +125,11 @@ open class IrIntrinsicFunction(
|
||||
}
|
||||
}
|
||||
|
||||
fun createWithResult(
|
||||
expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext,
|
||||
argsTypes: List<Type> = expression.argTypes(context),
|
||||
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Type
|
||||
): IrIntrinsicFunction {
|
||||
fun createWithResult(expression: IrMemberAccessExpression,
|
||||
signature: JvmMethodSignature,
|
||||
context: JvmBackendContext,
|
||||
argsTypes: List<Type> = expression.argTypes(context),
|
||||
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Type): IrIntrinsicFunction {
|
||||
return object : IrIntrinsicFunction(expression, signature, context, argsTypes) {
|
||||
|
||||
override fun genInvokeInstructionWithResult(v: InstructionAdapter) = invokeInstruction(v)
|
||||
@@ -161,5 +162,5 @@ fun IrMemberAccessExpression.receiverAndArgs(): List<IrExpression> {
|
||||
}
|
||||
|
||||
fun List<IrExpression>.asmTypes(context: JvmBackendContext): List<Type> {
|
||||
return map { context.state.typeMapper.mapType(it.type) }
|
||||
return map { context.state.typeMapper.mapType(it.type.toKotlinType()) }
|
||||
}
|
||||
@@ -1,23 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -33,7 +23,7 @@ class IsArrayOf : IntrinsicMethod() {
|
||||
}
|
||||
/*TODO original?*/
|
||||
val elementType = expression.getTypeArgument(descriptor.original.typeParameters.first().index)!!
|
||||
val arrayKtType = builtIns.getArrayType(Variance.INVARIANT, elementType)
|
||||
val arrayKtType = builtIns.getArrayType(Variance.INVARIANT, elementType.toKotlinType())
|
||||
val arrayType = typeMapper.mapType(arrayKtType)
|
||||
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.intrinsics
|
||||
@@ -21,6 +10,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
@@ -31,7 +21,7 @@ class NewArray : IntrinsicMethod() {
|
||||
return object : IrIntrinsicFunction(expression, signature, context) {
|
||||
override fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue {
|
||||
super.invoke(v, codegen, data)
|
||||
codegen.newArrayInstruction(ktType)
|
||||
codegen.newArrayInstruction(ktType.toKotlinType())
|
||||
return StackValue.onStack(returnType)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -23,7 +12,6 @@ import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
|
||||
import org.jetbrains.kotlin.backend.common.bridges.generateBridgesForFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
|
||||
@@ -53,11 +41,12 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription.*
|
||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor
|
||||
@@ -214,6 +203,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
)
|
||||
|
||||
val irFunction = IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.BRIDGE, bridgeDescriptorForIrFunction)
|
||||
irFunction.returnType = bridgeDescriptorForIrFunction.returnType!!.toIrType()!!
|
||||
irFunction.createParameterDeclarations()
|
||||
|
||||
context.createIrBuilder(irFunction.symbol).irBlockBody(irFunction) {
|
||||
@@ -226,8 +216,10 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
val implementation = if (isSpecialBridge) delegateTo.copyAsDeclaration() else delegateTo.descriptor
|
||||
val call = IrCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
implementation.returnType!!.toIrType()!!,
|
||||
implementation,
|
||||
null, JvmLoweredStatementOrigin.BRIDGE_DELEGATION,
|
||||
implementation.typeParametersCount,
|
||||
JvmLoweredStatementOrigin.BRIDGE_DELEGATION,
|
||||
if (isStubDeclarationWithDelegationToSuper) getSuperClassDescriptor(
|
||||
descriptor.containingDeclaration as ClassDescriptor
|
||||
) else null
|
||||
@@ -257,7 +249,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
)
|
||||
)
|
||||
}
|
||||
+IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.symbol, call)
|
||||
+IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.returnType, irFunction.symbol, call)
|
||||
}.apply {
|
||||
irFunction.body = this
|
||||
}
|
||||
@@ -292,7 +284,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
if (delegateParameterTypes == null || OBJECT_TYPE == delegateParameterTypes[i]) {
|
||||
irNotEquals(checkValue, irNull())
|
||||
} else {
|
||||
irIs(checkValue, overrideDescriptor.valueParameters[i].type)
|
||||
irIs(checkValue, overrideDescriptor.valueParameters[i].type.toIrType()!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,21 +293,25 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
context.andand(arg, result)
|
||||
}
|
||||
|
||||
+irIfThen(irNot(condition), irBlock {
|
||||
+irIfThen(context.irBuiltIns.unitType, irNot(condition), irBlock {
|
||||
+irReturn(
|
||||
when (typeSafeBarrierDescription) {
|
||||
MAP_GET_OR_DEFAULT -> irGet(IrVariableSymbolImpl(bridgeDescriptor.valueParameters[1]))
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription.NULL -> irNull()
|
||||
INDEX -> IrConstImpl.int(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.builtIns.intType, typeSafeBarrierDescription.defaultValue as Int
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription.MAP_GET_OR_DEFAULT -> irGet(
|
||||
bridgeDescriptor.valueParameters[1].type.toIrType()!!,
|
||||
IrVariableSymbolImpl(
|
||||
bridgeDescriptor.valueParameters[1]
|
||||
)
|
||||
)
|
||||
FALSE -> irFalse()
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription.NULL -> irNull()
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription.INDEX -> IrConstImpl.int(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.intType, typeSafeBarrierDescription.defaultValue as Int
|
||||
)
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription.FALSE -> irFalse()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -69,6 +58,7 @@ class ConstAndJvmFieldPropertiesLowering : IrElementTransformerVoid(), FileLower
|
||||
descriptor.correspondingProperty,
|
||||
expression.dispatchReceiver,
|
||||
expression.getValueArgument(descriptor.valueParameters.lastIndex)!!,
|
||||
expression.type,
|
||||
expression.origin,
|
||||
expression.superQualifier
|
||||
)
|
||||
@@ -80,6 +70,7 @@ class ConstAndJvmFieldPropertiesLowering : IrElementTransformerVoid(), FileLower
|
||||
expression.endOffset,
|
||||
descriptor.correspondingProperty,
|
||||
expression.dispatchReceiver,
|
||||
expression.type,
|
||||
expression.origin,
|
||||
expression.superQualifier
|
||||
)
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -33,6 +22,8 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -61,14 +52,20 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
val typeSubstitutor = TypeSubstitutor.create(mapOf(typeParameter0.typeConstructor to TypeProjectionImpl(arrayElementType)))
|
||||
val substitutedArrayOfFun = unsubstitutedArrayOfFun.substitute(typeSubstitutor)!!
|
||||
|
||||
val typeArguments = mapOf(typeParameter0 to arrayElementType)
|
||||
|
||||
val valueParameter0 = substitutedArrayOfFun.valueParameters[0]
|
||||
val arg0VarargType = valueParameter0.type
|
||||
val arg0VarargElementType = valueParameter0.varargElementType!!
|
||||
val arg0 = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType, arg0VarargElementType, arrayElements)
|
||||
val arg0 =
|
||||
IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arg0VarargType.toIrType()!!, arg0VarargElementType.toIrType()!!, arrayElements)
|
||||
|
||||
return IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedArrayOfFun, typeArguments).apply {
|
||||
return IrCallImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
substitutedArrayOfFun.returnType!!.toIrType()!!,
|
||||
substitutedArrayOfFun,
|
||||
substitutedArrayOfFun.typeParametersCount
|
||||
).apply {
|
||||
putValueArgument(0, arg0)
|
||||
}
|
||||
}
|
||||
@@ -127,6 +124,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
enumConstructor.body!! // will be transformed later
|
||||
).apply {
|
||||
parent = enumClass
|
||||
returnType = loweredConstructorDescriptor.returnType.toIrType()!!
|
||||
createParameterDeclarations()
|
||||
loweredEnumConstructors[constructorDescriptor] = this
|
||||
constructorDescriptor.valueParameters.forEach {
|
||||
@@ -193,7 +191,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
return IrFieldImpl(
|
||||
enumEntry.startOffset, enumEntry.endOffset, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
|
||||
fieldSymbol
|
||||
fieldSymbol, enumEntry.initializerExpression!!.type
|
||||
).also {
|
||||
it.initializer = IrExpressionBodyImpl(enumEntry.initializerExpression!!)
|
||||
enumEntryFields.add(it)
|
||||
@@ -227,15 +225,16 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
return IrFieldImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
|
||||
createSyntheticValuesFieldDescriptor(valuesArrayType),
|
||||
valuesArrayType.toIrType()!!,
|
||||
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)
|
||||
).also { valuesField = it }
|
||||
}
|
||||
|
||||
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
|
||||
createArrayOfExpression(
|
||||
irClass.defaultType,
|
||||
irClass.defaultType.toKotlinType(),
|
||||
enumEntryFields.map { irField ->
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol)
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol, irField.symbol.owner.type)
|
||||
})
|
||||
|
||||
private fun createSyntheticValuesFieldDescriptor(valuesArrayType: SimpleType): PropertyDescriptorImpl {
|
||||
@@ -263,6 +262,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
val result = IrDelegatingConstructorCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
enumConstructorCall.symbol,
|
||||
enumConstructorCall.descriptor,
|
||||
enumConstructorCall.typeArgumentsCount
|
||||
@@ -298,6 +298,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
val result = IrDelegatingConstructorCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
loweredDelegatedConstructor.symbol,
|
||||
loweredDelegatedConstructor.descriptor,
|
||||
loweredDelegatedConstructor.typeParameters.size
|
||||
@@ -330,8 +331,8 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
val result = createConstructorCall(startOffset, endOffset, loweredConstructor)
|
||||
|
||||
result.putValueArgument(0, IrConstImpl.string(startOffset, endOffset, context.builtIns.stringType, name))
|
||||
result.putValueArgument(1, IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, ordinal))
|
||||
result.putValueArgument(0, IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, name))
|
||||
result.putValueArgument(1, IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, ordinal))
|
||||
|
||||
descriptor.valueParameters.forEach { valueParameter ->
|
||||
val i = valueParameter.index
|
||||
@@ -357,6 +358,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
loweredConstructor.symbol,
|
||||
loweredConstructor.descriptor,
|
||||
loweredConstructor.typeParameters.size
|
||||
@@ -368,6 +370,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
IrCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
loweredConstructor.symbol.owner.parentAsClass.defaultType,
|
||||
loweredConstructor.symbol
|
||||
)
|
||||
}
|
||||
@@ -468,27 +471,49 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
val substitutedValueOf = unsubstitutedValueOf.substitute(typeSubstitutor)!!
|
||||
|
||||
val irValueOfCall =
|
||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, substitutedValueOf, mapOf(typeParameterT to enumClassType))
|
||||
IrCallImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
substitutedValueOf.returnType!!.toIrType()!!,
|
||||
substitutedValueOf,
|
||||
substitutedValueOf.typeParametersCount
|
||||
)
|
||||
irValueOfCall.putValueArgument(
|
||||
0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunction.valueParameters[0].symbol)
|
||||
)
|
||||
|
||||
return IrBlockBodyImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueOfFunction.symbol, irValueOfCall))
|
||||
listOf(
|
||||
IrReturnImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
valueOfFunction.returnType,
|
||||
valueOfFunction.symbol,
|
||||
irValueOfCall
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun createEnumValuesBody(valuesField: IrField): IrBody {
|
||||
val cloneFun = valuesField.type.memberScope.findSingleFunction(Name.identifier("clone"))
|
||||
val cloneFun = valuesField.type.toKotlinType().memberScope.findSingleFunction(Name.identifier("clone"))
|
||||
|
||||
val irCloneValues = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cloneFun).apply {
|
||||
dispatchReceiver = IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesField.symbol)
|
||||
val irCloneValues = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, cloneFun.returnType!!.toIrType()!!, cloneFun, 0).apply {
|
||||
dispatchReceiver = IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesField.symbol, valuesField.symbol.owner.type)
|
||||
}
|
||||
|
||||
return IrBlockBodyImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
listOf(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valuesFunction.symbol, irCloneValues))
|
||||
listOf(
|
||||
IrReturnImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
valuesFunction.symbol.owner.returnType,
|
||||
valuesFunction.symbol,
|
||||
irCloneValues
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -34,6 +23,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -80,10 +71,25 @@ class InterfaceDelegationLowering(val state: GenerationState) : IrElementTransfo
|
||||
val defaultImpls = InterfaceLowering.createDefaultImplsClassDescriptor(interfaceDescriptor)
|
||||
val defaultImplFun =
|
||||
InterfaceLowering.createDefaultImplFunDescriptor(defaultImpls, interfaceFun.original, interfaceDescriptor, state.typeMapper)
|
||||
|
||||
irFunction.returnType = defaultImplFun.returnType!!.toIrType()!!
|
||||
val irCallImpl =
|
||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, defaultImplFun, null, JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION)
|
||||
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.symbol, irCallImpl))
|
||||
IrCallImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
defaultImplFun.returnType!!.toIrType()!!,
|
||||
defaultImplFun,
|
||||
defaultImplFun.typeParametersCount,
|
||||
JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION
|
||||
)
|
||||
irBody.statements.add(
|
||||
IrReturnImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
irFunction.returnType,
|
||||
irFunction.symbol,
|
||||
irCallImpl
|
||||
)
|
||||
)
|
||||
|
||||
var offset = 0
|
||||
irFunction.dispatchReceiverParameter?.let {
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -20,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -32,9 +22,10 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
|
||||
class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
@@ -72,38 +63,42 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer
|
||||
false
|
||||
) as PropertyDescriptor
|
||||
privateInstance.name
|
||||
val field = createInstanceFieldWithInitializer(IrFieldSymbolImpl(privateInstance), constructor, irClass)
|
||||
val field = createInstanceFieldWithInitializer(IrFieldSymbolImpl(privateInstance), constructor, irClass, irClass.defaultType)
|
||||
createFieldWithCustomInitializer(
|
||||
publicInstance,
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, field.symbol),
|
||||
publicInstanceOwner
|
||||
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, field.symbol, irClass.defaultType),
|
||||
publicInstanceOwner,
|
||||
irClass.defaultType
|
||||
)
|
||||
} else {
|
||||
createInstanceFieldWithInitializer(publicInstance, constructor, publicInstanceOwner)
|
||||
createInstanceFieldWithInitializer(publicInstance, constructor, publicInstanceOwner, irClass.defaultType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInstanceFieldWithInitializer(
|
||||
fieldSymbol: IrFieldSymbol,
|
||||
constructor: ClassConstructorDescriptor,
|
||||
instanceOwner: IrDeclarationContainer
|
||||
instanceOwner: IrDeclarationContainer,
|
||||
objectType: IrType
|
||||
): IrField =
|
||||
createFieldWithCustomInitializer(
|
||||
fieldSymbol,
|
||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, constructor),
|
||||
instanceOwner
|
||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, objectType, constructor, 0),
|
||||
instanceOwner,
|
||||
objectType
|
||||
)
|
||||
|
||||
private fun createFieldWithCustomInitializer(
|
||||
fieldSymbol: IrFieldSymbol,
|
||||
instanceInitializer: IrExpression,
|
||||
instanceOwner: IrDeclarationContainer
|
||||
instanceOwner: IrDeclarationContainer,
|
||||
objectType: IrType
|
||||
): IrField =
|
||||
IrFieldImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
|
||||
fieldSymbol,
|
||||
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, instanceInitializer)
|
||||
fieldSymbol, objectType
|
||||
).also {
|
||||
it.initializer = IrExpressionBodyImpl(instanceInitializer)
|
||||
pendingTransformations.add { instanceOwner.declarations.add(it) }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -33,11 +22,11 @@ class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLowering
|
||||
|
||||
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
|
||||
val entrySymbol = context.descriptorsFactory.getSymbolForEnumEntry(expression.symbol)
|
||||
return IrGetFieldImpl(expression.startOffset, expression.endOffset, entrySymbol)
|
||||
return IrGetFieldImpl(expression.startOffset, expression.endOffset, entrySymbol, expression.type)
|
||||
}
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
||||
val instanceField = context.descriptorsFactory.getSymbolForObjectInstance(expression.symbol)
|
||||
return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceField)
|
||||
return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceField, expression.type)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.backend.jvm.lower
|
||||
@@ -44,7 +33,9 @@ import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.usesDefaultArguments
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -182,13 +173,16 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
|
||||
IrDelegatingConstructorCallImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
accessorForIr as ClassConstructorDescriptor
|
||||
context.irBuiltIns.unitType,
|
||||
accessorForIr as ClassConstructorDescriptor,
|
||||
0
|
||||
)
|
||||
else IrCallImpl(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
expression.type,
|
||||
accessorForIr,
|
||||
emptyMap(),
|
||||
0,
|
||||
expression.origin/*TODO super*/
|
||||
)
|
||||
//copyAllArgsToValueParams(call, expression)
|
||||
@@ -202,7 +196,7 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
|
||||
IrConstImpl.constNull(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
context.ir.symbols.defaultConstructorMarker.descriptor.defaultType
|
||||
context.ir.symbols.defaultConstructorMarker.owner.defaultType
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -246,23 +240,29 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
|
||||
accessorForIr, body
|
||||
)
|
||||
syntheticFunction.returnType = accessor.calleeDescriptor.returnType!!.toIrType()!!
|
||||
syntheticFunction.createParameterDeclarations()
|
||||
|
||||
val calleeDescriptor = accessor.calleeDescriptor as FunctionDescriptor
|
||||
val delegationCall =
|
||||
if (!isConstructor)
|
||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor)
|
||||
else IrDelegatingConstructorCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
createFunctionSymbol(accessor.calleeDescriptor) as IrConstructorSymbol,
|
||||
accessor.calleeDescriptor as ClassConstructorDescriptor
|
||||
)
|
||||
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor.returnType!!.toIrType()!!, calleeDescriptor, 0)
|
||||
else {
|
||||
val delegationConstructor = createFunctionSymbol(accessor.calleeDescriptor)
|
||||
IrDelegatingConstructorCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
context.irBuiltIns.unitType,
|
||||
delegationConstructor as IrConstructorSymbol,
|
||||
accessor.calleeDescriptor as ClassConstructorDescriptor
|
||||
)
|
||||
}
|
||||
copyAllArgsToValueParams(delegationCall, syntheticFunction)
|
||||
|
||||
body.statements.add(
|
||||
if (isConstructor) delegationCall else IrReturnImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
syntheticFunction.returnType,
|
||||
syntheticFunction.symbol,
|
||||
delegationCall
|
||||
)
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -85,7 +86,7 @@ class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPas
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(IrSimpleFunctionSymbolImpl(toArrayUtilDescriptor)).apply {
|
||||
irCall(IrSimpleFunctionSymbolImpl(toArrayUtilDescriptor), toArrayUtilDescriptor.returnType!!.toIrType()!!).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
@@ -143,7 +144,7 @@ class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPas
|
||||
|
||||
irFunction.body = context.createIrBuilder(irFunction.symbol).irBlockBody {
|
||||
+irReturn(
|
||||
irCall(IrSimpleFunctionSymbolImpl(toArrayUtilDescriptor)).apply {
|
||||
irCall(IrSimpleFunctionSymbolImpl(toArrayUtilDescriptor), toArrayUtilDescriptor.returnType!!.toIrType()!!).apply {
|
||||
putValueArgument(
|
||||
0,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol)
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.ir2cfg.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.isNothing
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
|
||||
@@ -66,7 +55,7 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun IrElement?.isNothing() = this is IrExpression && KotlinBuiltIns.isNothing(type)
|
||||
private fun IrElement?.isNothing() = this is IrExpression && type.isNothing()
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody, data: Boolean): IrStatement? {
|
||||
return body.process()
|
||||
@@ -81,8 +70,7 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
return if (data) {
|
||||
builder.add(declaration)
|
||||
declaration
|
||||
}
|
||||
else null
|
||||
} else null
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn, data: Boolean): IrStatement? {
|
||||
@@ -121,8 +109,7 @@ class FunctionGenerator(val function: IrFunction) {
|
||||
builder.move(branch.condition)
|
||||
if (!result.process().isNothing()) {
|
||||
builder.jump(whenExit)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
builder.move(branch.condition)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user