mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-27 00:21:29 +00:00
Compare commits
235 Commits
rr/perf/no
...
1.2.60
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be42b8094b | ||
|
|
44ecfb2fb8 | ||
|
|
5c26b0ea6f | ||
|
|
feb5a3040f | ||
|
|
31c113e7ee | ||
|
|
b520c72efe | ||
|
|
c411521b7e | ||
|
|
3a54e120b5 | ||
|
|
386e9b6f6c | ||
|
|
46f1e271bf | ||
|
|
923f51cd01 | ||
|
|
1f6ecc2f42 | ||
|
|
5133ac21f8 | ||
|
|
b09f3a36c4 | ||
|
|
c9d4aab352 | ||
|
|
ca34e2085e | ||
|
|
10ce84990b | ||
|
|
cbe3d00dfe | ||
|
|
403ae3f837 | ||
|
|
db12e36ec5 | ||
|
|
503d911601 | ||
|
|
fdfaeae21f | ||
|
|
375c785694 | ||
|
|
4c9eb5ef1c | ||
|
|
80763879ef | ||
|
|
aa83ea22f3 | ||
|
|
d8cddb29ef | ||
|
|
4d3cf043d8 | ||
|
|
2b2c6a68db | ||
|
|
ddea4a8458 | ||
|
|
2ae0d752d1 | ||
|
|
f787a414ff | ||
|
|
5d3663316a | ||
|
|
eb5767bad5 | ||
|
|
b5d3ed2bbe | ||
|
|
2df5edb7d0 | ||
|
|
82eb0bcfd4 | ||
|
|
9f98e596c3 | ||
|
|
a1c1c42924 | ||
|
|
c62e788936 | ||
|
|
9a04e1938c | ||
|
|
95af90e281 | ||
|
|
add6664045 | ||
|
|
1f6d7d9873 | ||
|
|
8007d78401 | ||
|
|
d303b4cb13 | ||
|
|
621acd3457 | ||
|
|
418389a125 | ||
|
|
f403b99d34 | ||
|
|
51da66fb39 | ||
|
|
2cb03f9097 | ||
|
|
cf07348abe | ||
|
|
8caf1ae593 | ||
|
|
94ac895de2 | ||
|
|
27f15a74b0 | ||
|
|
fe26547cd7 | ||
|
|
1960587512 | ||
|
|
8d1690ca00 | ||
|
|
ca04d5933c | ||
|
|
b0991596fe | ||
|
|
c4ec46b3c5 | ||
|
|
c1fe8f31f0 | ||
|
|
52af70f887 | ||
|
|
290805100c | ||
|
|
4f54b01820 | ||
|
|
cb9692834e | ||
|
|
56f2e469fc | ||
|
|
37374f5617 | ||
|
|
bd18a115a7 | ||
|
|
35170f5b3f | ||
|
|
42d4597480 | ||
|
|
92f008db5e | ||
|
|
19fe1a57ee | ||
|
|
0eaebcaf9e | ||
|
|
43d195f3e2 | ||
|
|
34fc43ae02 | ||
|
|
42fc117900 | ||
|
|
bcb74bf5bb | ||
|
|
679d49b8f2 | ||
|
|
e8377e6b22 | ||
|
|
2a04236902 | ||
|
|
5de77d1404 | ||
|
|
c860d8b0d6 | ||
|
|
f8f3cd435a | ||
|
|
2a70d61a9f | ||
|
|
be5a711e78 | ||
|
|
b69b9e2a9f | ||
|
|
956514c87e | ||
|
|
7e833239e8 | ||
|
|
6fdbae2aa4 | ||
|
|
47d62d9019 | ||
|
|
16d0ec4980 | ||
|
|
d479f0ebd5 | ||
|
|
0b42d17c83 | ||
|
|
7b5c88ed7c | ||
|
|
b0fb1d85ff | ||
|
|
5859c5ec25 | ||
|
|
d24b7b0a62 | ||
|
|
85fe6508f6 | ||
|
|
a6d7485f37 | ||
|
|
f50b00a3d6 | ||
|
|
349d703232 | ||
|
|
26eb425bdb | ||
|
|
1507ce4081 | ||
|
|
9edd9847a6 | ||
|
|
2950465277 | ||
|
|
66c564ec7a | ||
|
|
f92588ce9c | ||
|
|
3325a13974 | ||
|
|
559282b6da | ||
|
|
67c1b4918f | ||
|
|
9c00f62c6d | ||
|
|
93afdb29ef | ||
|
|
6512ed882f | ||
|
|
195b35e638 | ||
|
|
41439dd708 | ||
|
|
0368b4be03 | ||
|
|
d871511a18 | ||
|
|
89863a712f | ||
|
|
b9867d3091 | ||
|
|
eb056eb469 | ||
|
|
3adcb27b24 | ||
|
|
2d4b8f57f7 | ||
|
|
76f294fc0f | ||
|
|
57d08e74c9 | ||
|
|
0c5b8caa43 | ||
|
|
e679d60fd4 | ||
|
|
f8862690eb | ||
|
|
b2fd7d06da | ||
|
|
39d1eaeb2c | ||
|
|
11ebc67b9b | ||
|
|
94f5d0419a | ||
|
|
fe92eeb6ca | ||
|
|
b21b425d7e | ||
|
|
20820baa48 | ||
|
|
2bae870b43 | ||
|
|
c7a3be0083 | ||
|
|
8e824defaf | ||
|
|
0765850907 | ||
|
|
3f2fabb655 | ||
|
|
0bbe975baa | ||
|
|
f07eb3121a | ||
|
|
c880337f3e | ||
|
|
96d2896831 | ||
|
|
c1083a103e | ||
|
|
31b987cf27 | ||
|
|
26141ab16c | ||
|
|
d97e98f4a8 | ||
|
|
6e9bcf3929 | ||
|
|
eaf4d2a5ac | ||
|
|
c402630348 | ||
|
|
67334ae9e9 | ||
|
|
fa10c32ffa | ||
|
|
78a25c33fd | ||
|
|
c49df7fee6 | ||
|
|
4ae13e29fb | ||
|
|
c4ea50b357 | ||
|
|
0df72aaf15 | ||
|
|
a6718a6086 | ||
|
|
bdc02571c7 | ||
|
|
acbd5e7fae | ||
|
|
8efd490c5c | ||
|
|
ea32314468 | ||
|
|
c2251e8ca9 | ||
|
|
bb97b70373 | ||
|
|
2c3e02bc8c | ||
|
|
ffd673bbda | ||
|
|
34b04d8ec4 | ||
|
|
e1b7142454 | ||
|
|
70230564fb | ||
|
|
371ee9f1f7 | ||
|
|
20d5c78e5d | ||
|
|
1a25aefc94 | ||
|
|
b021fea545 | ||
|
|
b20b34224d | ||
|
|
42caa688de | ||
|
|
a8f31de2f5 | ||
|
|
f6488f7c4a | ||
|
|
34677658b3 | ||
|
|
fca612bcf8 | ||
|
|
d2908c3894 | ||
|
|
00c292fe77 | ||
|
|
899de0eb0f | ||
|
|
d4c2b33c39 | ||
|
|
60c4308186 | ||
|
|
e3e7eaec7b | ||
|
|
feeedf7c02 | ||
|
|
c08aefbf80 | ||
|
|
4d141fbd6c | ||
|
|
2dac33d3d1 | ||
|
|
02869ab0c7 | ||
|
|
a007784439 | ||
|
|
c3b3ad53b2 | ||
|
|
e1e0a61572 | ||
|
|
79681ce425 | ||
|
|
8fa29e4857 | ||
|
|
0e04e74d7f | ||
|
|
e1286f221f | ||
|
|
7380d1e3a1 | ||
|
|
a620a94d7b | ||
|
|
c4e6cb3232 | ||
|
|
ef32ee409a | ||
|
|
68c6c79be9 | ||
|
|
ba0f3277c5 | ||
|
|
d254acc980 | ||
|
|
1f4d43da55 | ||
|
|
e5dc807427 | ||
|
|
536e0583a4 | ||
|
|
4830afe183 | ||
|
|
26e6c8ed16 | ||
|
|
b5350da727 | ||
|
|
c576bc8fba | ||
|
|
87eb155795 | ||
|
|
80a94a7efb | ||
|
|
1457cfd8a8 | ||
|
|
d874ed4869 | ||
|
|
214463e6f7 | ||
|
|
f8e171c9f5 | ||
|
|
08a544b1a2 | ||
|
|
cff73d5309 | ||
|
|
2c37746a28 | ||
|
|
e5de325629 | ||
|
|
a2e33996a6 | ||
|
|
0ce12e4b17 | ||
|
|
01ae6515b1 | ||
|
|
62206740f5 | ||
|
|
a27e2b0d1e | ||
|
|
68c5f701d5 | ||
|
|
569a0a63d8 | ||
|
|
67ac21fca6 | ||
|
|
5dcd4c86e1 | ||
|
|
019e2212b8 | ||
|
|
b135fd279d | ||
|
|
4e95d27f7b | ||
|
|
c9751c2eeb |
5686
ChangeLog.md
5686
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -35,9 +35,8 @@ class CacheVersion(
|
||||
private val whenVersionChanged: CacheVersion.Action,
|
||||
private val whenTurnedOn: CacheVersion.Action,
|
||||
private val whenTurnedOff: CacheVersion.Action,
|
||||
isEnabled: ()->Boolean
|
||||
private val isEnabled: Boolean
|
||||
) {
|
||||
private val isEnabled by lazy(isEnabled)
|
||||
|
||||
private val actualVersion: Int?
|
||||
get() = try {
|
||||
@@ -95,18 +94,18 @@ class CacheVersion(
|
||||
}
|
||||
}
|
||||
|
||||
fun normalCacheVersion(dataRoot: File, enabled: Boolean? = null): CacheVersion =
|
||||
fun normalCacheVersion(dataRoot: File, enabled: Boolean): CacheVersion =
|
||||
CacheVersion(ownVersion = NORMAL_VERSION,
|
||||
versionFile = File(dataRoot, NORMAL_VERSION_FILE_NAME),
|
||||
whenVersionChanged = CacheVersion.Action.REBUILD_CHUNK,
|
||||
whenTurnedOn = CacheVersion.Action.REBUILD_CHUNK,
|
||||
whenTurnedOff = CacheVersion.Action.CLEAN_NORMAL_CACHES,
|
||||
isEnabled = { enabled ?: IncrementalCompilation.isEnabled() })
|
||||
isEnabled = enabled)
|
||||
|
||||
fun dataContainerCacheVersion(dataRoot: File, enabled: Boolean? = null): CacheVersion =
|
||||
fun dataContainerCacheVersion(dataRoot: File, enabled: Boolean): CacheVersion =
|
||||
CacheVersion(ownVersion = DATA_CONTAINER_VERSION,
|
||||
versionFile = File(dataRoot, DATA_CONTAINER_VERSION_FILE_NAME),
|
||||
whenVersionChanged = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
whenTurnedOn = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
whenTurnedOff = CacheVersion.Action.CLEAN_DATA_CONTAINER,
|
||||
isEnabled = { enabled ?: IncrementalCompilation.isEnabled() })
|
||||
isEnabled = enabled)
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import gnu.trove.THashSet
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.incremental.storage.*
|
||||
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
@@ -264,7 +265,7 @@ open class IncrementalJvmCache(
|
||||
|
||||
override fun clean() {
|
||||
super.clean()
|
||||
normalCacheVersion(targetDataRoot).clean()
|
||||
normalCacheVersion(targetDataRoot, IncrementalCompilation.isEnabledForJvm()).clean()
|
||||
}
|
||||
|
||||
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
|
||||
|
||||
@@ -78,7 +78,7 @@ class KotlinModuleXmlBuilder {
|
||||
directoriesToFilterOut: Set<File>) {
|
||||
p.println("<!-- Classpath -->")
|
||||
for (file in files) {
|
||||
val isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.isEnabled()
|
||||
val isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.isEnabledForJvm()
|
||||
if (isOutput) {
|
||||
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
|
||||
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
|
||||
|
||||
@@ -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")
|
||||
9
buildSrc/gradle.properties.as33c4
Normal file
9
buildSrc/gradle.properties.as33c4
Normal file
@@ -0,0 +1,9 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=false
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
intellijUltimateEnabled=false
|
||||
298
buildSrc/prepare-deps/intellij-sdk/build.gradle.kts.as33c4
Normal file
298
buildSrc/prepare-deps/intellij-sdk/build.gradle.kts.as33c4
Normal file
@@ -0,0 +1,298 @@
|
||||
|
||||
@file:Suppress("PropertyName")
|
||||
|
||||
import org.gradle.api.publish.ivy.internal.artifact.DefaultIvyArtifact
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyConfiguration
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyPublicationIdentity
|
||||
import org.gradle.api.publish.ivy.internal.publisher.IvyDescriptorFileGenerator
|
||||
import java.io.File
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
|
||||
}
|
||||
}
|
||||
|
||||
val intellijUltimateEnabled: Boolean by rootProject.extra
|
||||
val intellijRepo: String by rootProject.extra
|
||||
val intellijReleaseType: String by rootProject.extra
|
||||
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
|
||||
val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelease") as String?
|
||||
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
|
||||
val intellijSeparateSdks: Boolean by rootProject.extra
|
||||
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
|
||||
val installIntellijUltimate = intellijUltimateEnabled
|
||||
|
||||
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
|
||||
if (intellijVersionDelimiterIndex == -1) {
|
||||
error("Invalid IDEA version $intellijVersion")
|
||||
}
|
||||
|
||||
val platformBaseVersion = intellijVersion.substring(0, intellijVersionDelimiterIndex)
|
||||
|
||||
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
|
||||
|
||||
logger.info("intellijVersion: $intellijVersion")
|
||||
logger.info("androidStudioRelease: $androidStudioRelease")
|
||||
logger.info("androidStudioBuild: $androidStudioBuild")
|
||||
|
||||
logger.info("intellijSeparateSdks: $intellijSeparateSdks")
|
||||
logger.info("installIntellijCommunity: $installIntellijCommunity")
|
||||
logger.info("installIntellijUltimate: $installIntellijUltimate")
|
||||
|
||||
val studioOs by lazy {
|
||||
when {
|
||||
OperatingSystem.current().isWindows -> "windows"
|
||||
OperatingSystem.current().isMacOsX -> "mac"
|
||||
OperatingSystem.current().isLinux -> "linux"
|
||||
else -> {
|
||||
logger.error("Unknown operating system for android tools: ${OperatingSystem.current().name}")
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
if (androidStudioRelease != null) {
|
||||
ivy {
|
||||
artifactPattern("https://dl.google.com/dl/android/studio/ide-zips/$androidStudioRelease/[artifact]-[revision]-$studioOs.zip")
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
ivy {
|
||||
artifactPattern("https://dl.bintray.com/kotlin/as/[artifact]-[revision].zip")
|
||||
credentials {
|
||||
username = System.getenv("AS_BINTRAY_USER_NAME")
|
||||
password = System.getenv("AS_BINTRAY_API_KEY")
|
||||
}
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
maven { setUrl("$intellijRepo/$intellijReleaseType") }
|
||||
maven { setUrl("https://plugins.jetbrains.com/maven") }
|
||||
// github returns broken pipe =(
|
||||
// ivy {
|
||||
// artifactPattern("https://raw.github.com/JetBrains/intellij-community/[revision]/lib/src/[artifact].zip")
|
||||
// metadataSources {
|
||||
// artifact()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
val intellij by configurations.creating
|
||||
val intellijUltimate by configurations.creating
|
||||
val sources by configurations.creating
|
||||
val `asm-shaded-sources` by configurations.creating
|
||||
val `jps-standalone` by configurations.creating
|
||||
val `jps-build-test` by configurations.creating
|
||||
val `intellij-core` by configurations.creating
|
||||
val `plugins-NodeJS` by configurations.creating
|
||||
|
||||
val customDepsRepoDir = File(buildDir, "repo")
|
||||
val customDepsOrg: String by rootProject.extra
|
||||
val customDepsRevision = intellijVersion
|
||||
val customDepsRepoModulesDir = File(customDepsRepoDir, "$customDepsOrg/$customDepsRevision")
|
||||
val repoDir = customDepsRepoModulesDir
|
||||
|
||||
dependencies {
|
||||
if (androidStudioRelease != null) {
|
||||
intellij("google:android-studio-ide:$androidStudioBuild")
|
||||
} else {
|
||||
if (installIntellijCommunity) {
|
||||
intellij("com.jetbrains.intellij.idea:ideaIC:$intellijVersion")
|
||||
}
|
||||
if (installIntellijUltimate) {
|
||||
intellijUltimate("com.jetbrains.intellij.idea:ideaIU:$intellijVersion")
|
||||
}
|
||||
}
|
||||
sources("com.jetbrains.intellij.idea:ideaIC:$intellijVersion:sources@jar")
|
||||
// if (platformBaseVersion == "182") {
|
||||
// // There is no asm sources for 182 yet
|
||||
// `asm-shaded-sources`("asmsources:asm-src:181@zip")
|
||||
// } else {
|
||||
// `asm-shaded-sources`("asmsources:asm-src:$platformBaseVersion@zip")
|
||||
// }
|
||||
`jps-standalone`("com.jetbrains.intellij.idea:jps-standalone:$intellijVersion")
|
||||
`jps-build-test`("com.jetbrains.intellij.idea:jps-build-test:$intellijVersion")
|
||||
`intellij-core`("com.jetbrains.intellij.idea:intellij-core:$intellijVersion")
|
||||
if (intellijUltimateEnabled) {
|
||||
`plugins-NodeJS`("com.jetbrains.plugins:NodeJS:${rootProject.extra["versions.idea.NodeJS"]}@zip")
|
||||
}
|
||||
}
|
||||
|
||||
fun Task.configureExtractFromConfigurationTask(sourceConfig: Configuration,
|
||||
pathRemap: (String) -> String = { it },
|
||||
extractor: (Configuration) -> Any) {
|
||||
dependsOn(sourceConfig)
|
||||
inputs.files(sourceConfig)
|
||||
val targetDir = File(repoDir, sourceConfig.name)
|
||||
outputs.dirs(targetDir)
|
||||
doFirst {
|
||||
project.copy {
|
||||
from(extractor(sourceConfig))
|
||||
into(targetDir)
|
||||
eachFile {
|
||||
path = pathRemap(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removePathPrefix(path: String): String {
|
||||
if (androidStudioRelease == null) return path
|
||||
val slashes = 2 // if (studioOs == "mac") 2 else 1
|
||||
var result = path
|
||||
repeat(slashes) {
|
||||
result = result.substringAfter('/')
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val unzipIntellijSdk by tasks.creating {
|
||||
configureExtractFromConfigurationTask(intellij, pathRemap = { removePathPrefix(it) }) {
|
||||
zipTree(it.singleFile).matching {
|
||||
exclude("**/plugins/Kotlin/**")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unzipIntellijUltimateSdk by tasks.creating {
|
||||
configureExtractFromConfigurationTask(intellijUltimate) {
|
||||
zipTree(it.singleFile).matching {
|
||||
exclude("plugins/Kotlin/**")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unzipIntellijCore by tasks.creating { configureExtractFromConfigurationTask(`intellij-core`) { zipTree(it.singleFile) } }
|
||||
|
||||
val unzipJpsStandalone by tasks.creating { configureExtractFromConfigurationTask(`jps-standalone`) { zipTree(it.singleFile) } }
|
||||
|
||||
//val copyAsmShadedSources by tasks.creating(Copy::class.java) {
|
||||
// from(`asm-shaded-sources`)
|
||||
// rename(".zip", ".jar")
|
||||
// destinationDir = File(repoDir, `asm-shaded-sources`.name)
|
||||
//}
|
||||
|
||||
val copyIntellijSdkSources by tasks.creating(ShadowJar::class.java) {
|
||||
// from(copyAsmShadedSources)
|
||||
from(sources)
|
||||
baseName = "ideaIC"
|
||||
version = intellijVersion
|
||||
classifier = "sources"
|
||||
destinationDir = File(repoDir, sources.name)
|
||||
}
|
||||
|
||||
val copyJpsBuildTest by tasks.creating { configureExtractFromConfigurationTask(`jps-build-test`) { it.singleFile } }
|
||||
|
||||
val unzipNodeJSPlugin by tasks.creating { configureExtractFromConfigurationTask(`plugins-NodeJS`) { zipTree(it.singleFile) } }
|
||||
|
||||
fun writeIvyXml(moduleName: String, fileName: String, jarFiles: FileCollection, baseDir: File, sourcesJar: File?) {
|
||||
with(IvyDescriptorFileGenerator(DefaultIvyPublicationIdentity(customDepsOrg, moduleName, intellijVersion))) {
|
||||
addConfiguration(DefaultIvyConfiguration("default"))
|
||||
addConfiguration(DefaultIvyConfiguration("sources"))
|
||||
jarFiles.asFileTree.files.forEach {
|
||||
if (it.isFile && it.extension == "jar") {
|
||||
val relativeName = it.toRelativeString(baseDir).removeSuffix(".jar")
|
||||
addArtifact(DefaultIvyArtifact(it, relativeName, "jar", "jar", null).also { it.conf = "default" })
|
||||
}
|
||||
}
|
||||
if (sourcesJar != null) {
|
||||
val sourcesArtifactName = sourcesJar.name.removeSuffix(".jar").substringBefore("-")
|
||||
addArtifact(DefaultIvyArtifact(sourcesJar, sourcesArtifactName, "jar", "sources", "sources").also { it.conf = "sources" })
|
||||
}
|
||||
writeTo(File(customDepsRepoModulesDir, "$fileName.ivy.xml"))
|
||||
}
|
||||
}
|
||||
|
||||
val prepareIvyXmls by tasks.creating {
|
||||
dependsOn(unzipIntellijCore, unzipJpsStandalone, copyIntellijSdkSources, copyJpsBuildTest/*, copyAsmShadedSources */)
|
||||
|
||||
val intellijSdkDir = File(repoDir, intellij.name)
|
||||
val intellijUltimateSdkDir = File(repoDir, intellijUltimate.name)
|
||||
|
||||
if (installIntellijCommunity) {
|
||||
dependsOn(unzipIntellijSdk)
|
||||
inputs.dir(intellijSdkDir)
|
||||
outputs.file(File(repoDir, "${intellij.name}.ivy.xml"))
|
||||
}
|
||||
|
||||
if (installIntellijUltimate) {
|
||||
dependsOn(unzipIntellijUltimateSdk)
|
||||
inputs.dir(intellijUltimateSdkDir)
|
||||
outputs.file(File(repoDir, "${intellijUltimate.name}.ivy.xml"))
|
||||
}
|
||||
|
||||
val flatDeps = listOf(`intellij-core`, `jps-standalone`, `jps-build-test`, `asm-shaded-sources`)
|
||||
flatDeps.forEach {
|
||||
inputs.dir(File(repoDir, it.name))
|
||||
outputs.file(File(repoDir, "${it.name}.ivy.xml"))
|
||||
}
|
||||
inputs.dir(File(repoDir, sources.name))
|
||||
|
||||
if (intellijUltimateEnabled) {
|
||||
dependsOn(unzipNodeJSPlugin)
|
||||
inputs.dir(File(repoDir, `plugins-NodeJS`.name))
|
||||
outputs.file(File(repoDir, "${`plugins-NodeJS`.name}.ivy.xml"))
|
||||
}
|
||||
|
||||
doFirst {
|
||||
val sourcesFile = if (sources.isEmpty) null else File(repoDir, "${sources.name}/${sources.singleFile.name}")
|
||||
|
||||
if (installIntellijCommunity) {
|
||||
val libDir = File(intellijSdkDir, "lib")
|
||||
writeIvyXml(intellij.name,
|
||||
intellij.name,
|
||||
fileTree(libDir).filter {
|
||||
it.parentFile == libDir && !it.name.startsWith("kotlin-")
|
||||
},
|
||||
libDir,
|
||||
sourcesFile)
|
||||
|
||||
File(intellijSdkDir, "plugins").listFiles { it: File -> it.isDirectory }.forEach {
|
||||
writeIvyXml(it.name, "intellij.plugin.${it.name}", files("$it/lib/"), File(it, "lib"), sourcesFile)
|
||||
}
|
||||
}
|
||||
|
||||
if (installIntellijUltimate) {
|
||||
val libDir = File(intellijUltimateSdkDir, "lib")
|
||||
writeIvyXml(intellij.name, // important! the module name should be "intellij"
|
||||
intellijUltimate.name,
|
||||
fileTree(libDir).filter {
|
||||
it.parentFile == libDir && !it.name.startsWith("kotlin-")
|
||||
},
|
||||
libDir,
|
||||
sourcesFile)
|
||||
|
||||
File(intellijUltimateSdkDir, "plugins").listFiles { it: File -> it.isDirectory }.forEach {
|
||||
writeIvyXml(it.name, "intellijUltimate.plugin.${it.name}", files("$it/lib/"), File(it, "lib"), sourcesFile)
|
||||
}
|
||||
}
|
||||
|
||||
flatDeps.forEach {
|
||||
writeIvyXml(it.name, it.name, files("$repoDir/${it.name}"), File(repoDir, it.name), sourcesFile)
|
||||
}
|
||||
|
||||
if (intellijUltimateEnabled) {
|
||||
val nodeJsBaseDir = "${`plugins-NodeJS`.name}/NodeJS/lib"
|
||||
writeIvyXml("NodeJS", `plugins-NodeJS`.name, files("$repoDir/$nodeJsBaseDir"), File(repoDir, nodeJsBaseDir), sourcesFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val build by tasks.creating {
|
||||
dependsOn(prepareIvyXmls)
|
||||
}
|
||||
|
||||
val clean by tasks.creating(Delete::class) {
|
||||
delete(customDepsRepoModulesDir)
|
||||
delete(buildDir)
|
||||
}
|
||||
@@ -97,13 +97,16 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
private lateinit var platformVersion: String
|
||||
private lateinit var platformBaseNumber: String
|
||||
private lateinit var platformDir: File
|
||||
private var isAndroidStudioPlatform: Boolean = false
|
||||
|
||||
private fun initEnvironment(project: Project) {
|
||||
projectDir = project.projectDir
|
||||
platformVersion = project.extensions.extraProperties.get("versions.intellijSdk").toString()
|
||||
platformBaseNumber = platformVersion.substringBefore(".", "").takeIf { it.isNotEmpty() }
|
||||
?: error("Invalid platform version: $platformVersion")
|
||||
?: platformVersion.substringBefore("-", "").takeIf { it.isNotEmpty() }
|
||||
?: error("Invalid platform version: $platformVersion")
|
||||
platformDir = IntellijRootUtils.getIntellijRootDir(project)
|
||||
isAndroidStudioPlatform = project.extensions.extraProperties.has("versions.androidStudioRelease")
|
||||
}
|
||||
|
||||
private fun pill(rootProject: Project) {
|
||||
@@ -165,12 +168,19 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
val runConfigurationsDir = File(projectDir, "buildSrc/src/main/resources/runConfigurations")
|
||||
val targetDir = File(projectDir, ".idea/runConfigurations")
|
||||
val platformDirProjectRelative = "\$PROJECT_DIR\$/" + platformDir.toRelativeString(projectDir)
|
||||
val additionalIdeaArgs = if (isAndroidStudioPlatform) "-Didea.platform.prefix=AndroidStudio" else ""
|
||||
|
||||
targetDir.mkdirs()
|
||||
|
||||
fun substitute(text: String): String {
|
||||
return text
|
||||
.replace("\$IDEA_HOME_PATH\$", platformDirProjectRelative)
|
||||
.replace("\$ADDITIONAL_IDEA_ARGS\$", additionalIdeaArgs)
|
||||
}
|
||||
|
||||
runConfigurationsDir.listFiles()
|
||||
.filter { it.extension == "xml" }
|
||||
.map { it.name to it.readText().replace("\$IDEA_HOME_PATH\$", platformDirProjectRelative) }
|
||||
.map { it.name to substitute(it.readText()) }
|
||||
.forEach { File(targetDir, it.first).writeText(it.second) }
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<log_file alias="idea.log" path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<module name="idea-runner" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true $ADDITIONAL_IDEA_ARGS$" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$IDEA_HOME_PATH$" />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<log_file alias="idea.log" path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<module name="idea-runner" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.ProcessCanceledException=disabled" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.ProcessCanceledException=disabled $ADDITIONAL_IDEA_ARGS$" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$IDEA_HOME_PATH$" />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
|
||||
@@ -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? {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,7 +62,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
|
||||
private boolean isDone = false;
|
||||
|
||||
private final Set<File> packagePartSourceFiles = new HashSet<>();
|
||||
private final Set<File> sourceFiles = new HashSet<>();
|
||||
private final Map<String, PackageParts> partsGroupedByPackage = new LinkedHashMap<>();
|
||||
|
||||
public ClassFileFactory(@NotNull GenerationState state, @NotNull ClassBuilderFactory builderFactory) {
|
||||
@@ -121,9 +121,8 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
}
|
||||
|
||||
JvmModuleProtoBuf.Module moduleProto = builder.build();
|
||||
if (moduleProto.getSerializedSize() == 0) return;
|
||||
|
||||
generators.put(outputFilePath, new OutAndSourceFileList(CollectionsKt.toList(packagePartSourceFiles)) {
|
||||
generators.put(outputFilePath, new OutAndSourceFileList(CollectionsKt.toList(sourceFiles)) {
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
return ModuleMappingKt.serializeToByteArray(moduleProto, JvmMetadataVersion.INSTANCE.toArray());
|
||||
@@ -227,14 +226,14 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
@NotNull
|
||||
public PackageCodegen forPackage(@NotNull FqName fqName, @NotNull Collection<KtFile> files) {
|
||||
assert !isDone : "Already done!";
|
||||
registerPackagePartSourceFiles(files);
|
||||
registerSourceFiles(files);
|
||||
return state.getCodegenFactory().createPackageCodegen(state, files, fqName, buildNewPackagePartRegistry(fqName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MultifileClassCodegen forMultifileClass(@NotNull FqName facadeFqName, @NotNull Collection<KtFile> files) {
|
||||
assert !isDone : "Already done!";
|
||||
registerPackagePartSourceFiles(files);
|
||||
registerSourceFiles(files);
|
||||
return state.getCodegenFactory().createMultifileClassCodegen(state, files, facadeFqName, buildNewPackagePartRegistry(facadeFqName.parent()));
|
||||
}
|
||||
|
||||
@@ -246,8 +245,8 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
};
|
||||
}
|
||||
|
||||
private void registerPackagePartSourceFiles(Collection<KtFile> files) {
|
||||
packagePartSourceFiles.addAll(toIoFilesIgnoringNonPhysical(PackagePartClassUtils.getFilesWithCallables(files)));
|
||||
private void registerSourceFiles(Collection<KtFile> files) {
|
||||
sourceFiles.addAll(toIoFilesIgnoringNonPhysical(files));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,13 +377,13 @@ 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
|
||||
): IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment? {
|
||||
if (!IncrementalCompilation.isEnabled()) return null
|
||||
if (!IncrementalCompilation.isEnabledForJvm()) return null
|
||||
|
||||
val packageFqName = facadeFqName.parent()
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -35,9 +36,19 @@ class SamWrapperClasses(private val state: GenerationState) {
|
||||
expressionCodegen: ExpressionCodegen,
|
||||
contextDescriptor: CallableMemberDescriptor
|
||||
): Type {
|
||||
val isInsideInline = InlineUtil.isInlineOrContainingInline(expressionCodegen.context.contextDescriptor)
|
||||
val isInsideInline = InlineUtil.isInlineOrContainingInline(expressionCodegen.context.contextDescriptor) ||
|
||||
isInsideInlineLambdaContext(expressionCodegen.context, state)
|
||||
return samInterfaceToWrapperClass.getOrPut(WrapperKey(samType, file, isInsideInline)) {
|
||||
SamWrapperCodegen(state, samType, expressionCodegen.parentCodegen, isInsideInline).genWrapper(file, contextDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInsideInlineLambdaContext(context: CodegenContext<*>, state: GenerationState):Boolean {
|
||||
var parent: CodegenContext<*>? = context
|
||||
while (parent != null && parent != state.rootContext) {
|
||||
if (parent is InlineLambdaContext) return true
|
||||
parent = parent.parentContext
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -44,6 +44,7 @@ class ScriptCodegen private constructor(
|
||||
typeMapper.mapSupertype(scriptDescriptor.getSuperClassOrAny().defaultType, null).internalName,
|
||||
mapSupertypesNames(typeMapper, scriptDescriptor.getSuperInterfaces(), null)
|
||||
)
|
||||
AnnotationCodegen.forClass(v.visitor, this, typeMapper).genAnnotations(scriptDescriptor, null)
|
||||
}
|
||||
|
||||
override fun generateBody() {
|
||||
@@ -75,10 +76,9 @@ class ScriptCodegen private constructor(
|
||||
|
||||
val jvmSignature = typeMapper.mapScriptSignature(
|
||||
scriptDescriptor,
|
||||
scriptContext.earlierScripts,
|
||||
scriptDefinition.implicitReceivers,
|
||||
scriptDefinition.environmentVariables
|
||||
scriptContext.earlierScripts
|
||||
)
|
||||
val asmMethod = jvmSignature.asmMethod
|
||||
|
||||
if (state.replSpecific.shouldGenerateScriptResultValue) {
|
||||
val resultFieldInfo = scriptContext.resultFieldInfo
|
||||
@@ -94,6 +94,8 @@ class ScriptCodegen private constructor(
|
||||
OtherOrigin(scriptDeclaration, scriptDescriptor.unsubstitutedPrimaryConstructor),
|
||||
ACC_PUBLIC, jvmSignature.asmMethod.name, jvmSignature.asmMethod.descriptor, null, null)
|
||||
|
||||
FunctionCodegen.generateMethodAnnotations(scriptDescriptor.unsubstitutedPrimaryConstructor, asmMethod, mv, this, typeMapper)
|
||||
|
||||
if (state.classBuilderMode.generateBodies) {
|
||||
mv.visitCode()
|
||||
|
||||
@@ -104,48 +106,15 @@ class ScriptCodegen private constructor(
|
||||
val superclass = scriptDescriptor.getSuperClassNotAny()
|
||||
// TODO: throw if class is not found)
|
||||
|
||||
if (superclass == null) {
|
||||
iv.load(0, classType)
|
||||
iv.invokespecial("java/lang/Object", "<init>", "()V", false)
|
||||
}
|
||||
else {
|
||||
val ctorDesc = superclass.unsubstitutedPrimaryConstructor
|
||||
?: throw RuntimeException("Primary constructor not found for script template " + superclass.toString())
|
||||
|
||||
iv.load(0, classType)
|
||||
|
||||
fun Int.incrementIf(cond: Boolean): Int = if (cond) plus(1) else this
|
||||
val valueParamStart = 1
|
||||
.incrementIf(scriptContext.earlierScripts.isNotEmpty())
|
||||
.incrementIf(scriptDefinition.implicitReceivers.isNotEmpty())
|
||||
.incrementIf(scriptDefinition.environmentVariables.isNotEmpty())
|
||||
|
||||
val valueParameters = scriptDescriptor.unsubstitutedPrimaryConstructor.valueParameters
|
||||
for (superclassParam in ctorDesc.valueParameters) {
|
||||
val valueParam = valueParameters.first { it.name == superclassParam.name }
|
||||
iv.load(valueParam!!.index + valueParamStart, typeMapper.mapType(valueParam.type))
|
||||
}
|
||||
|
||||
val ctorMethod = typeMapper.mapToCallableMethod(ctorDesc, false)
|
||||
val sig = ctorMethod.getAsmMethod().descriptor
|
||||
|
||||
iv.invokespecial(
|
||||
typeMapper.mapSupertype(superclass.defaultType, null).internalName,
|
||||
"<init>", sig, false)
|
||||
}
|
||||
iv.load(0, classType)
|
||||
|
||||
val frameMap = FrameMap()
|
||||
frameMap.enterTemp(OBJECT_TYPE)
|
||||
|
||||
fun genFieldFromArrayElement(descriptor: ClassDescriptor, paramIndex: Int, elementIndex: Int, name: String) {
|
||||
val elementClassType = typeMapper.mapClass(descriptor)
|
||||
iv.load(0, classType)
|
||||
iv.load(paramIndex, elementClassType)
|
||||
iv.aconst(elementIndex)
|
||||
iv.aload(OBJECT_TYPE)
|
||||
iv.checkcast(elementClassType)
|
||||
iv.putfield(classType.internalName, name, elementClassType.descriptor)
|
||||
val array = StackValue.local(paramIndex, AsmUtil.getArrayType(OBJECT_TYPE))
|
||||
val value = StackValue.arrayElement(OBJECT_TYPE, null, array, StackValue.constant(elementIndex, Type.INT_TYPE))
|
||||
val field = StackValue.field(elementClassType, classType, name, false, StackValue.local(0, classType))
|
||||
field.store(value, iv)
|
||||
}
|
||||
|
||||
if (!scriptContext.earlierScripts.isEmpty()) {
|
||||
@@ -157,6 +126,37 @@ class ScriptCodegen private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (superclass == null) {
|
||||
iv.load(0, classType)
|
||||
iv.invokespecial("java/lang/Object", "<init>", "()V", false)
|
||||
} else {
|
||||
val ctorDesc = superclass.unsubstitutedPrimaryConstructor
|
||||
?: throw RuntimeException("Primary constructor not found for script template " + superclass.toString())
|
||||
|
||||
iv.load(0, classType)
|
||||
|
||||
fun Int.incrementIf(cond: Boolean): Int = if (cond) plus(1) else this
|
||||
val valueParamStart = 1
|
||||
.incrementIf(scriptContext.earlierScripts.isNotEmpty())
|
||||
|
||||
val valueParameters = scriptDescriptor.unsubstitutedPrimaryConstructor.valueParameters
|
||||
for (superclassParam in ctorDesc.valueParameters) {
|
||||
val valueParam = valueParameters.first { it.name == superclassParam.name }
|
||||
val paramType = typeMapper.mapType(valueParam.type)
|
||||
iv.load(valueParam!!.index + valueParamStart, paramType)
|
||||
frameMap.enterTemp(paramType)
|
||||
}
|
||||
|
||||
val ctorMethod = typeMapper.mapToCallableMethod(ctorDesc, false)
|
||||
val sig = ctorMethod.getAsmMethod().descriptor
|
||||
|
||||
iv.invokespecial(
|
||||
typeMapper.mapSupertype(superclass.defaultType, null).internalName,
|
||||
"<init>", sig, false
|
||||
)
|
||||
}
|
||||
iv.load(0, classType)
|
||||
|
||||
if (scriptDefinition.implicitReceivers.isNotEmpty()) {
|
||||
val receiversParamIndex = frameMap.enterTemp(AsmUtil.getArrayType(OBJECT_TYPE))
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1607,9 +1607,7 @@ public class KotlinTypeMapper {
|
||||
@NotNull
|
||||
public JvmMethodSignature mapScriptSignature(
|
||||
@NotNull ScriptDescriptor script,
|
||||
@NotNull List<ScriptDescriptor> importedScripts,
|
||||
List<? extends KType> implicitReceivers,
|
||||
List<? extends Pair<String, ? extends KType>> environmentVariables
|
||||
@NotNull List<ScriptDescriptor> importedScripts
|
||||
) {
|
||||
JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
|
||||
|
||||
@@ -1619,14 +1617,6 @@ public class KotlinTypeMapper {
|
||||
writeParameter(sw, DescriptorUtilsKt.getModule(script).getBuiltIns().getArray().getDefaultType(), null);
|
||||
}
|
||||
|
||||
if (implicitReceivers.size() > 0) {
|
||||
writeParameter(sw, DescriptorUtilsKt.getModule(script).getBuiltIns().getArray().getDefaultType(), null);
|
||||
}
|
||||
|
||||
if (environmentVariables.size() > 0) {
|
||||
writeParameter(sw, DescriptorUtilsKt.getModule(script).getBuiltIns().getMap().getDefaultType(), null);
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
|
||||
writeParameter(sw, valueParameter.getType(), /* callableDescriptor = */ null);
|
||||
}
|
||||
|
||||
@@ -37,19 +37,21 @@ class Jsr305Parser(private val collector: MessageCollector) {
|
||||
item.startsWith("@") -> {
|
||||
val (name, state) = parseJsr305UserDefined(item) ?: return@forEach
|
||||
val current = userDefined[name]
|
||||
if (current != null) {
|
||||
if (current == null) {
|
||||
userDefined[name] = state
|
||||
} else if (current != state) {
|
||||
reportDuplicateJsr305("@$name:${current.description}", item)
|
||||
return@forEach
|
||||
}
|
||||
userDefined[name] = state
|
||||
}
|
||||
item.startsWith("under-migration") -> {
|
||||
if (migration != null) {
|
||||
val state = parseJsr305UnderMigration(item)
|
||||
if (migration == null) {
|
||||
migration = state
|
||||
} else if (migration != state) {
|
||||
reportDuplicateJsr305("under-migration:${migration?.description}", item)
|
||||
return@forEach
|
||||
}
|
||||
|
||||
migration = parseJsr305UnderMigration(item)
|
||||
}
|
||||
item == "enable" -> {
|
||||
collector.report(
|
||||
@@ -61,11 +63,12 @@ class Jsr305Parser(private val collector: MessageCollector) {
|
||||
global = ReportLevel.STRICT
|
||||
}
|
||||
else -> {
|
||||
if (global != null) {
|
||||
if (global == null) {
|
||||
global = ReportLevel.findByDescription(item)
|
||||
} else if (global!!.description != item) {
|
||||
reportDuplicateJsr305(global!!.description, item)
|
||||
return@forEach
|
||||
}
|
||||
global = ReportLevel.findByDescription(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLITool<A> {
|
||||
|
||||
public static String KOTLIN_HOME_PROPERTY = "kotlin.home";
|
||||
public static String KOTLIN_HOME_ENV_VAR = "KOTLIN_HOME";
|
||||
|
||||
// Used in CompilerRunnerUtil#invokeExecMethod, in Eclipse plugin (KotlinCLICompiler) and in kotlin-gradle-plugin (GradleCompilerRunner)
|
||||
@NotNull
|
||||
@@ -165,16 +164,13 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, arguments.configureLanguageVersionSettings(collector));
|
||||
}
|
||||
|
||||
private static final String kotlinHomeEnvVar = System.getenv(KOTLIN_HOME_ENV_VAR);
|
||||
|
||||
@Nullable
|
||||
private static KotlinPaths computeKotlinPaths(@NotNull MessageCollector messageCollector, @NotNull CommonCompilerArguments arguments) {
|
||||
KotlinPaths paths;
|
||||
String kotlinHomeProperty = System.getProperty(KOTLIN_HOME_PROPERTY);
|
||||
File kotlinHome =
|
||||
arguments.getKotlinHome() != null ? new File(arguments.getKotlinHome()) :
|
||||
kotlinHomeProperty != null ? new File(kotlinHomeProperty) :
|
||||
kotlinHomeEnvVar != null ? new File(kotlinHomeEnvVar)
|
||||
kotlinHomeProperty != null ? new File(kotlinHomeProperty)
|
||||
: null;
|
||||
if (kotlinHome != null) {
|
||||
if (kotlinHome.isDirectory()) {
|
||||
|
||||
@@ -135,7 +135,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
"ATTENTION!\n" +
|
||||
"This build uses internal compiler arguments:\n" +
|
||||
arguments.internalArguments.joinToString(prefix = "\n", postfix = "\n\n", separator = "\n") +
|
||||
"This mode is strictly prohibited for production use,\n" +
|
||||
"This mode is not recommended for production use,\n" +
|
||||
"as no stability/compatibility guarantees are given on\n" +
|
||||
"compiler or generated code. Use it at your own risk!\n"
|
||||
)
|
||||
|
||||
@@ -68,7 +68,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.put(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION, true)
|
||||
}
|
||||
|
||||
val pluginLoadResult = loadPlugins(paths, arguments, configuration)
|
||||
val pluginLoadResult = loadPlugins(arguments, configuration)
|
||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
||||
|
||||
if (!arguments.script && arguments.buildFile == null) {
|
||||
@@ -217,13 +217,13 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
override fun getPerformanceManager(): CommonCompilerPerformanceManager = performanceManager
|
||||
|
||||
private fun loadPlugins(paths: KotlinPaths?, arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration): ExitCode {
|
||||
private fun loadPlugins(arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration): ExitCode {
|
||||
var pluginClasspaths: Iterable<String> = arguments.pluginClasspaths?.asIterable() ?: emptyList()
|
||||
val pluginOptions = arguments.pluginOptions?.toMutableList() ?: ArrayList()
|
||||
|
||||
if (!arguments.disableDefaultScriptingPlugin) {
|
||||
val explicitOrLoadedScriptingPlugin =
|
||||
pluginClasspaths.any { File(it).name == PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR } ||
|
||||
pluginClasspaths.any { File(it).name.startsWith(PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME) } ||
|
||||
try {
|
||||
PluginCliParser::class.java.classLoader.loadClass("org.jetbrains.kotlin.extensions.ScriptingCompilerConfigurationExtension")
|
||||
true
|
||||
@@ -233,7 +233,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
// if scripting plugin is not enabled explicitly (probably from another path) and not in the classpath already,
|
||||
// try to find and enable it implicitly
|
||||
if (!explicitOrLoadedScriptingPlugin) {
|
||||
val libPath = paths?.libPath?.takeIf { it.exists() } ?: File(".")
|
||||
val libPath = PathUtil.kotlinPathsForCompiler.libPath.takeIf { it.exists() && it.isDirectory } ?: File(".")
|
||||
with(PathUtil) {
|
||||
val jars = arrayOf(
|
||||
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
||||
@@ -302,7 +302,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
override fun setupPlatformSpecificArgumentsAndServices(
|
||||
configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments, services: Services
|
||||
) {
|
||||
if (IncrementalCompilation.isEnabled()) {
|
||||
if (IncrementalCompilation.isEnabledForJvm()) {
|
||||
services.get(LookupTracker::class.java)?.let {
|
||||
configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it)
|
||||
}
|
||||
|
||||
@@ -183,13 +183,20 @@ class KotlinCoreEnvironment private constructor(
|
||||
JsSyntheticTranslateExtension.registerExtensionPoint(project)
|
||||
CompilerConfigurationExtension.registerExtensionPoint(project)
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
|
||||
try {
|
||||
registrar.registerProjectComponents(project, configuration)
|
||||
} catch (e: AbstractMethodError) {
|
||||
throw IllegalStateException(
|
||||
"The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler", e
|
||||
)
|
||||
val message = "The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler"
|
||||
// Since the scripting plugin is often discovered in the compiler environment, it is often taken from the incompatible
|
||||
// location, and in many cases this is not a fatal error, therefore strong warning is generated instead of exception
|
||||
if (registrar.javaClass.simpleName == "ScriptingCompilerConfigurationComponentRegistrar") {
|
||||
messageCollector?.report(STRONG_WARNING, "Default scripting plugin is disabled: $message")
|
||||
} else {
|
||||
throw IllegalStateException(message, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +207,6 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
registerProjectServicesForCLI(projectEnvironment)
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
registerProjectServices(projectEnvironment, messageCollector)
|
||||
|
||||
for (extension in CompilerConfigurationExtension.getInstances(project)) {
|
||||
@@ -212,6 +218,13 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
// If not disabled explicitly, we should always support at least the standard script definition
|
||||
if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) &&
|
||||
StandardScriptDefinition !in configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS)
|
||||
) {
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
|
||||
}
|
||||
|
||||
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? CliScriptDefinitionProvider
|
||||
if (scriptDefinitionProvider != null) {
|
||||
scriptDefinitionProvider.setScriptDefinitionsSources(configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS_SOURCES))
|
||||
@@ -416,12 +429,6 @@ class KotlinCoreEnvironment private constructor(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles
|
||||
): KotlinCoreEnvironment {
|
||||
setCompatibleBuild()
|
||||
// If not disabled explicitly, we should always support at least the standard script definition
|
||||
if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) &&
|
||||
StandardScriptDefinition !in configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS)
|
||||
) {
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
|
||||
}
|
||||
val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration)
|
||||
// Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally
|
||||
// breaks a lot of tests, therefore it is disabled for production and enabled for tests
|
||||
@@ -458,12 +465,6 @@ class KotlinCoreEnvironment private constructor(
|
||||
parentDisposable: Disposable, initialConfiguration: CompilerConfiguration, extensionConfigs: EnvironmentConfigFiles
|
||||
): KotlinCoreEnvironment {
|
||||
val configuration = initialConfiguration.copy()
|
||||
// in tests we assume that standard definition should only be added if no other explicit defs are already added
|
||||
if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) &&
|
||||
configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS).isEmpty()
|
||||
) {
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
|
||||
}
|
||||
// Tests are supposed to create a single project and dispose it right after use
|
||||
return KotlinCoreEnvironment(
|
||||
parentDisposable,
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.daemon.report.CompileServicesFacadeMessageCollector
|
||||
@@ -469,7 +470,7 @@ class CompileServiceImpl(
|
||||
}
|
||||
|
||||
val workingDir = incrementalCompilationOptions.workingDir
|
||||
val versions = commonCacheVersions(workingDir) +
|
||||
val versions = commonCacheVersions(workingDir, enabled = true) +
|
||||
customCacheVersion(incrementalCompilationOptions.customCacheVersion,
|
||||
incrementalCompilationOptions.customCacheVersionFileName,
|
||||
workingDir,
|
||||
@@ -519,7 +520,7 @@ class CompileServiceImpl(
|
||||
}
|
||||
|
||||
val workingDir = incrementalCompilationOptions.workingDir
|
||||
val versions = commonCacheVersions(workingDir) +
|
||||
val versions = commonCacheVersions(workingDir, enabled = true) +
|
||||
customCacheVersion(incrementalCompilationOptions.customCacheVersion,
|
||||
incrementalCompilationOptions.customCacheVersionFileName,
|
||||
workingDir,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ public class SingleAbstractMethodUtils {
|
||||
// Otherwise android data binding can cause resolve re-entrance
|
||||
// For details see KT-18687, KT-16149
|
||||
// TODO: prevent resolve re-entrance on architecture level, or (alternatively) ask data binding owners not to do it
|
||||
if (DescriptorUtilsKt.getFqNameSafe(klass).asString().equals("android.databinding.DataBindingComponent")) {
|
||||
if (DescriptorUtilsKt.getFqNameSafe(klass).asString().endsWith(".databinding.DataBindingComponent")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||
c.expectedType,
|
||||
{ c.dataFlowValueFactory.createDataFlowValue(expression, expressionType, c) } ,
|
||||
c.dataFlowInfo
|
||||
) { expectedMustNotBeNull, actualMayBeNull ->
|
||||
c.trace.report(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(expression, expectedMustNotBeNull, actualMayBeNull))
|
||||
) { expectedType, actualType ->
|
||||
c.trace.report(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(expression, expectedType, actualType))
|
||||
}
|
||||
|
||||
when (expression) {
|
||||
@@ -121,12 +121,15 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||
receiverParameter.type,
|
||||
{ dataFlowValue },
|
||||
c.dataFlowInfo
|
||||
) { expectedMustNotBeNull,
|
||||
actualMayBeNull ->
|
||||
val reportOn = (receiverArgument as? ExpressionReceiver)?.expression ?: (c.call.calleeExpression ?: c.call.callElement)
|
||||
c.trace.report(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(
|
||||
reportOn, expectedMustNotBeNull, actualMayBeNull
|
||||
))
|
||||
) { expectedType,
|
||||
actualType ->
|
||||
val receiverExpression = (receiverArgument as? ExpressionReceiver)?.expression
|
||||
if (receiverExpression != null) {
|
||||
c.trace.report(ErrorsJvm.RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(receiverExpression, actualType))
|
||||
} else {
|
||||
val reportOn = c.call.calleeExpression ?: c.call.callElement
|
||||
c.trace.report(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(reportOn, expectedType, actualType))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,22 +138,21 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||
expectedType: KotlinType,
|
||||
dataFlowValue: () -> DataFlowValue,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
reportWarning: (expectedMustNotBeNull: ErrorsJvm.NullabilityInformationSource, actualMayBeNull: ErrorsJvm.NullabilityInformationSource) -> Unit
|
||||
reportWarning: (expectedType: KotlinType, actualType: KotlinType) -> Unit
|
||||
) {
|
||||
if (TypeUtils.noExpectedType(expectedType)) {
|
||||
return
|
||||
}
|
||||
|
||||
val expectedMustNotBeNull = expectedType.mustNotBeNull()
|
||||
val actualMayBeNull = expressionType.mayBeNull()
|
||||
if (expectedMustNotBeNull == ErrorsJvm.NullabilityInformationSource.KOTLIN && actualMayBeNull == ErrorsJvm.NullabilityInformationSource.KOTLIN) {
|
||||
val expectedMustNotBeNull = expectedType.mustNotBeNull() ?: return
|
||||
val actualMayBeNull = expressionType.mayBeNull() ?: return
|
||||
if (expectedMustNotBeNull.isFromKotlin && actualMayBeNull.isFromKotlin) {
|
||||
// a type mismatch error will be reported elsewhere
|
||||
return
|
||||
}
|
||||
|
||||
if (expectedMustNotBeNull != null && actualMayBeNull != null &&
|
||||
dataFlowInfo.getStableNullability(dataFlowValue()) != Nullability.NOT_NULL) {
|
||||
reportWarning(expectedMustNotBeNull, actualMayBeNull)
|
||||
if (dataFlowInfo.getStableNullability(dataFlowValue()) != Nullability.NOT_NULL) {
|
||||
reportWarning(expectedMustNotBeNull.enhancedType, actualMayBeNull.enhancedType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,23 +161,30 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||
dataFlowValue: () -> DataFlowValue,
|
||||
c: ResolutionContext<*>,
|
||||
body: () -> T
|
||||
) = if (type.mustNotBeNull() == ErrorsJvm.NullabilityInformationSource.JAVA &&
|
||||
) = if (type.mustNotBeNull()?.isFromJava == true &&
|
||||
c.dataFlowInfo.getStableNullability(dataFlowValue()).canBeNull())
|
||||
body()
|
||||
else
|
||||
null
|
||||
|
||||
private fun KotlinType.mustNotBeNull(): ErrorsJvm.NullabilityInformationSource? = when {
|
||||
!isError && !isFlexible() && !TypeUtils.acceptsNullable(this) -> ErrorsJvm.NullabilityInformationSource.KOTLIN
|
||||
isFlexible() && !TypeUtils.acceptsNullable(asFlexibleType().upperBound) -> ErrorsJvm.NullabilityInformationSource.KOTLIN
|
||||
this is TypeWithEnhancement && enhancement.mustNotBeNull() != null -> ErrorsJvm.NullabilityInformationSource.JAVA
|
||||
private class EnhancedNullabilityInfo(val enhancedType: KotlinType, val isFromJava: Boolean) {
|
||||
val isFromKotlin get() = !isFromJava
|
||||
}
|
||||
|
||||
private fun KotlinType.enhancementFromKotlin() = EnhancedNullabilityInfo(this, isFromJava = false)
|
||||
private fun TypeWithEnhancement.enhancementFromJava() = EnhancedNullabilityInfo(enhancement, isFromJava = true)
|
||||
|
||||
private fun KotlinType.mustNotBeNull(): EnhancedNullabilityInfo? = when {
|
||||
!isError && !isFlexible() && !TypeUtils.acceptsNullable(this) -> enhancementFromKotlin()
|
||||
isFlexible() && !TypeUtils.acceptsNullable(asFlexibleType().upperBound) -> enhancementFromKotlin()
|
||||
this is TypeWithEnhancement && enhancement.mustNotBeNull() != null -> enhancementFromJava()
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun KotlinType.mayBeNull(): ErrorsJvm.NullabilityInformationSource? = when {
|
||||
!isError && !isFlexible() && TypeUtils.acceptsNullable(this) -> ErrorsJvm.NullabilityInformationSource.KOTLIN
|
||||
isFlexible() && TypeUtils.acceptsNullable(asFlexibleType().lowerBound) -> ErrorsJvm.NullabilityInformationSource.KOTLIN
|
||||
this is TypeWithEnhancement && enhancement.mayBeNull() != null -> ErrorsJvm.NullabilityInformationSource.JAVA
|
||||
private fun KotlinType.mayBeNull(): EnhancedNullabilityInfo? = when {
|
||||
!isError && !isFlexible() && TypeUtils.acceptsNullable(this) -> enhancementFromKotlin()
|
||||
isFlexible() && TypeUtils.acceptsNullable(asFlexibleType().lowerBound) -> enhancementFromKotlin()
|
||||
this is TypeWithEnhancement && enhancement.mayBeNull() != null -> enhancementFromJava()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +87,10 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER, "Interfaces can call default methods via super only within @JvmDefault members. Please annotate the containing interface member with @JvmDefault");
|
||||
MAP.put(SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC, "Using non-JVM static members protected in the superclass companion is unsupported yet");
|
||||
|
||||
MAP.put(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS,
|
||||
"Expected type does not accept nulls in {0}, but the value may be null in {1}", Renderers.TO_STRING, Renderers.TO_STRING);
|
||||
MAP.put(NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS, "Type mismatch: inferred type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE);
|
||||
MAP.put(RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS,
|
||||
"Unsafe use of a nullable receiver of type {0}", RENDER_TYPE);
|
||||
|
||||
MAP.put(WHEN_ENUM_CAN_BE_NULL_IN_JAVA, "Enum argument can be null in Java, but exhaustive when contains no null branch");
|
||||
|
||||
MAP.put(JAVA_CLASS_ON_COMPANION,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.jvm.diagnostics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -123,26 +122,12 @@ public interface ErrorsJvm {
|
||||
|
||||
DiagnosticFactory0<KtDeclaration> NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
|
||||
enum NullabilityInformationSource {
|
||||
KOTLIN {
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Kotlin";
|
||||
}
|
||||
},
|
||||
JAVA {
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Java";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DiagnosticFactory2<KtElement, NullabilityInformationSource, NullabilityInformationSource> NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
||||
DiagnosticFactory2<KtElement, KotlinType, KotlinType> NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
||||
= DiagnosticFactory2.create(WARNING);
|
||||
|
||||
DiagnosticFactory1<KtElement, KotlinType> RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
||||
= DiagnosticFactory1.create(WARNING);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
Object _initializer = new Object() {
|
||||
{
|
||||
|
||||
@@ -58,31 +58,50 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
|
||||
val classDescriptorOwner = getterOrSetter.containingDeclaration as? ClassDescriptor ?: return null
|
||||
|
||||
val originalGetterOrSetter = getterOrSetter.original
|
||||
return syntheticScopes.collectSyntheticExtensionProperties(listOf(classDescriptorOwner.defaultType))
|
||||
.filterIsInstance<SyntheticJavaPropertyDescriptor>()
|
||||
.firstOrNull { originalGetterOrSetter == it.getMethod || originalGetterOrSetter == it.setMethod }
|
||||
|
||||
val names = propertyNamesByAccessorName(name)
|
||||
|
||||
return names
|
||||
.flatMap {
|
||||
syntheticScopes.collectSyntheticExtensionProperties(
|
||||
listOf(classDescriptorOwner.defaultType),
|
||||
it,
|
||||
NoLookupLocation.FROM_SYNTHETIC_SCOPE
|
||||
)
|
||||
}.filterIsInstance<SyntheticJavaPropertyDescriptor>()
|
||||
.firstOrNull { originalGetterOrSetter == it.getMethod || originalGetterOrSetter == it.setMethod }
|
||||
}
|
||||
|
||||
fun propertyNamesByAccessorName(name: Name): List<Name> = listOfNotNull(
|
||||
propertyNameByGetMethodName(name),
|
||||
propertyNameBySetMethodName(name, withIsPrefix = true),
|
||||
propertyNameBySetMethodName(name, withIsPrefix = false)
|
||||
)
|
||||
|
||||
fun findByGetterOrSetter(getterOrSetter: FunctionDescriptor, syntheticScope: SyntheticScope) =
|
||||
findByGetterOrSetter(getterOrSetter,
|
||||
object : SyntheticScopes {
|
||||
override val scopes: Collection<SyntheticScope> = listOf(syntheticScope)
|
||||
})
|
||||
findByGetterOrSetter(getterOrSetter,
|
||||
object : SyntheticScopes {
|
||||
override val scopes: Collection<SyntheticScope> = listOf(syntheticScope)
|
||||
})
|
||||
|
||||
fun propertyNameByGetMethodName(methodName: Name): Name?
|
||||
= org.jetbrains.kotlin.load.java.propertyNameByGetMethodName(methodName)
|
||||
fun propertyNameByGetMethodName(methodName: Name): Name? = org.jetbrains.kotlin.load.java.propertyNameByGetMethodName(methodName)
|
||||
|
||||
fun propertyNameBySetMethodName(methodName: Name, withIsPrefix: Boolean): Name?
|
||||
= org.jetbrains.kotlin.load.java.propertyNameBySetMethodName(methodName, withIsPrefix)
|
||||
fun propertyNameBySetMethodName(methodName: Name, withIsPrefix: Boolean): Name? =
|
||||
org.jetbrains.kotlin.load.java.propertyNameBySetMethodName(methodName, withIsPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val lookupTracker: LookupTracker) : SyntheticScope {
|
||||
private val syntheticPropertyInClass = storageManager.createMemoizedFunction<Pair<ClassDescriptor, Name>, SyntheticPropertyHolder> { pair ->
|
||||
syntheticPropertyInClassNotCached(pair.first, pair.second)
|
||||
}
|
||||
private val syntheticPropertyInClass =
|
||||
storageManager.createMemoizedFunction<Pair<ClassDescriptor, Name>, SyntheticPropertyHolder> { pair ->
|
||||
syntheticPropertyInClassNotCached(pair.first, pair.second)
|
||||
}
|
||||
|
||||
private fun getSyntheticPropertyAndRecordLookups(classifier: ClassDescriptor, name: Name, location: LookupLocation): PropertyDescriptor? {
|
||||
private fun getSyntheticPropertyAndRecordLookups(
|
||||
classifier: ClassDescriptor,
|
||||
name: Name,
|
||||
location: LookupLocation
|
||||
): PropertyDescriptor? {
|
||||
val (descriptor, lookedNames) = syntheticPropertyInClass(Pair(classifier, name))
|
||||
|
||||
if (location !is NoLookupLocation) {
|
||||
@@ -119,15 +138,15 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
|
||||
val possibleGetMethodNames = possibleGetMethodNames(name)
|
||||
val getMethod = possibleGetMethodNames
|
||||
.flatMap { memberScope.getContributedFunctions(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE) }
|
||||
.singleOrNull {
|
||||
it.hasJavaOriginInHierarchy() && isGoodGetMethod(it)
|
||||
} ?: return result(null, possibleGetMethodNames)
|
||||
.flatMap { memberScope.getContributedFunctions(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE) }
|
||||
.singleOrNull {
|
||||
it.hasJavaOriginInHierarchy() && isGoodGetMethod(it)
|
||||
} ?: return result(null, possibleGetMethodNames)
|
||||
|
||||
|
||||
val setMethodName = setMethodName(getMethod.name)
|
||||
val setMethod = memberScope.getContributedFunctions(setMethodName, NoLookupLocation.FROM_SYNTHETIC_SCOPE)
|
||||
.singleOrNull { isGoodSetMethod(it, getMethod) }
|
||||
.singleOrNull { isGoodSetMethod(it, getMethod) }
|
||||
|
||||
val propertyType = getMethod.returnType!!
|
||||
|
||||
@@ -140,8 +159,8 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
if (returnType.isUnit()) return false
|
||||
|
||||
return descriptor.valueParameters.isEmpty()
|
||||
&& descriptor.typeParameters.isEmpty()
|
||||
&& descriptor.visibility.isVisibleOutside()
|
||||
&& descriptor.typeParameters.isEmpty()
|
||||
&& descriptor.visibility.isVisibleOutside()
|
||||
}
|
||||
|
||||
private fun isGoodSetMethod(descriptor: FunctionDescriptor, getMethod: FunctionDescriptor): Boolean {
|
||||
@@ -150,14 +169,14 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
if (!TypeUtils.equalTypes(parameter.type, propertyType)) {
|
||||
if (!propertyType.isSubtypeOf(parameter.type)) return false
|
||||
if (descriptor.findOverridden {
|
||||
val baseProperty = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(it, this)
|
||||
baseProperty?.getMethod?.name == getMethod.name
|
||||
} == null) return false
|
||||
val baseProperty = SyntheticJavaPropertyDescriptor.findByGetterOrSetter(it, this)
|
||||
baseProperty?.getMethod?.name == getMethod.name
|
||||
} == null) return false
|
||||
}
|
||||
|
||||
return parameter.varargElementType == null
|
||||
&& descriptor.typeParameters.isEmpty()
|
||||
&& descriptor.visibility.isVisibleOutside()
|
||||
&& descriptor.typeParameters.isEmpty()
|
||||
&& descriptor.visibility.isVisibleOutside()
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.findOverridden(condition: (FunctionDescriptor) -> Boolean): FunctionDescriptor? {
|
||||
@@ -168,7 +187,11 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
|
||||
override fun getSyntheticExtensionProperties(
|
||||
receiverTypes: Collection<KotlinType>,
|
||||
name: Name,
|
||||
location: LookupLocation
|
||||
): Collection<PropertyDescriptor> {
|
||||
var result: SmartList<PropertyDescriptor>? = null
|
||||
val processedTypes: MutableSet<TypeConstructor>? = if (receiverTypes.size > 1) HashSet<TypeConstructor>() else null
|
||||
for (type in receiverTypes) {
|
||||
@@ -181,22 +204,25 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor>
|
||||
= emptyList()
|
||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> =
|
||||
emptyList()
|
||||
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor>
|
||||
= emptyList()
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> =
|
||||
emptyList()
|
||||
|
||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor>
|
||||
= emptyList()
|
||||
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> = emptyList()
|
||||
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor>
|
||||
= emptyList()
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> = emptyList()
|
||||
|
||||
override fun getSyntheticConstructor(constructor: ConstructorDescriptor): ConstructorDescriptor?
|
||||
= null
|
||||
override fun getSyntheticConstructor(constructor: ConstructorDescriptor): ConstructorDescriptor? = null
|
||||
|
||||
private fun collectSyntheticPropertiesByName(result: SmartList<PropertyDescriptor>?, type: TypeConstructor, name: Name, processedTypes: MutableSet<TypeConstructor>?, location: LookupLocation): SmartList<PropertyDescriptor>? {
|
||||
private fun collectSyntheticPropertiesByName(
|
||||
result: SmartList<PropertyDescriptor>?,
|
||||
type: TypeConstructor,
|
||||
name: Name,
|
||||
processedTypes: MutableSet<TypeConstructor>?,
|
||||
location: LookupLocation
|
||||
): SmartList<PropertyDescriptor>? {
|
||||
if (processedTypes != null && !processedTypes.add(type)) return result
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
@@ -205,8 +231,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
val classifier = type.declarationDescriptor
|
||||
if (classifier is ClassDescriptor) {
|
||||
result = result.add(getSyntheticPropertyAndRecordLookups(classifier, name, location))
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
type.supertypes.forEach { result = collectSyntheticPropertiesByName(result, it.constructor, name, processedTypes, location) }
|
||||
}
|
||||
|
||||
@@ -220,7 +245,10 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return result
|
||||
}
|
||||
|
||||
private fun MutableList<PropertyDescriptor>.collectSyntheticProperties(type: TypeConstructor, processedTypes: MutableSet<TypeConstructor>) {
|
||||
private fun MutableList<PropertyDescriptor>.collectSyntheticProperties(
|
||||
type: TypeConstructor,
|
||||
processedTypes: MutableSet<TypeConstructor>
|
||||
) {
|
||||
if (!processedTypes.add(type)) return
|
||||
|
||||
val classifier = type.declarationDescriptor
|
||||
@@ -231,8 +259,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
addIfNotNull(syntheticPropertyInClass(Pair(classifier, propertyName)).descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
type.supertypes.forEach { collectSyntheticProperties(it.constructor, processedTypes) }
|
||||
}
|
||||
}
|
||||
@@ -244,7 +271,12 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return list
|
||||
}
|
||||
|
||||
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptyList()
|
||||
override fun getSyntheticMemberFunctions(
|
||||
receiverTypes: Collection<KotlinType>,
|
||||
name: Name,
|
||||
location: LookupLocation
|
||||
): Collection<FunctionDescriptor> = emptyList()
|
||||
|
||||
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> = emptyList()
|
||||
|
||||
private data class SyntheticPropertyHolder(val descriptor: PropertyDescriptor?, val lookedNames: List<Name>) {
|
||||
@@ -254,19 +286,19 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
}
|
||||
|
||||
private class MyPropertyDescriptor(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
original: PropertyDescriptor?,
|
||||
annotations: Annotations,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
isVar: Boolean,
|
||||
name: Name,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
source: SourceElement
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
original: PropertyDescriptor?,
|
||||
annotations: Annotations,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
isVar: Boolean,
|
||||
name: Name,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
source: SourceElement
|
||||
) : SyntheticJavaPropertyDescriptor, PropertyDescriptorImpl(
|
||||
containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, source,
|
||||
/* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false,
|
||||
/* isDelegated = */ false
|
||||
containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, source,
|
||||
/* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false,
|
||||
/* isDelegated = */ false
|
||||
) {
|
||||
|
||||
override var getMethod: FunctionDescriptor by Delegates.notNull()
|
||||
@@ -276,51 +308,64 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
private set
|
||||
|
||||
companion object {
|
||||
fun create(ownerClass: ClassDescriptor, getMethod: FunctionDescriptor, setMethod: FunctionDescriptor?, name: Name, type: KotlinType): MyPropertyDescriptor {
|
||||
fun create(
|
||||
ownerClass: ClassDescriptor,
|
||||
getMethod: FunctionDescriptor,
|
||||
setMethod: FunctionDescriptor?,
|
||||
name: Name,
|
||||
type: KotlinType
|
||||
): MyPropertyDescriptor {
|
||||
val visibility = syntheticVisibility(getMethod, isUsedForExtension = true)
|
||||
val descriptor = MyPropertyDescriptor(DescriptorUtils.getContainingModule(ownerClass),
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
visibility,
|
||||
setMethod != null,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE)
|
||||
val descriptor = MyPropertyDescriptor(
|
||||
DescriptorUtils.getContainingModule(ownerClass),
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
visibility,
|
||||
setMethod != null,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
descriptor.getMethod = getMethod
|
||||
descriptor.setMethod = setMethod
|
||||
|
||||
val classTypeParams = ownerClass.typeConstructor.parameters
|
||||
val typeParameters = ArrayList<TypeParameterDescriptor>(classTypeParams.size)
|
||||
val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(classTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters)
|
||||
val typeSubstitutor =
|
||||
DescriptorSubstitutor.substituteTypeParameters(classTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters)
|
||||
|
||||
val propertyType = typeSubstitutor.safeSubstitute(type, Variance.INVARIANT)
|
||||
val receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
|
||||
descriptor.setType(propertyType, typeParameters, null, receiverType)
|
||||
|
||||
val getter = PropertyGetterDescriptorImpl(descriptor,
|
||||
getMethod.annotations,
|
||||
Modality.FINAL,
|
||||
visibility,
|
||||
false,
|
||||
getMethod.isExternal,
|
||||
false,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
null,
|
||||
SourceElement.NO_SOURCE)
|
||||
val getter = PropertyGetterDescriptorImpl(
|
||||
descriptor,
|
||||
getMethod.annotations,
|
||||
Modality.FINAL,
|
||||
visibility,
|
||||
false,
|
||||
getMethod.isExternal,
|
||||
false,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
null,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
getter.initialize(null)
|
||||
|
||||
val setter = if (setMethod != null)
|
||||
PropertySetterDescriptorImpl(descriptor,
|
||||
setMethod.annotations,
|
||||
Modality.FINAL,
|
||||
syntheticVisibility(setMethod, isUsedForExtension = true),
|
||||
false,
|
||||
setMethod.isExternal,
|
||||
false,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
null,
|
||||
SourceElement.NO_SOURCE)
|
||||
PropertySetterDescriptorImpl(
|
||||
descriptor,
|
||||
setMethod.annotations,
|
||||
Modality.FINAL,
|
||||
syntheticVisibility(setMethod, isUsedForExtension = true),
|
||||
false,
|
||||
setMethod.isExternal,
|
||||
false,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
null,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
else
|
||||
null
|
||||
setter?.initializeDefault()
|
||||
@@ -332,12 +377,12 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
}
|
||||
|
||||
override fun createSubstitutedCopy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
newModality: Modality,
|
||||
newVisibility: Visibility,
|
||||
original: PropertyDescriptor?,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
newName: Name
|
||||
newOwner: DeclarationDescriptor,
|
||||
newModality: Modality,
|
||||
newVisibility: Visibility,
|
||||
original: PropertyDescriptor?,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
newName: Name
|
||||
): PropertyDescriptorImpl {
|
||||
return MyPropertyDescriptor(newOwner, this, annotations, newModality, newVisibility, isVar, newName, kind, source).apply {
|
||||
getMethod = this@MyPropertyDescriptor.getMethod
|
||||
@@ -357,8 +402,8 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
|
||||
}
|
||||
val classParametersSubstitutor = TypeConstructorSubstitution.createByConstructorsMap(
|
||||
substitutionMap,
|
||||
approximateCapturedTypes = true
|
||||
substitutionMap,
|
||||
approximateCapturedTypes = true
|
||||
).buildSubstitutor()
|
||||
|
||||
descriptor.getMethod = getMethod.substitute(classParametersSubstitutor) ?: return null
|
||||
|
||||
@@ -20,10 +20,9 @@ import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.findNonGenericClassAcrossDependencies
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.script.classId
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import kotlin.reflect.KClass
|
||||
@@ -33,19 +32,15 @@ import kotlin.reflect.KVariance
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
fun KotlinScriptDefinition.getScriptParameters(scriptDescriptor: ScriptDescriptor): List<ScriptParameter> =
|
||||
template.primaryConstructor?.parameters
|
||||
?.map { ScriptParameter(Name.identifier(it.name!!), getKotlinTypeByKType(scriptDescriptor, it.type)) }
|
||||
?: emptyList()
|
||||
template.primaryConstructor?.parameters
|
||||
?.map { ScriptParameter(Name.identifier(it.name!!), getKotlinTypeByKType(scriptDescriptor, it.type)) }
|
||||
?: emptyList()
|
||||
|
||||
fun getKotlinTypeByKClass(scriptDescriptor: ScriptDescriptor, kClass: KClass<out Any>): KotlinType =
|
||||
getKotlinTypeByFqName(scriptDescriptor,
|
||||
kClass.qualifiedName ?: throw RuntimeException("Cannot get FQN from $kClass"))
|
||||
|
||||
private fun getKotlinTypeByFqName(scriptDescriptor: ScriptDescriptor, fqName: String): KotlinType =
|
||||
scriptDescriptor.module.findNonGenericClassAcrossDependencies(
|
||||
ClassId.topLevel(FqName(fqName)),
|
||||
NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module)
|
||||
).defaultType
|
||||
scriptDescriptor.module.findNonGenericClassAcrossDependencies(
|
||||
kClass.classId,
|
||||
NotFoundClasses(LockBasedStorageManager.NO_LOCKS, scriptDescriptor.module)
|
||||
).defaultType
|
||||
|
||||
// TODO: support star projections
|
||||
// TODO: support annotations on types and type parameters
|
||||
|
||||
@@ -98,6 +98,7 @@ public interface Errors {
|
||||
DiagnosticFactory2<PsiElement, String, String> API_NOT_AVAILABLE = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, FqName> MISSING_DEPENDENCY_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> MISSING_SCRIPT_BASE_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> MISSING_SCRIPT_RECEIVER_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> MISSING_SCRIPT_ENVIRONMENT_PROPERTY_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> PRE_RELEASE_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
@@ -357,6 +357,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(API_NOT_AVAILABLE, "This declaration is only available since Kotlin {0} and cannot be used with the specified API version {1}", STRING, STRING);
|
||||
|
||||
MAP.put(MISSING_DEPENDENCY_CLASS, "Cannot access class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING);
|
||||
MAP.put(MISSING_SCRIPT_BASE_CLASS, "Cannot access script base class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING);
|
||||
MAP.put(MISSING_SCRIPT_RECEIVER_CLASS, "Cannot access implicit script receiver class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING);
|
||||
MAP.put(MISSING_SCRIPT_ENVIRONMENT_PROPERTY_CLASS, "Cannot access script environment property class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING);
|
||||
MAP.put(PRE_RELEASE_CLASS, "{0} is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler", TO_STRING);
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -596,6 +597,8 @@ internal fun reportResolvedUsingDeprecatedVisibility(
|
||||
val descriptorToLookup: DeclarationDescriptor = when (candidateDescriptor) {
|
||||
is ClassConstructorDescriptor -> candidateDescriptor.containingDeclaration
|
||||
is FakeCallableDescriptorForObject -> candidateDescriptor.classDescriptor
|
||||
is SyntheticMemberDescriptor<*> -> candidateDescriptor.baseDescriptorForSynthetic
|
||||
is PropertyDescriptor, is FunctionDescriptor -> candidateDescriptor
|
||||
else -> error(
|
||||
"Unexpected candidate descriptor of resolved call with " +
|
||||
"ResolvedUsingDeprecatedVisibility-diagnostic: $candidateDescriptor\n" +
|
||||
|
||||
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.DeprecationResolver
|
||||
@@ -62,7 +63,19 @@ fun checkClassifierUsages(
|
||||
}
|
||||
}
|
||||
|
||||
private fun runCheckersWithTarget(target: ClassifierDescriptor, expression: KtReferenceExpression) {
|
||||
override fun visitFunctionType(type: KtFunctionType) {
|
||||
super.visitFunctionType(type)
|
||||
|
||||
val kotlinType = context.trace.get(BindingContext.TYPE, type.parent as? KtTypeReference ?: return)
|
||||
if (kotlinType != null) {
|
||||
val descriptor = kotlinType.constructor.declarationDescriptor
|
||||
if (descriptor is ClassifierDescriptor) {
|
||||
runCheckersWithTarget(descriptor, type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runCheckersWithTarget(target: ClassifierDescriptor, expression: KtElement) {
|
||||
for (checker in checkers) {
|
||||
checker.check(target, expression, context)
|
||||
}
|
||||
|
||||
@@ -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>) {
|
||||
|
||||
@@ -22,9 +22,11 @@ import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.script.ScriptHelper
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
|
||||
class LazyScriptClassMemberScope(
|
||||
resolveSession: ResolveSession,
|
||||
@@ -33,34 +35,67 @@ class LazyScriptClassMemberScope(
|
||||
trace: BindingTrace
|
||||
) : LazyClassMemberScope(resolveSession, declarationProvider, scriptDescriptor, trace) {
|
||||
|
||||
override fun resolvePrimaryConstructor(): ClassConstructorDescriptor? {
|
||||
val constructor = ClassConstructorDescriptorImpl.create(
|
||||
scriptDescriptor,
|
||||
Annotations.EMPTY,
|
||||
true,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
constructor.initialize(
|
||||
createScriptParameters(constructor),
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
setDeferredReturnType(constructor)
|
||||
return constructor
|
||||
private val scriptPrimaryConstructor: () -> ClassConstructorDescriptorImpl? = resolveSession.storageManager.createNullableLazyValue {
|
||||
val baseClass = scriptDescriptor.baseClassDescriptor()
|
||||
val baseConstructorDescriptor = baseClass?.unsubstitutedPrimaryConstructor
|
||||
if (baseConstructorDescriptor != null) {
|
||||
val builtIns = scriptDescriptor.builtIns
|
||||
val implicitReceiversParamType =
|
||||
if (scriptDescriptor.scriptDefinition().implicitReceivers.isEmpty()) null
|
||||
else {
|
||||
"implicitReceivers" to builtIns.array.substitute(builtIns.anyType)!!
|
||||
}
|
||||
val environmentVarsParamType =
|
||||
if (scriptDescriptor.scriptDefinition().environmentVariables.isEmpty()) null
|
||||
else {
|
||||
"environmentVariables" to builtIns.map.substitute(builtIns.stringType, builtIns.nullableAnyType)!!
|
||||
}
|
||||
val annotations = baseConstructorDescriptor.annotations
|
||||
val constructorDescriptor = ClassConstructorDescriptorImpl.create(
|
||||
scriptDescriptor, annotations, baseConstructorDescriptor.isPrimary, scriptDescriptor.source
|
||||
)
|
||||
var paramsIndexBase = baseConstructorDescriptor.valueParameters.lastIndex + 1
|
||||
val syntheticParameters =
|
||||
listOf(implicitReceiversParamType, environmentVarsParamType).mapNotNull { param: Pair<String, KotlinType>? ->
|
||||
if (param == null) null
|
||||
else ValueParameterDescriptorImpl(
|
||||
constructorDescriptor,
|
||||
null,
|
||||
paramsIndexBase++,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(param.first),
|
||||
param.second,
|
||||
false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
}
|
||||
val parameters = baseConstructorDescriptor.valueParameters.map { it.copy(constructorDescriptor, it.name, it.index) } +
|
||||
syntheticParameters
|
||||
constructorDescriptor.initialize(parameters, baseConstructorDescriptor.visibility)
|
||||
constructorDescriptor.returnType = scriptDescriptor.defaultType
|
||||
constructorDescriptor
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createScriptParameters(constructor: ClassConstructorDescriptorImpl): List<ValueParameterDescriptor> {
|
||||
return ScriptHelper.getInstance().getScriptParameters(scriptDescriptor.scriptDefinition, scriptDescriptor)
|
||||
.mapIndexed { index, (name, type) ->
|
||||
ValueParameterDescriptorImpl(
|
||||
constructor, null, index, Annotations.EMPTY, name, type,
|
||||
/* declaresDefaultValue = */ false,
|
||||
/* isCrossinline = */ false,
|
||||
/* isNoinline = */ false,
|
||||
null, SourceElement.NO_SOURCE
|
||||
override fun resolvePrimaryConstructor(): ClassConstructorDescriptor? {
|
||||
val constructor = scriptPrimaryConstructor()
|
||||
?: ClassConstructorDescriptorImpl.create(
|
||||
scriptDescriptor,
|
||||
Annotations.EMPTY,
|
||||
true,
|
||||
SourceElement.NO_SOURCE
|
||||
).initialize(
|
||||
emptyList(),
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
}
|
||||
setDeferredReturnType(constructor)
|
||||
return constructor
|
||||
}
|
||||
|
||||
override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<PropertyDescriptor>) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassDescriptor.substitute(vararg types: KotlinType): KotlinType? =
|
||||
KotlinTypeFactory.simpleType(this.defaultType, arguments = types.map { it.asTypeProjection() })
|
||||
|
||||
@@ -18,10 +18,10 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
@@ -31,14 +31,15 @@ import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.script.ScriptEnvironmentDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.script.classId
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.script.ScriptHelper
|
||||
import org.jetbrains.kotlin.script.ScriptPriorities
|
||||
import org.jetbrains.kotlin.script.getScriptDefinition
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
@@ -66,11 +67,10 @@ class LazyScriptDescriptor(
|
||||
|
||||
override fun getPriority() = priority
|
||||
|
||||
val scriptDefinition: KotlinScriptDefinition
|
||||
by lazy {
|
||||
val file = scriptInfo.script.containingKtFile
|
||||
getScriptDefinition(file) ?: throw RuntimeException("file ${file.name} is not a script")
|
||||
}
|
||||
val scriptDefinition: () -> KotlinScriptDefinition = resolveSession.storageManager.createLazyValue {
|
||||
val file = scriptInfo.script.containingKtFile
|
||||
getScriptDefinition(file) ?: throw RuntimeException("file ${file.name} is not a script")
|
||||
}
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor) = this
|
||||
|
||||
@@ -88,28 +88,39 @@ class LazyScriptDescriptor(
|
||||
|
||||
override fun getUnsubstitutedPrimaryConstructor() = super.getUnsubstitutedPrimaryConstructor()!!
|
||||
|
||||
override fun computeSupertypes() =
|
||||
listOf(ScriptHelper.getInstance().getKotlinType(this, scriptDefinition.template)).ifEmpty { listOf(builtIns.anyType) }
|
||||
internal val baseClassDescriptor: () -> ClassDescriptor? = resolveSession.storageManager.createNullableLazyValue {
|
||||
findTypeDescriptor(scriptDefinition().template, Errors.MISSING_SCRIPT_BASE_CLASS)
|
||||
}
|
||||
|
||||
override fun computeSupertypes() = listOf(baseClassDescriptor()?.defaultType ?: builtIns.anyType)
|
||||
|
||||
private val scriptImplicitReceivers: () -> List<ClassDescriptor> = resolveSession.storageManager.createLazyValue {
|
||||
scriptDefinition.implicitReceivers.mapNotNull { receiver ->
|
||||
scriptDefinition().implicitReceivers.mapNotNull { receiver ->
|
||||
findTypeDescriptor(receiver, Errors.MISSING_SCRIPT_RECEIVER_CLASS)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun findTypeDescriptor(type: KType, errorDiagnostic: DiagnosticFactory1<PsiElement, String>): ClassDescriptor? {
|
||||
val receiverClassId = type.classId
|
||||
return receiverClassId?.let {
|
||||
module.findClassAcrossModuleDependencies(it)
|
||||
} ?: also {
|
||||
internal fun findTypeDescriptor(kClass: KClass<*>, errorDiagnostic: DiagnosticFactory1<PsiElement, String>?): ClassDescriptor? =
|
||||
findTypeDescriptor(kClass.classId, kClass.toString(), errorDiagnostic)
|
||||
|
||||
internal fun findTypeDescriptor(type: KType, errorDiagnostic: DiagnosticFactory1<PsiElement, String>?): ClassDescriptor? =
|
||||
findTypeDescriptor(type.classId, type.toString(), errorDiagnostic)
|
||||
|
||||
internal fun findTypeDescriptor(
|
||||
classId: ClassId?, typeName: String,
|
||||
errorDiagnostic: DiagnosticFactory1<PsiElement, String>?
|
||||
): ClassDescriptor? {
|
||||
val typeDescriptor = classId?.let { module.findClassAcrossModuleDependencies(it) }
|
||||
if (typeDescriptor == null && errorDiagnostic != null) {
|
||||
// TODO: use PositioningStrategies to highlight some specific place in case of error, instead of treating the whole file as invalid
|
||||
resolveSession.trace.report(
|
||||
errorDiagnostic.on(
|
||||
scriptInfo.script,
|
||||
receiverClassId?.asSingleFqName()?.toString() ?: type.toString()
|
||||
classId?.asSingleFqName()?.toString() ?: typeName
|
||||
)
|
||||
)
|
||||
}
|
||||
return typeDescriptor
|
||||
}
|
||||
|
||||
override fun getImplicitReceivers(): List<ClassDescriptor> = scriptImplicitReceivers()
|
||||
@@ -123,7 +134,7 @@ class LazyScriptDescriptor(
|
||||
private val scriptOuterScope: () -> LexicalScope = resolveSession.storageManager.createLazyValue {
|
||||
var outerScope = super.getOuterScope()
|
||||
val outerScopeReceivers = implicitReceivers.let {
|
||||
if (scriptDefinition.environmentVariables.isEmpty()) {
|
||||
if (scriptDefinition().environmentVariables.isEmpty()) {
|
||||
it
|
||||
} else {
|
||||
it + ScriptEnvironmentDescriptor(this)
|
||||
@@ -142,12 +153,17 @@ class LazyScriptDescriptor(
|
||||
}
|
||||
|
||||
override fun getOuterScope(): LexicalScope = scriptOuterScope()
|
||||
|
||||
private val scriptClassAnnotations: () -> Annotations = resolveSession.storageManager.createLazyValue {
|
||||
baseClassDescriptor()?.annotations?.let { ann ->
|
||||
FilteredAnnotations(ann) { fqname ->
|
||||
val shortName = fqname.shortName().identifier
|
||||
// TODO: consider more precise annotation filtering
|
||||
!shortName.startsWith("KotlinScript") && !shortName.startsWith("ScriptTemplate")
|
||||
}
|
||||
} ?: super.annotations
|
||||
}
|
||||
|
||||
override val annotations: Annotations
|
||||
get() = scriptClassAnnotations()
|
||||
}
|
||||
|
||||
private val KClass<*>.classId: ClassId
|
||||
get() = this.java.enclosingClass?.kotlin?.classId?.createNestedClassId(Name.identifier(simpleName!!))
|
||||
?: ClassId.topLevel(FqName(qualifiedName!!))
|
||||
|
||||
private val KType.classId: ClassId?
|
||||
get() = classifier?.let { it as? KClass<*> }?.classId
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class ScriptEnvironmentDescriptor(script: LazyScriptDescriptor) :
|
||||
override fun getUnsubstitutedMemberScope(): MemberScope = memberScope()
|
||||
|
||||
val properties: () -> List<ScriptEnvironmentPropertyDescriptor> = script.resolveSession.storageManager.createLazyValue {
|
||||
script.scriptDefinition.environmentVariables.mapNotNull { (name, type) ->
|
||||
script.scriptDefinition().environmentVariables.mapNotNull { (name, type) ->
|
||||
script.findTypeDescriptor(type, Errors.MISSING_SCRIPT_ENVIRONMENT_PROPERTY_CLASS)?.let {
|
||||
name to it
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.lazy.descriptors.script
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
val KClass<*>.classId: ClassId
|
||||
get() = this.java.enclosingClass?.kotlin?.classId?.createNestedClassId(Name.identifier(simpleName!!))
|
||||
?: ClassId.topLevel(FqName(qualifiedName!!))
|
||||
|
||||
val KType.classId: ClassId?
|
||||
get() = classifier?.let { it as? KClass<*> }?.classId
|
||||
@@ -37,7 +37,8 @@ fun makeJsIncrementally(
|
||||
messageCollector: MessageCollector = MessageCollector.NONE,
|
||||
reporter: ICReporter = EmptyICReporter
|
||||
) {
|
||||
val versions = commonCacheVersions(cachesDir) + standaloneCacheVersion(cachesDir)
|
||||
val isIncremental = IncrementalCompilation.isEnabledForJs()
|
||||
val versions = commonCacheVersions(cachesDir, isIncremental) + standaloneCacheVersion(cachesDir, isIncremental)
|
||||
val allKotlinFiles = sourceRoots.asSequence().flatMap { it.walk() }
|
||||
.filter { it.isFile && it.extension.equals("kt", ignoreCase = true) }.toList()
|
||||
|
||||
@@ -47,14 +48,13 @@ fun makeJsIncrementally(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <R> withJsIC(fn: ()->R): R {
|
||||
inline fun <R> withJsIC(fn: () -> R): R {
|
||||
val isJsEnabledBackup = IncrementalCompilation.isEnabledForJs()
|
||||
IncrementalCompilation.setIsEnabledForJs(true)
|
||||
|
||||
try {
|
||||
return withIC { fn() }
|
||||
}
|
||||
finally {
|
||||
return fn()
|
||||
} finally {
|
||||
IncrementalCompilation.setIsEnabledForJs(isJsEnabledBackup)
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class IncrementalJsCompilerRunner(
|
||||
reporter
|
||||
) {
|
||||
override fun isICEnabled(): Boolean =
|
||||
IncrementalCompilation.isEnabled() && IncrementalCompilation.isEnabledForJs()
|
||||
IncrementalCompilation.isEnabledForJs()
|
||||
|
||||
override fun createCacheManager(args: K2JSCompilerArguments): IncrementalJsCachesManager =
|
||||
IncrementalJsCachesManager(cacheDirectory, reporter)
|
||||
|
||||
@@ -56,7 +56,8 @@ fun makeIncrementally(
|
||||
messageCollector: MessageCollector = MessageCollector.NONE,
|
||||
reporter: ICReporter = EmptyICReporter
|
||||
) {
|
||||
val versions = commonCacheVersions(cachesDir) + standaloneCacheVersion(cachesDir)
|
||||
val isIncremental = IncrementalCompilation.isEnabledForJvm()
|
||||
val versions = commonCacheVersions(cachesDir, isIncremental) + standaloneCacheVersion(cachesDir, isIncremental)
|
||||
|
||||
val kotlinExtensions = listOf("kt", "kts")
|
||||
val allExtensions = kotlinExtensions + listOf("java")
|
||||
@@ -86,7 +87,7 @@ object EmptyICReporter : ICReporter {
|
||||
}
|
||||
|
||||
inline fun <R> withIC(enabled: Boolean = true, fn: ()->R): R {
|
||||
val isEnabledBackup = IncrementalCompilation.isEnabled()
|
||||
val isEnabledBackup = IncrementalCompilation.isEnabledForJvm()
|
||||
IncrementalCompilation.setIsEnabled(enabled)
|
||||
|
||||
try {
|
||||
@@ -114,7 +115,7 @@ class IncrementalJvmCompilerRunner(
|
||||
localStateDirs = localStateDirs
|
||||
) {
|
||||
override fun isICEnabled(): Boolean =
|
||||
IncrementalCompilation.isEnabled()
|
||||
IncrementalCompilation.isEnabledForJvm()
|
||||
|
||||
override fun createCacheManager(args: K2JVMCompilerArguments): IncrementalJvmCachesManager =
|
||||
IncrementalJvmCachesManager(cacheDirectory, File(args.destination), reporter)
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.io.File
|
||||
internal const val STANDALONE_CACHE_VERSION = 2
|
||||
internal const val STANDALONE_VERSION_FILE_NAME = "standalone-ic-format-version.txt"
|
||||
|
||||
fun standaloneCacheVersion(dataRoot: File): CacheVersion =
|
||||
customCacheVersion(STANDALONE_CACHE_VERSION, STANDALONE_VERSION_FILE_NAME, dataRoot, enabled = true)
|
||||
fun standaloneCacheVersion(dataRoot: File, enabled: Boolean): CacheVersion =
|
||||
customCacheVersion(STANDALONE_CACHE_VERSION, STANDALONE_VERSION_FILE_NAME, dataRoot, enabled)
|
||||
|
||||
fun customCacheVersion(version: Int, fileName: String, dataRoot: File, enabled: Boolean): CacheVersion =
|
||||
CacheVersion(ownVersion = version,
|
||||
@@ -30,8 +30,7 @@ fun customCacheVersion(version: Int, fileName: String, dataRoot: File, enabled:
|
||||
whenVersionChanged = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
whenTurnedOn = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
whenTurnedOff = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
isEnabled = { enabled })
|
||||
isEnabled = enabled)
|
||||
|
||||
fun commonCacheVersions(cachesDir: File): List<CacheVersion> =
|
||||
listOf(normalCacheVersion(cachesDir),
|
||||
dataContainerCacheVersion(cachesDir))
|
||||
fun commonCacheVersions(cachesDir: File, enabled: Boolean): List<CacheVersion> =
|
||||
listOf(normalCacheVersion(cachesDir, enabled), dataContainerCacheVersion(cachesDir, enabled))
|
||||
@@ -11,6 +11,7 @@ import com.intellij.psi.impl.LanguageConstantExpressionEvaluator
|
||||
import com.intellij.psi.impl.light.LightIdentifier
|
||||
import com.intellij.psi.impl.light.LightTypeElement
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
@@ -22,7 +23,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
class KtLightPsiArrayInitializerMemberValue(
|
||||
override val kotlinOrigin: KtElement,
|
||||
val lightParent: PsiElement,
|
||||
val arguments: (KtLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
||||
private val arguments: (KtLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
||||
) : KtLightElementBase(lightParent), PsiArrayInitializerMemberValue {
|
||||
override fun getInitializers(): Array<PsiAnnotationMemberValue> = arguments(this).toTypedArray()
|
||||
|
||||
@@ -82,6 +83,7 @@ private fun psiType(kotlinType: KotlinType, context: PsiElement): PsiType? {
|
||||
"kotlin.Char" -> PsiType.CHAR
|
||||
"kotlin.Double" -> PsiType.DOUBLE
|
||||
"kotlin.Float" -> PsiType.FLOAT
|
||||
"kotlin.Unit" -> PsiType.VOID
|
||||
"kotlin.String" -> PsiType.getJavaLangString(context.manager, context.resolveScope)
|
||||
else -> PsiType.getTypeByName(typeFqName, context.project, context.resolveScope)
|
||||
}
|
||||
@@ -90,11 +92,16 @@ private fun psiType(kotlinType: KotlinType, context: PsiElement): PsiType? {
|
||||
class KtLightPsiNameValuePair private constructor(
|
||||
override val kotlinOrigin: KtElement,
|
||||
val valueArgument: KtValueArgument,
|
||||
lightParent: PsiElement
|
||||
lightParent: PsiElement,
|
||||
private val argument: (KtLightPsiNameValuePair) -> PsiAnnotationMemberValue?
|
||||
) : KtLightElementBase(lightParent),
|
||||
PsiNameValuePair {
|
||||
|
||||
constructor(valueArgument: KtValueArgument, lightParent: PsiElement) : this(valueArgument.asElement(), valueArgument, lightParent)
|
||||
constructor(
|
||||
valueArgument: KtValueArgument,
|
||||
lightParent: PsiElement,
|
||||
argument: (KtLightPsiNameValuePair) -> PsiAnnotationMemberValue?
|
||||
) : this(valueArgument.asElement(), valueArgument, lightParent, argument)
|
||||
|
||||
override fun setValue(newValue: PsiAnnotationMemberValue): PsiAnnotationMemberValue =
|
||||
throw UnsupportedOperationException("can't modify KtLightPsiNameValuePair")
|
||||
@@ -103,8 +110,9 @@ class KtLightPsiNameValuePair private constructor(
|
||||
|
||||
override fun getName(): String? = valueArgument.getArgumentName()?.asName?.asString()
|
||||
|
||||
override fun getValue(): PsiAnnotationMemberValue? =
|
||||
valueArgument.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(this, it) }
|
||||
private val _value: PsiAnnotationMemberValue? by lazyPub { argument(this) }
|
||||
|
||||
override fun getValue(): PsiAnnotationMemberValue? = _value
|
||||
|
||||
override fun getLiteralValue(): String? = (getValue() as? PsiLiteralExpression)?.value?.toString()
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.psi.impl.LanguageConstantExpressionEvaluator
|
||||
import com.intellij.psi.impl.light.LightIdentifier
|
||||
import com.intellij.psi.impl.light.LightTypeElement
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
@@ -22,7 +23,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
class KtLightPsiArrayInitializerMemberValue(
|
||||
override val kotlinOrigin: KtElement,
|
||||
val lightParent: PsiElement,
|
||||
val arguments: (KtLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
||||
private val arguments: (KtLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
||||
) : KtLightElementBase(lightParent), PsiArrayInitializerMemberValue {
|
||||
override fun getInitializers(): Array<PsiAnnotationMemberValue> = arguments(this).toTypedArray()
|
||||
|
||||
@@ -72,16 +73,17 @@ class KtLightPsiClassObjectAccessExpression(override val kotlinOrigin: KtClassLi
|
||||
}
|
||||
|
||||
private fun psiType(kotlinType: KotlinType, context: PsiElement): PsiType? {
|
||||
val typeFqName = kotlinType.constructor.declarationDescriptor?.fqNameSafe?.asString() ?: return null
|
||||
return when (typeFqName) {
|
||||
"kotlin.Int" -> PsiType.INT
|
||||
"kotlin.Long" -> PsiType.LONG
|
||||
"kotlin.Short" -> PsiType.SHORT
|
||||
"kotlin.Boolean" -> PsiType.BOOLEAN
|
||||
"kotlin.Byte" -> PsiType.BYTE
|
||||
"kotlin.Char" -> PsiType.CHAR
|
||||
"kotlin.Double" -> PsiType.DOUBLE
|
||||
"kotlin.Float" -> PsiType.FLOAT
|
||||
val typeFqName = kotlinType.constructor.declarationDescriptor?.fqNameSafe?.asString() ?: return null
|
||||
return when (typeFqName) {
|
||||
"kotlin.Int" -> PsiType.INT
|
||||
"kotlin.Long" -> PsiType.LONG
|
||||
"kotlin.Short" -> PsiType.SHORT
|
||||
"kotlin.Boolean" -> PsiType.BOOLEAN
|
||||
"kotlin.Byte" -> PsiType.BYTE
|
||||
"kotlin.Char" -> PsiType.CHAR
|
||||
"kotlin.Double" -> PsiType.DOUBLE
|
||||
"kotlin.Float" -> PsiType.FLOAT
|
||||
"kotlin.Unit" -> PsiType.VOID
|
||||
"kotlin.String" -> PsiType.getJavaLangString(context.manager, context.resolveScope)
|
||||
else -> PsiType.getTypeByName(typeFqName, context.project, context.resolveScope)
|
||||
}
|
||||
@@ -90,11 +92,16 @@ private fun psiType(kotlinType: KotlinType, context: PsiElement): PsiType? {
|
||||
class KtLightPsiNameValuePair private constructor(
|
||||
override val kotlinOrigin: KtElement,
|
||||
val valueArgument: KtValueArgument,
|
||||
lightParent: PsiElement
|
||||
lightParent: PsiElement,
|
||||
private val argument: (KtLightPsiNameValuePair) -> PsiAnnotationMemberValue?
|
||||
) : KtLightElementBase(lightParent),
|
||||
PsiNameValuePair {
|
||||
|
||||
constructor(valueArgument: KtValueArgument, lightParent: PsiElement) : this(valueArgument.asElement(), valueArgument, lightParent)
|
||||
constructor(
|
||||
valueArgument: KtValueArgument,
|
||||
lightParent: PsiElement,
|
||||
argument: (KtLightPsiNameValuePair) -> PsiAnnotationMemberValue?
|
||||
) : this(valueArgument.asElement(), valueArgument, lightParent, argument)
|
||||
|
||||
override fun setValue(newValue: PsiAnnotationMemberValue): PsiAnnotationMemberValue =
|
||||
throw UnsupportedOperationException("can't modify KtLightPsiNameValuePair")
|
||||
@@ -103,8 +110,9 @@ class KtLightPsiNameValuePair private constructor(
|
||||
|
||||
override fun getName(): String? = valueArgument.getArgumentName()?.asName?.asString()
|
||||
|
||||
override fun getValue(): PsiAnnotationMemberValue? =
|
||||
valueArgument.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(this, it) }
|
||||
private val _value: PsiAnnotationMemberValue? by lazyPub { argument(this) }
|
||||
|
||||
override fun getValue(): PsiAnnotationMemberValue? = _value
|
||||
|
||||
override fun getLiteralValue(): String? = (getValue() as? PsiLiteralExpression)?.value?.toString()
|
||||
|
||||
|
||||
@@ -5,38 +5,72 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
|
||||
class KtLightPsiJavaCodeReferenceElement(
|
||||
private val ktElement: PsiElement,
|
||||
private val reference: PsiReference,
|
||||
private val clsDelegateProvider: () -> PsiJavaCodeReferenceElement
|
||||
reference: () -> PsiReference?,
|
||||
clsDelegateProvider: () -> PsiJavaCodeReferenceElement?
|
||||
) :
|
||||
PsiElement by ktElement,
|
||||
PsiReference by reference,
|
||||
PsiReference by LazyPsiReferenceDelegate(ktElement, reference),
|
||||
PsiJavaCodeReferenceElement {
|
||||
|
||||
private val delegate by lazyPub { clsDelegateProvider() }
|
||||
private val delegate by lazyPub(clsDelegateProvider)
|
||||
|
||||
override fun advancedResolve(incompleteCode: Boolean): JavaResolveResult = delegate.advancedResolve(incompleteCode)
|
||||
override fun advancedResolve(incompleteCode: Boolean): JavaResolveResult =
|
||||
delegate?.advancedResolve(incompleteCode) ?: JavaResolveResult.EMPTY
|
||||
|
||||
override fun getReferenceNameElement(): PsiElement? = ktElement
|
||||
|
||||
override fun getTypeParameters(): Array<PsiType> = delegate.typeParameters
|
||||
override fun getTypeParameters(): Array<PsiType> = delegate?.typeParameters ?: emptyArray()
|
||||
|
||||
override fun getReferenceName(): String? = delegate.referenceName
|
||||
override fun getReferenceName(): String? = delegate?.referenceName
|
||||
|
||||
override fun isQualified(): Boolean = delegate.isQualified
|
||||
override fun isQualified(): Boolean = delegate?.isQualified ?: false
|
||||
|
||||
override fun processVariants(processor: PsiScopeProcessor) = delegate.processVariants(processor)
|
||||
override fun processVariants(processor: PsiScopeProcessor) {
|
||||
delegate?.processVariants(processor)
|
||||
}
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<JavaResolveResult> = delegate.multiResolve(incompleteCode)
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<JavaResolveResult> = delegate?.multiResolve(incompleteCode) ?: emptyArray()
|
||||
|
||||
override fun getQualifiedName(): String = delegate.qualifiedName
|
||||
override fun getQualifiedName(): String? = delegate?.qualifiedName
|
||||
|
||||
override fun getQualifier(): PsiElement? = delegate.qualifier
|
||||
override fun getQualifier(): PsiElement? = delegate?.qualifier
|
||||
|
||||
override fun getParameterList(): PsiReferenceParameterList? = delegate.parameterList
|
||||
override fun getParameterList(): PsiReferenceParameterList? = delegate?.parameterList
|
||||
}
|
||||
|
||||
private class LazyPsiReferenceDelegate(
|
||||
private val psiElement: PsiElement,
|
||||
referenceProvider: () -> PsiReference?
|
||||
) : PsiReference {
|
||||
|
||||
private val delegate by lazyPub(referenceProvider)
|
||||
|
||||
override fun getElement(): PsiElement = psiElement
|
||||
|
||||
override fun resolve(): PsiElement? = delegate?.resolve()
|
||||
|
||||
override fun getRangeInElement(): TextRange = delegate?.rangeInElement ?: psiElement.textRange
|
||||
|
||||
override fun getCanonicalText(): String = delegate?.canonicalText ?: "<no-text>"
|
||||
|
||||
@Throws(IncorrectOperationException::class)
|
||||
override fun handleElementRename(newElementName: String): PsiElement = delegate?.handleElementRename(newElementName) ?: element
|
||||
|
||||
@Throws(IncorrectOperationException::class)
|
||||
override fun bindToElement(element: PsiElement): PsiElement =
|
||||
delegate?.bindToElement(element) ?: throw IncorrectOperationException("can't rename LazyPsiReferenceDelegate")
|
||||
|
||||
override fun isSoft(): Boolean = delegate?.isSoft ?: false
|
||||
|
||||
override fun isReferenceTo(element: PsiElement): Boolean = delegate?.isReferenceTo(element) ?: false
|
||||
|
||||
override fun getVariants(): Array<Any> = delegate?.variants ?: emptyArray()
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
@@ -96,28 +98,17 @@ class KtLightAnnotationForSourceEntry(
|
||||
|
||||
override fun findDeclaredAttributeValue(name: String?): PsiAnnotationMemberValue? = getAttributeValue(name, false)
|
||||
|
||||
private fun getCallEntry(name: String): MutableMap.MutableEntry<ValueParameterDescriptor, ResolvedValueArgument>? {
|
||||
val resolvedCall = kotlinOrigin.getResolvedCall() ?: return null
|
||||
return resolvedCall.valueArguments.entries.find { (param, _) -> param.name.asString() == name } ?: return null
|
||||
}
|
||||
|
||||
private fun getAttributeValue(name: String?, useDefault: Boolean): PsiAnnotationMemberValue? {
|
||||
val name = name ?: "value"
|
||||
val callEntry = getCallEntry(name) ?: return null
|
||||
|
||||
val resolvedCall = kotlinOrigin.getResolvedCall() ?: return null
|
||||
val callEntry = resolvedCall.valueArguments.entries.find { (param, _) -> param.name.asString() == name } ?: return null
|
||||
|
||||
val valueArguments = callEntry.value.arguments
|
||||
val valueArgument = valueArguments.firstOrNull()
|
||||
val argument = valueArgument?.getArgumentExpression()
|
||||
if (argument != null) {
|
||||
val arrayExpected = callEntry.key?.type?.let { KotlinBuiltIns.isArray(it) } ?: false
|
||||
|
||||
if (arrayExpected && (argument is KtStringTemplateExpression || argument is KtConstantExpression || getAnnotationName(argument) != null))
|
||||
return KtLightPsiArrayInitializerMemberValue(
|
||||
PsiTreeUtil.findCommonParent(valueArguments.map { it.getArgumentExpression() }) as KtElement,
|
||||
this,
|
||||
{ self ->
|
||||
valueArguments.mapNotNull {
|
||||
it.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(self, it) }
|
||||
}
|
||||
})
|
||||
|
||||
val valueArgument = callEntry.value.arguments.firstOrNull()
|
||||
if (valueArgument != null) {
|
||||
ktLightAnnotationParameterList.attributes.find { (it as KtLightPsiNameValuePair).valueArgument === valueArgument }?.let {
|
||||
return it.value
|
||||
}
|
||||
@@ -136,15 +127,14 @@ class KtLightAnnotationForSourceEntry(
|
||||
}
|
||||
|
||||
|
||||
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? {
|
||||
val reference = (kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference
|
||||
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = KtLightPsiJavaCodeReferenceElement(
|
||||
kotlinOrigin.navigationElement,
|
||||
{
|
||||
(kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference
|
||||
?: (kotlinOrigin.calleeExpression?.nameReference)?.references?.firstOrNull()
|
||||
?: return null
|
||||
return KtLightPsiJavaCodeReferenceElement(
|
||||
kotlinOrigin.navigationElement,
|
||||
reference,
|
||||
{ super.getNameReferenceElement()!! })
|
||||
}
|
||||
},
|
||||
{ super.getNameReferenceElement() }
|
||||
)
|
||||
|
||||
|
||||
private val ktLightAnnotationParameterList by lazyPub { KtLightAnnotationParameterList() }
|
||||
@@ -153,13 +143,40 @@ class KtLightAnnotationForSourceEntry(
|
||||
|
||||
inner class KtLightAnnotationParameterList() : KtLightElementBase(this),
|
||||
PsiAnnotationParameterList {
|
||||
override val kotlinOrigin get() = null
|
||||
override val kotlinOrigin: KtElement? get() = null
|
||||
|
||||
private val _attributes: Array<PsiNameValuePair> by lazyPub {
|
||||
this@KtLightAnnotationForSourceEntry.kotlinOrigin.valueArguments.map { KtLightPsiNameValuePair(it as KtValueArgument, this) }
|
||||
this@KtLightAnnotationForSourceEntry.kotlinOrigin.valueArguments.map { makeLightPsiNameValuePair(it as KtValueArgument) }
|
||||
.toTypedArray<PsiNameValuePair>()
|
||||
}
|
||||
|
||||
private fun makeArrayInitializerIfExpected(pair: KtLightPsiNameValuePair): PsiAnnotationMemberValue? {
|
||||
val valueArgument = pair.valueArgument
|
||||
val name = valueArgument.name ?: "value"
|
||||
val callEntry = getCallEntry(name) ?: return null
|
||||
|
||||
val valueArguments = callEntry.value.arguments
|
||||
val argument = valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
|
||||
|
||||
if (!callEntry.key.type.let { KotlinBuiltIns.isArray(it) }) return null
|
||||
|
||||
if (argument !is KtStringTemplateExpression && argument !is KtConstantExpression && getAnnotationName(argument) == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val parent = PsiTreeUtil.findCommonParent(valueArguments.map { it.getArgumentExpression() }) as KtElement
|
||||
return KtLightPsiArrayInitializerMemberValue(parent, pair) { self ->
|
||||
valueArguments.mapNotNull {
|
||||
it.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(self, it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeLightPsiNameValuePair(valueArgument: KtValueArgument) = KtLightPsiNameValuePair(valueArgument, this) { self ->
|
||||
makeArrayInitializerIfExpected(self)
|
||||
?: self.valueArgument.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(self, it) }
|
||||
}
|
||||
|
||||
override fun getAttributes(): Array<PsiNameValuePair> = _attributes
|
||||
|
||||
}
|
||||
@@ -323,6 +340,7 @@ private val backendNullabilityAnnotations = arrayOf(Nullable::class.java.name, N
|
||||
private fun KtElement.analyze(): BindingContext = LightClassGenerationSupport.getInstance(this.project).analyze(this)
|
||||
|
||||
private fun KtElement.getResolvedCall(): ResolvedCall<out CallableDescriptor>? {
|
||||
if (!isValid) return null
|
||||
val context = analyze()
|
||||
return this.getResolvedCall(context)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
@@ -98,28 +100,17 @@ class KtLightAnnotationForSourceEntry(
|
||||
|
||||
override fun findDeclaredAttributeValue(name: String?): PsiAnnotationMemberValue? = getAttributeValue(name, false)
|
||||
|
||||
private fun getCallEntry(name: String): MutableMap.MutableEntry<ValueParameterDescriptor, ResolvedValueArgument>? {
|
||||
val resolvedCall = kotlinOrigin.getResolvedCall() ?: return null
|
||||
return resolvedCall.valueArguments.entries.find { (param, _) -> param.name.asString() == name } ?: return null
|
||||
}
|
||||
|
||||
private fun getAttributeValue(name: String?, useDefault: Boolean): PsiAnnotationMemberValue? {
|
||||
val name = name ?: "value"
|
||||
val callEntry = getCallEntry(name) ?: return null
|
||||
|
||||
val resolvedCall = kotlinOrigin.getResolvedCall() ?: return null
|
||||
val callEntry = resolvedCall.valueArguments.entries.find { (param, _) -> param.name.asString() == name } ?: return null
|
||||
|
||||
val valueArguments = callEntry.value.arguments
|
||||
val valueArgument = valueArguments.firstOrNull()
|
||||
val argument = valueArgument?.getArgumentExpression()
|
||||
if (argument != null) {
|
||||
val arrayExpected = callEntry.key?.type?.let { KotlinBuiltIns.isArray(it) } ?: false
|
||||
|
||||
if (arrayExpected && (argument is KtStringTemplateExpression || argument is KtConstantExpression || getAnnotationName(argument) != null))
|
||||
return KtLightPsiArrayInitializerMemberValue(
|
||||
PsiTreeUtil.findCommonParent(valueArguments.map { it.getArgumentExpression() }) as KtElement,
|
||||
this,
|
||||
{ self ->
|
||||
valueArguments.mapNotNull {
|
||||
it.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(self, it) }
|
||||
}
|
||||
})
|
||||
|
||||
val valueArgument = callEntry.value.arguments.firstOrNull()
|
||||
if (valueArgument != null) {
|
||||
ktLightAnnotationParameterList.attributes.find { (it as KtLightPsiNameValuePair).valueArgument === valueArgument }?.let {
|
||||
return it.value
|
||||
}
|
||||
@@ -138,15 +129,14 @@ class KtLightAnnotationForSourceEntry(
|
||||
}
|
||||
|
||||
|
||||
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? {
|
||||
val reference = (kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference
|
||||
override fun getNameReferenceElement(): PsiJavaCodeReferenceElement? = KtLightPsiJavaCodeReferenceElement(
|
||||
kotlinOrigin.navigationElement,
|
||||
{
|
||||
(kotlinOrigin as? KtAnnotationEntry)?.typeReference?.reference
|
||||
?: (kotlinOrigin.calleeExpression?.nameReference)?.references?.firstOrNull()
|
||||
?: return null
|
||||
return KtLightPsiJavaCodeReferenceElement(
|
||||
kotlinOrigin.navigationElement,
|
||||
reference,
|
||||
{ super.getNameReferenceElement()!! })
|
||||
}
|
||||
},
|
||||
{ super.getNameReferenceElement() }
|
||||
)
|
||||
|
||||
|
||||
private val ktLightAnnotationParameterList by lazyPub { KtLightAnnotationParameterList() }
|
||||
@@ -155,13 +145,40 @@ class KtLightAnnotationForSourceEntry(
|
||||
|
||||
inner class KtLightAnnotationParameterList() : KtLightElementBase(this),
|
||||
PsiAnnotationParameterList {
|
||||
override val kotlinOrigin get() = null
|
||||
override val kotlinOrigin: KtElement? get() = null
|
||||
|
||||
private val _attributes: Array<PsiNameValuePair> by lazyPub {
|
||||
this@KtLightAnnotationForSourceEntry.kotlinOrigin.valueArguments.map { KtLightPsiNameValuePair(it as KtValueArgument, this) }
|
||||
this@KtLightAnnotationForSourceEntry.kotlinOrigin.valueArguments.map { makeLightPsiNameValuePair(it as KtValueArgument) }
|
||||
.toTypedArray<PsiNameValuePair>()
|
||||
}
|
||||
|
||||
private fun makeArrayInitializerIfExpected(pair: KtLightPsiNameValuePair): PsiAnnotationMemberValue? {
|
||||
val valueArgument = pair.valueArgument
|
||||
val name = valueArgument.name ?: "value"
|
||||
val callEntry = getCallEntry(name) ?: return null
|
||||
|
||||
val valueArguments = callEntry.value.arguments
|
||||
val argument = valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
|
||||
|
||||
if (!callEntry.key.type.let { KotlinBuiltIns.isArray(it) }) return null
|
||||
|
||||
if (argument !is KtStringTemplateExpression && argument !is KtConstantExpression && getAnnotationName(argument) == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val parent = PsiTreeUtil.findCommonParent(valueArguments.map { it.getArgumentExpression() }) as KtElement
|
||||
return KtLightPsiArrayInitializerMemberValue(parent, pair) { self ->
|
||||
valueArguments.mapNotNull {
|
||||
it.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(self, it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeLightPsiNameValuePair(valueArgument: KtValueArgument) = KtLightPsiNameValuePair(valueArgument, this) { self ->
|
||||
makeArrayInitializerIfExpected(self)
|
||||
?: self.valueArgument.getArgumentExpression()?.let { convertToLightAnnotationMemberValue(self, it) }
|
||||
}
|
||||
|
||||
override fun getAttributes(): Array<PsiNameValuePair> = _attributes
|
||||
|
||||
}
|
||||
@@ -325,6 +342,7 @@ private val backendNullabilityAnnotations = arrayOf(Nullable::class.java.name, N
|
||||
private fun KtElement.analyze(): BindingContext = LightClassGenerationSupport.getInstance(this.project).analyze(this)
|
||||
|
||||
private fun KtElement.getResolvedCall(): ResolvedCall<out CallableDescriptor>? {
|
||||
if (!isValid) return null
|
||||
val context = analyze()
|
||||
return this.getResolvedCall(context)
|
||||
}
|
||||
@@ -385,7 +403,7 @@ private fun unwrapCall(callee: KtExpression): KtExpression = when (callee) {
|
||||
|
||||
private fun getAnnotationName(callee: KtExpression): String? {
|
||||
val callee = unwrapCall(callee)
|
||||
val resultingDescriptor = callee.getResolvedCall()?.resultingDescriptor
|
||||
val resultingDescriptor = callee.getResolvedCall()?.resultingDescriptor
|
||||
if (resultingDescriptor is ClassConstructorDescriptor) {
|
||||
val ktClass = resultingDescriptor.constructedClass.source.getPsi() as? KtClass
|
||||
if (ktClass?.isAnnotation() == true) return ktClass.fqName?.toString()
|
||||
|
||||
@@ -119,7 +119,10 @@ public class KtPackageDirective extends KtModifierListOwnerStub<KotlinPlaceHolde
|
||||
|
||||
public void setFqName(@NotNull FqName fqName) {
|
||||
if (fqName.isRoot()) {
|
||||
delete();
|
||||
if (!getFqName().isRoot()) {
|
||||
//noinspection ConstantConditions
|
||||
replace(new KtPsiFactory(getProject()).createFile("").getPackageDirective());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import com.intellij.psi.*
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.lexer.KotlinLexer
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -33,6 +35,7 @@ import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.util.*
|
||||
|
||||
// NOTE: in this file we collect only Kotlin-specific methods working with PSI and not modifying it
|
||||
@@ -430,6 +433,8 @@ val KtModifierListOwner.isPublic: Boolean
|
||||
fun KtModifierListOwner.visibilityModifierType(): KtModifierKeywordToken? =
|
||||
visibilityModifier()?.node?.elementType as KtModifierKeywordToken?
|
||||
|
||||
fun KtModifierListOwner.visibilityModifierTypeOrDefault(): KtModifierKeywordToken = visibilityModifierType() ?: KtTokens.DEFAULT_VISIBILITY_KEYWORD
|
||||
|
||||
fun KtDeclaration.modalityModifier() = modifierFromTokenSet(MODALITY_MODIFIERS)
|
||||
|
||||
fun KtStringTemplateExpression.isPlain() = entries.all { it is KtLiteralStringTemplateEntry }
|
||||
@@ -591,4 +596,14 @@ fun isTopLevelInFileOrScript(element: PsiElement): Boolean {
|
||||
is KtBlockExpression -> parent.parent is KtScript
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
fun KtModifierKeywordToken.toVisibility(): Visibility {
|
||||
return when (this) {
|
||||
KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
|
||||
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
|
||||
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
|
||||
KtTokens.INTERNAL_KEYWORD -> Visibilities.INTERNAL
|
||||
else -> throw IllegalArgumentException("Unknown visibility modifier:$this")
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,10 @@ open class KotlinScriptDefinition(open val template: KClass<out Any>) : UserData
|
||||
open val implicitReceivers: List<KType> get() = emptyList()
|
||||
|
||||
open val environmentVariables: List<Pair<String, KType>> get() = emptyList()
|
||||
|
||||
open val targetClassAnnotations: List<Annotation> get() = emptyList()
|
||||
|
||||
open val targetMethodAnnotations: List<Annotation> get() = emptyList()
|
||||
}
|
||||
|
||||
object StandardScriptDefinition : KotlinScriptDefinition(ScriptTemplateWithArgs::class)
|
||||
|
||||
@@ -222,13 +222,20 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
||||
private val resolutionScope: ResolutionScope
|
||||
) : AbstractScopeTowerLevel(scopeTower) {
|
||||
|
||||
val deprecationDiagnosticOfThisScope: ResolutionDiagnostic? =
|
||||
if (resolutionScope is DeprecatedLexicalScope) ResolvedUsingDeprecatedVisibility(resolutionScope, location) else null
|
||||
|
||||
internal constructor(scopeTower: ImplicitScopeTower, lexicalScope: LexicalScope) : this(scopeTower, lexicalScope as ResolutionScope)
|
||||
|
||||
override fun getVariables(
|
||||
name: Name,
|
||||
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||
): Collection<CandidateWithBoundDispatchReceiver> = resolutionScope.getContributedVariables(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
createCandidateDescriptor(
|
||||
it,
|
||||
dispatchReceiver = null,
|
||||
specialError = deprecationDiagnosticOfThisScope
|
||||
)
|
||||
}
|
||||
|
||||
override fun getObjects(
|
||||
@@ -249,8 +256,13 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
||||
): Collection<CandidateWithBoundDispatchReceiver> {
|
||||
val result: ArrayList<CandidateWithBoundDispatchReceiver> = ArrayList()
|
||||
|
||||
resolutionScope.getContributedFunctionsAndConstructors(name, location, scopeTower.syntheticScopes)
|
||||
.mapTo(result) { createCandidateDescriptor(it, dispatchReceiver = null) }
|
||||
resolutionScope.getContributedFunctionsAndConstructors(name, location, scopeTower.syntheticScopes).mapTo(result) {
|
||||
createCandidateDescriptor(
|
||||
it,
|
||||
dispatchReceiver = null,
|
||||
specialError = deprecationDiagnosticOfThisScope
|
||||
)
|
||||
}
|
||||
|
||||
// Add constructors of deprecated classifier with an additional diagnostic
|
||||
val descriptorWithDeprecation = resolutionScope.getContributedClassifierIncludeDeprecated(name, location)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.scopes.utils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -91,8 +92,20 @@ fun DeclarationDescriptor.canBeResolvedWithoutDeprecation(
|
||||
location: LookupLocation
|
||||
): Boolean {
|
||||
for (scope in scopeForResolution.parentsWithSelf) {
|
||||
val (descriptorFromCurrentScope, isDeprecated) = scope.getContributedClassifierIncludeDeprecated(name, location) ?: continue
|
||||
if (descriptorFromCurrentScope == this && !isDeprecated) return true
|
||||
val hasNonDeprecatedSuitableCandidate = when (this) {
|
||||
// Looking for classifier: fair check via special method in ResolutionScope
|
||||
is ClassifierDescriptor -> scope.getContributedClassifierIncludeDeprecated(name, location)
|
||||
?.let { it.descriptor == this && !it.isDeprecated }
|
||||
|
||||
// Looking for member: heuristically check only one case, when another descriptor visible through explicit import
|
||||
is VariableDescriptor -> (scope as? ImportingScope)?.getContributedVariables(name, location)?.any { it == this }
|
||||
|
||||
is FunctionDescriptor -> (scope as? ImportingScope)?.getContributedFunctions(name, location)?.any { it == this }
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (hasNonDeprecatedSuitableCandidate == true) return true
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
@@ -89,8 +89,10 @@ class DescriptorSerializer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
for (descriptor in classDescriptor.constructors) {
|
||||
builder.addConstructor(constructorProto(descriptor))
|
||||
if (!DescriptorUtils.isAnonymousObject(classDescriptor) && classDescriptor.kind != ClassKind.ENUM_ENTRY) {
|
||||
for (descriptor in classDescriptor.constructors) {
|
||||
builder.addConstructor(constructorProto(descriptor))
|
||||
}
|
||||
}
|
||||
|
||||
val callableMembers =
|
||||
|
||||
@@ -3,7 +3,7 @@ This build uses internal compiler arguments:
|
||||
|
||||
-XXLanguage:-InlineClasses
|
||||
|
||||
This mode is strictly prohibited for production use,
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ This build uses internal compiler arguments:
|
||||
|
||||
-XXLanguage:+
|
||||
|
||||
This mode is strictly prohibited for production use,
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ This build uses internal compiler arguments:
|
||||
|
||||
-XXLanguage:+InlineClasses
|
||||
|
||||
This mode is strictly prohibited for production use,
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ This build uses internal compiler arguments:
|
||||
|
||||
-XXLanguage:InlineClasses
|
||||
|
||||
This mode is strictly prohibited for production use,
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ This build uses internal compiler arguments:
|
||||
|
||||
-XXLanguage:+UnknownFeature
|
||||
|
||||
This mode is strictly prohibited for production use,
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ This build uses internal compiler arguments:
|
||||
|
||||
-XXLanguage:+SoundSmartCastsAfterTry
|
||||
|
||||
This mode is strictly prohibited for production use,
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
|
||||
@@ -5,4 +5,9 @@ public class Annotated {
|
||||
|
||||
public void bar(@MyMigrationNonnull String x) {
|
||||
}
|
||||
}
|
||||
|
||||
@MyNullable
|
||||
public String nullable() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
15
compiler/testData/cli/jvm/jsr305/MyNullable.java
vendored
Normal file
15
compiler/testData/cli/jvm/jsr305/MyNullable.java
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import javax.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import javax.annotation.meta.TypeQualifierNickname;
|
||||
import javax.annotation.meta.When;
|
||||
|
||||
@Documented
|
||||
@TypeQualifierNickname
|
||||
@Nonnull(when = When.MAYBE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MyNullable {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
warning: argument -Xjsr305-annotations is deprecated. Please use -Xjsr305 instead
|
||||
compiler/testData/cli/jvm/jsr305Usage.kt:2:11: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Usage.kt:2:11: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
a.foo(null)
|
||||
^
|
||||
OK
|
||||
|
||||
3
compiler/testData/cli/jvm/jsr305Migration.kt
vendored
3
compiler/testData/cli/jvm/jsr305Migration.kt
vendored
@@ -1,4 +1,5 @@
|
||||
fun test(annotated: Annotated) {
|
||||
annotated.foo(null)
|
||||
annotated.bar(null)
|
||||
}
|
||||
annotated.nullable().length
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:2:19: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:2:19: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
annotated.foo(null)
|
||||
^
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:4:5: warning: unsafe use of a nullable receiver of type String?
|
||||
annotated.nullable().length
|
||||
^
|
||||
OK
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:2:19: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:2:19: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
annotated.foo(null)
|
||||
^
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:4:5: warning: unsafe use of a nullable receiver of type String?
|
||||
annotated.nullable().length
|
||||
^
|
||||
OK
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:2:19: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:2:19: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
annotated.foo(null)
|
||||
^
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:3:19: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:3:19: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
annotated.bar(null)
|
||||
^
|
||||
compiler/testData/cli/jvm/jsr305Migration.kt:4:5: warning: unsafe use of a nullable receiver of type String?
|
||||
annotated.nullable().length
|
||||
^
|
||||
OK
|
||||
|
||||
2
compiler/testData/cli/jvm/jsr305NoFlag.out
vendored
2
compiler/testData/cli/jvm/jsr305NoFlag.out
vendored
@@ -1,4 +1,4 @@
|
||||
compiler/testData/cli/jvm/jsr305Usage.kt:2:11: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Usage.kt:2:11: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
a.foo(null)
|
||||
^
|
||||
OK
|
||||
|
||||
2
compiler/testData/cli/jvm/jsr305Warn.out
vendored
2
compiler/testData/cli/jvm/jsr305Warn.out
vendored
@@ -1,4 +1,4 @@
|
||||
compiler/testData/cli/jvm/jsr305Usage.kt:2:11: warning: expected type does not accept nulls in Java, but the value may be null in Kotlin
|
||||
compiler/testData/cli/jvm/jsr305Usage.kt:2:11: warning: type mismatch: inferred type is Nothing? but String was expected
|
||||
a.foo(null)
|
||||
^
|
||||
OK
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
error: specify path to the script file (.kts) as the first argument
|
||||
error: specify path to the script file as the first argument
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
error: specify path to the script file (.kts) as the first argument
|
||||
error: specify path to the script file as the first argument
|
||||
COMPILATION_ERROR
|
||||
|
||||
2
compiler/testData/cli/jvm/wrongXjsr305.args
vendored
2
compiler/testData/cli/jvm/wrongXjsr305.args
vendored
@@ -6,7 +6,9 @@ $TEMP_DIR$
|
||||
-Xjsr305=@hello\:warning
|
||||
-Xjsr305=@hello\:warn
|
||||
-Xjsr305=@hello\:ignore
|
||||
-Xjsr305=@hello\:warn
|
||||
-Xjsr305=strict
|
||||
-Xjsr305=ignore
|
||||
-Xjsr305=under-migration\:ignore
|
||||
-Xjsr305=under-migration\:strict
|
||||
-Xjsr305=under-migration\:ignore
|
||||
|
||||
1
compiler/testData/cli/jvm/wrongXjsr305.out
vendored
1
compiler/testData/cli/jvm/wrongXjsr305.out
vendored
@@ -2,7 +2,6 @@ warning: option 'enable' for -Xjsr305 flag is deprecated. Please use 'strict' in
|
||||
error: unrecognized -Xjsr305 value: under-migration:stct
|
||||
error: unrecognized -Xjsr305 value: @hello:warning
|
||||
error: conflict duplicating -Xjsr305 value: @hello:warn, @hello:ignore
|
||||
error: conflict duplicating -Xjsr305 value: strict, strict
|
||||
error: conflict duplicating -Xjsr305 value: strict, ignore
|
||||
error: conflict duplicating -Xjsr305 value: under-migration:ignore, under-migration:strict
|
||||
COMPILATION_ERROR
|
||||
|
||||
49
compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt
vendored
Normal file
49
compiler/testData/codegen/box/coroutines/suspendCovariantJavaOverrides.kt
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// COMMON_COROUTINES_TEST
|
||||
|
||||
// FILE: I.kt
|
||||
|
||||
interface I {
|
||||
suspend fun foo(x: Int): String
|
||||
suspend fun bar(x: Int): String
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass implements I {
|
||||
@Override
|
||||
public String foo(int x, COROUTINES_PACKAGE.Continuation<? super String> continuation) {
|
||||
return "O";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object bar(int x, COROUTINES_PACKAGE.Continuation<? super String> continuation) {
|
||||
return foo(x, continuation);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import helpers.*
|
||||
import COROUTINES_PACKAGE.*
|
||||
import COROUTINES_PACKAGE.intrinsics.*
|
||||
|
||||
class K : JavaClass() {
|
||||
override suspend fun foo(x: Int): String = super.foo(x) + suspendCoroutine { it.resume("K") }
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
|
||||
builder {
|
||||
// Changing the call to 'K().bar(1)' doesn't work because of KT-25036
|
||||
result = K().foo(1)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
39
compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt
vendored
Normal file
39
compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// COMMON_COROUTINES_TEST
|
||||
|
||||
// FILE: I.kt
|
||||
|
||||
interface I {
|
||||
suspend fun foo(x: Int): String
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass implements I {
|
||||
@Override
|
||||
public Object foo(int x, COROUTINES_PACKAGE.Continuation<? super String> continuation) {
|
||||
continuation.resume("OK");
|
||||
return COROUTINES_PACKAGE.intrinsics.IntrinsicsKt.getCOROUTINE_SUSPENDED();
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import helpers.*
|
||||
import COROUTINES_PACKAGE.*
|
||||
import COROUTINES_PACKAGE.intrinsics.*
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
|
||||
builder {
|
||||
result = JavaClass().foo(1)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -1,49 +1,34 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalMultiplatform
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
// MODULE: library
|
||||
// FILE: expected.kt
|
||||
|
||||
package a
|
||||
|
||||
@OptionalExpectation
|
||||
expect annotation class Anno(val s: String)
|
||||
expect annotation class A(val x: Int)
|
||||
|
||||
// FILE: jvm.kt
|
||||
@OptionalExpectation
|
||||
expect annotation class B(val s: String)
|
||||
|
||||
import java.lang.reflect.AnnotatedElement
|
||||
// FILE: actual.kt
|
||||
|
||||
@Anno("Foo")
|
||||
class Foo @Anno("<init>") constructor(@Anno("x") x: Int) {
|
||||
@Anno("bar")
|
||||
fun bar() {}
|
||||
package a
|
||||
|
||||
@Anno("getX")
|
||||
var x = x
|
||||
@Anno("setX")
|
||||
set
|
||||
actual annotation class A(actual val x: Int)
|
||||
|
||||
@Anno("Nested")
|
||||
interface Nested
|
||||
}
|
||||
// MODULE: main(library)
|
||||
// FILE: main.kt
|
||||
|
||||
private fun check(element: AnnotatedElement) {
|
||||
check(element.annotations)
|
||||
}
|
||||
package usage
|
||||
|
||||
private fun check(annotations: Array<Annotation>) {
|
||||
val filtered = annotations.filterNot { it.annotationClass.java.name == "kotlin.Metadata" }
|
||||
if (filtered.isNotEmpty()) {
|
||||
throw AssertionError("Annotations should be empty: $filtered")
|
||||
}
|
||||
}
|
||||
import a.A
|
||||
import a.B
|
||||
|
||||
@A(42)
|
||||
@B("OK")
|
||||
fun box(): String {
|
||||
val foo = Foo::class.java
|
||||
check(foo)
|
||||
check(Foo.Nested::class.java)
|
||||
check(foo.declaredMethods.single { it.name == "bar" })
|
||||
check(foo.declaredMethods.single { it.name == "getX" })
|
||||
check(foo.declaredMethods.single { it.name == "setX" })
|
||||
check(foo.constructors.single())
|
||||
check(foo.constructors.single().parameterAnnotations.single())
|
||||
return "OK"
|
||||
}
|
||||
|
||||
49
compiler/testData/codegen/box/multiplatform/optionalExpectationJvm.kt
vendored
Normal file
49
compiler/testData/codegen/box/multiplatform/optionalExpectationJvm.kt
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalMultiplatform
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: common.kt
|
||||
|
||||
@OptionalExpectation
|
||||
expect annotation class Anno(val s: String)
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
import java.lang.reflect.AnnotatedElement
|
||||
|
||||
@Anno("Foo")
|
||||
class Foo @Anno("<init>") constructor(@Anno("x") x: Int) {
|
||||
@Anno("bar")
|
||||
fun bar() {}
|
||||
|
||||
@Anno("getX")
|
||||
var x = x
|
||||
@Anno("setX")
|
||||
set
|
||||
|
||||
@Anno("Nested")
|
||||
interface Nested
|
||||
}
|
||||
|
||||
private fun check(element: AnnotatedElement) {
|
||||
check(element.annotations)
|
||||
}
|
||||
|
||||
private fun check(annotations: Array<Annotation>) {
|
||||
val filtered = annotations.filterNot { it.annotationClass.java.name == "kotlin.Metadata" }
|
||||
if (filtered.isNotEmpty()) {
|
||||
throw AssertionError("Annotations should be empty: $filtered")
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val foo = Foo::class.java
|
||||
check(foo)
|
||||
check(Foo.Nested::class.java)
|
||||
check(foo.declaredMethods.single { it.name == "bar" })
|
||||
check(foo.declaredMethods.single { it.name == "getX" })
|
||||
check(foo.declaredMethods.single { it.name == "setX" })
|
||||
check(foo.constructors.single())
|
||||
check(foo.constructors.single().parameterAnnotations.single())
|
||||
return "OK"
|
||||
}
|
||||
47
compiler/testData/codegen/box/ranges/expression/overflowZeroDownToMaxValue.kt
vendored
Normal file
47
compiler/testData/codegen/box/ranges/expression/overflowZeroDownToMaxValue.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS_IR or not
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for NATIVE or not
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
|
||||
// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT!
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
import java.lang.Integer.MAX_VALUE as MaxI
|
||||
import java.lang.Integer.MIN_VALUE as MinI
|
||||
import java.lang.Byte.MAX_VALUE as MaxB
|
||||
import java.lang.Byte.MIN_VALUE as MinB
|
||||
import java.lang.Short.MAX_VALUE as MaxS
|
||||
import java.lang.Short.MIN_VALUE as MinS
|
||||
import java.lang.Long.MAX_VALUE as MaxL
|
||||
import java.lang.Long.MIN_VALUE as MinL
|
||||
import java.lang.Character.MAX_VALUE as MaxC
|
||||
import java.lang.Character.MIN_VALUE as MinC
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<Int>()
|
||||
val range1 = 0 downTo MaxI step 3
|
||||
for (i in range1) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<Int>()) {
|
||||
return "Wrong elements for 0 downTo MaxI step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<Long>()
|
||||
val range2 = 0 downTo MaxL step 3
|
||||
for (i in range2) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<Long>()) {
|
||||
return "Wrong elements for 0 downTo MaxL step 3: $list2"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
47
compiler/testData/codegen/box/ranges/expression/overflowZeroToMinValue.kt
vendored
Normal file
47
compiler/testData/codegen/box/ranges/expression/overflowZeroToMinValue.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS_IR or not
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for NATIVE or not
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
|
||||
// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT!
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
import java.lang.Integer.MAX_VALUE as MaxI
|
||||
import java.lang.Integer.MIN_VALUE as MinI
|
||||
import java.lang.Byte.MAX_VALUE as MaxB
|
||||
import java.lang.Byte.MIN_VALUE as MinB
|
||||
import java.lang.Short.MAX_VALUE as MaxS
|
||||
import java.lang.Short.MIN_VALUE as MinS
|
||||
import java.lang.Long.MAX_VALUE as MaxL
|
||||
import java.lang.Long.MIN_VALUE as MinL
|
||||
import java.lang.Character.MAX_VALUE as MaxC
|
||||
import java.lang.Character.MIN_VALUE as MinC
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<Int>()
|
||||
val range1 = 0..MinI step 3
|
||||
for (i in range1) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<Int>()) {
|
||||
return "Wrong elements for 0..MinI step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<Long>()
|
||||
val range2 = 0L..MinL step 3
|
||||
for (i in range2) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L..MinL step 3: $list2"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
45
compiler/testData/codegen/box/ranges/literal/overflowZeroDownToMaxValue.kt
vendored
Normal file
45
compiler/testData/codegen/box/ranges/literal/overflowZeroDownToMaxValue.kt
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS_IR or not
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for NATIVE or not
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
|
||||
// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT!
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
import java.lang.Integer.MAX_VALUE as MaxI
|
||||
import java.lang.Integer.MIN_VALUE as MinI
|
||||
import java.lang.Byte.MAX_VALUE as MaxB
|
||||
import java.lang.Byte.MIN_VALUE as MinB
|
||||
import java.lang.Short.MAX_VALUE as MaxS
|
||||
import java.lang.Short.MIN_VALUE as MinS
|
||||
import java.lang.Long.MAX_VALUE as MaxL
|
||||
import java.lang.Long.MIN_VALUE as MinL
|
||||
import java.lang.Character.MAX_VALUE as MaxC
|
||||
import java.lang.Character.MIN_VALUE as MinC
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<Int>()
|
||||
for (i in 0 downTo MaxI step 3) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<Int>()) {
|
||||
return "Wrong elements for 0 downTo MaxI step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<Long>()
|
||||
for (i in 0 downTo MaxL step 3) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<Long>()) {
|
||||
return "Wrong elements for 0 downTo MaxL step 3: $list2"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
45
compiler/testData/codegen/box/ranges/literal/overflowZeroToMinValue.kt
vendored
Normal file
45
compiler/testData/codegen/box/ranges/literal/overflowZeroToMinValue.kt
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS_IR or not
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// TODO: muted automatically, investigate should it be ran for NATIVE or not
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
|
||||
// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT!
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
import java.lang.Integer.MAX_VALUE as MaxI
|
||||
import java.lang.Integer.MIN_VALUE as MinI
|
||||
import java.lang.Byte.MAX_VALUE as MaxB
|
||||
import java.lang.Byte.MIN_VALUE as MinB
|
||||
import java.lang.Short.MAX_VALUE as MaxS
|
||||
import java.lang.Short.MIN_VALUE as MinS
|
||||
import java.lang.Long.MAX_VALUE as MaxL
|
||||
import java.lang.Long.MIN_VALUE as MinL
|
||||
import java.lang.Character.MAX_VALUE as MaxC
|
||||
import java.lang.Character.MIN_VALUE as MinC
|
||||
|
||||
fun box(): String {
|
||||
val list1 = ArrayList<Int>()
|
||||
for (i in 0..MinI step 3) {
|
||||
list1.add(i)
|
||||
if (list1.size > 23) break
|
||||
}
|
||||
if (list1 != listOf<Int>()) {
|
||||
return "Wrong elements for 0..MinI step 3: $list1"
|
||||
}
|
||||
|
||||
val list2 = ArrayList<Long>()
|
||||
for (i in 0L..MinL step 3) {
|
||||
list2.add(i)
|
||||
if (list2.size > 23) break
|
||||
}
|
||||
if (list2 != listOf<Long>()) {
|
||||
return "Wrong elements for 0L..MinL step 3: $list2"
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
// FULL_JDK
|
||||
// See KT-11258 Incorrect resolution sequence for Java field
|
||||
|
||||
//SHOULD BE deleted after KT-16616 fix
|
||||
// See KT-11258, KT-16616
|
||||
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun box(): String {
|
||||
listOf(
|
||||
@@ -22,5 +21,8 @@ fun box(): String {
|
||||
).map {
|
||||
it.members.map(Any::toString)
|
||||
}
|
||||
|
||||
assertEquals(1, Collection<Any>::size.getter(listOf(1)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
13
compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt
vendored
Normal file
13
compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class E { X, Y, Z }
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(11, E::class.members.size)
|
||||
assertEquals("Y", E::name.call(E.Y))
|
||||
assertEquals(2, E::ordinal.call(E.Z))
|
||||
return "OK"
|
||||
}
|
||||
10
compiler/testData/codegen/box/reflection/builtins/stringLength.kt
vendored
Normal file
10
compiler/testData/codegen/box/reflection/builtins/stringLength.kt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun box(): String {
|
||||
String::class.members
|
||||
assertEquals(2, String::length.call("OK"))
|
||||
return "OK"
|
||||
}
|
||||
@@ -17,6 +17,7 @@ fun box(): String {
|
||||
assertTrue(Interface::class.constructors.isEmpty())
|
||||
assertTrue(Obj::class.constructors.isEmpty())
|
||||
assertTrue(C.Companion::class.constructors.isEmpty())
|
||||
assertTrue(object {}::class.constructors.isEmpty())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
24
compiler/testData/codegen/box/reflection/constructors/enumEntry.kt
vendored
Normal file
24
compiler/testData/codegen/box/reflection/constructors/enumEntry.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class TestEnum(val id: String? = null) {
|
||||
ENUM1(id = "enum1_id"),
|
||||
|
||||
ENUM2(id = "enum2_id") {
|
||||
override fun test() {
|
||||
ENUM1.test()
|
||||
}
|
||||
};
|
||||
|
||||
open fun test() {
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(listOf("fun <init>(kotlin.String?): TestEnum"), TestEnum.ENUM1::class.constructors.map { it.toString() })
|
||||
assertEquals(listOf(), TestEnum.ENUM2::class.constructors.map { it.toString() })
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -48,11 +48,13 @@ fun box(): String {
|
||||
val p4 = TwoSecondaries::class.primaryConstructor
|
||||
assertNull(p4)
|
||||
|
||||
assertNotNull(En::class.primaryConstructor) // TODO: maybe primaryConstructor should be null for enum classes
|
||||
assertNotNull(En::class.primaryConstructor)
|
||||
|
||||
assertNull(I::class.primaryConstructor)
|
||||
assertNull(O::class.primaryConstructor)
|
||||
assertNull(C.Companion::class.primaryConstructor)
|
||||
|
||||
assertNull(object {}::class.primaryConstructor)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
15
compiler/testData/codegen/box/reflection/functions/enumValuesValueOf.kt
vendored
Normal file
15
compiler/testData/codegen/box/reflection/functions/enumValuesValueOf.kt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class E { X, Y, Z }
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("fun values(): kotlin.Array<E>", E::values.toString())
|
||||
assertEquals(listOf(E.X, E.Y, E.Z), E::values.call().toList())
|
||||
assertEquals("fun valueOf(kotlin.String): E", E::valueOf.toString())
|
||||
assertEquals(E.Y, E::valueOf.call("Y"))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
37
compiler/testData/codegen/box/reflection/mapping/methodsFromObject.kt
vendored
Normal file
37
compiler/testData/codegen/box/reflection/mapping/methodsFromObject.kt
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.memberFunctions
|
||||
import kotlin.reflect.jvm.javaMethod
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
annotation class A
|
||||
interface I
|
||||
class C
|
||||
|
||||
interface MyCustomMembers {
|
||||
fun equals(): Boolean
|
||||
fun hashCode(hehe: Int): Int
|
||||
fun toString(hehe: String): Any
|
||||
}
|
||||
|
||||
interface MyCloneable : Cloneable
|
||||
|
||||
fun KClass<*>.functions() = memberFunctions.map { it.javaMethod!!.name }.sorted()
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(listOf("equals", "hashCode", "toString"), A::class.functions())
|
||||
assertEquals(listOf("equals", "hashCode", "toString"), I::class.functions())
|
||||
assertEquals(listOf("equals", "hashCode", "toString"), C::class.functions())
|
||||
|
||||
assertEquals(
|
||||
listOf("equals", "equals", "hashCode", "hashCode", "toString", "toString"),
|
||||
MyCustomMembers::class.functions()
|
||||
)
|
||||
|
||||
// TODO: KT-22923
|
||||
// assertEquals(listOf("clone", "equals", "hashCode", "toString"), MyCloneable::class.functions())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
25
compiler/testData/codegen/box/reflection/methodsFromAny/builtinFunctionsToString.kt
vendored
Normal file
25
compiler/testData/codegen/box/reflection/methodsFromAny/builtinFunctionsToString.kt
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE
|
||||
// FULL_JDK
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import java.util.*
|
||||
|
||||
fun assertToString(s: String, x: Any) {
|
||||
assertEquals(s, x.toString())
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertToString("fun kotlin.collections.Map<K, V>.getOrDefault(K, V): V", Map<*, *>::getOrDefault)
|
||||
assertToString("fun java.util.HashMap<K, V>.getOrDefault(K, V): V", HashMap<*, *>::getOrDefault)
|
||||
|
||||
// TODO: uncomment once KT-11754 is fixed
|
||||
// assertToString("", MutableList<*>::removeAt)
|
||||
|
||||
assertToString("fun kotlin.collections.Collection<E>.contains(E): kotlin.Boolean", Collection<*>::contains)
|
||||
assertToString("fun kotlin.collections.Set<E>.contains(E): kotlin.Boolean", Set<*>::contains)
|
||||
|
||||
assertToString("fun kotlin.collections.Collection<E>.isEmpty(): kotlin.Boolean", Collection<*>::isEmpty)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
// WITH_REFLECT
|
||||
// FULL_JDK
|
||||
// See KT-11258 Incorrect resolution sequence for Java field
|
||||
|
||||
// TODO: enable this test on JVM, see KT-16616
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun box(): String {
|
||||
listOf(
|
||||
ArrayList::class,
|
||||
LinkedList::class,
|
||||
AbstractList::class,
|
||||
HashSet::class,
|
||||
TreeSet::class,
|
||||
HashMap::class,
|
||||
TreeMap::class,
|
||||
AbstractMap::class,
|
||||
AbstractMap.SimpleEntry::class
|
||||
).map {
|
||||
it.members.map(Any::toString)
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
39
compiler/testData/codegen/box/sam/kt24825.kt
vendored
Normal file
39
compiler/testData/codegen/box/sam/kt24825.kt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: JavaClass.java
|
||||
public class JavaClass {
|
||||
public static void run(Runnable l) {
|
||||
l.run();
|
||||
}
|
||||
|
||||
public static void s(Runnable a, Runnable onError) {
|
||||
a.run();
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
var state = ""
|
||||
|
||||
fun unit() {}
|
||||
|
||||
class B {
|
||||
val s = mutableListOf<Unit>()
|
||||
|
||||
init {
|
||||
s.add(JavaClass.s({ state += "O" }, ::unit))
|
||||
|
||||
Any().apply {
|
||||
JavaClass.run {
|
||||
s.add(JavaClass.s({ state += "K" }, ::unit))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
B()
|
||||
return state
|
||||
}
|
||||
@@ -1,3 +1,10 @@
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
@kotlin.OptionalExpectation
|
||||
annotation class Anno {
|
||||
public abstract method s(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public interface Foo$Nested {
|
||||
inner class Foo$Nested
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user