mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-21 00:21:29 +00:00
Compare commits
1 Commits
dump-model
...
rr/mitropo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a4eee7b36 |
12
.bunch
12
.bunch
@@ -1,7 +1,7 @@
|
||||
201
|
||||
202
|
||||
203_202
|
||||
193
|
||||
as40_193
|
||||
as41
|
||||
as42_202
|
||||
201
|
||||
202_201
|
||||
192
|
||||
as36_192
|
||||
as40
|
||||
as41_201
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -3,6 +3,5 @@
|
||||
* text=auto
|
||||
* eol=lf
|
||||
*.png binary
|
||||
*.jar binary
|
||||
compiler/cli/bin/* eol=lf
|
||||
compiler/cli/bin/*.bat eol=crlf
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -59,6 +59,3 @@ node_modules/
|
||||
.rpt2_cache/
|
||||
libraries/tools/kotlin-test-js-runner/lib/
|
||||
local.properties
|
||||
buildSrcTmp/
|
||||
distTmp/
|
||||
outTmp/
|
||||
|
||||
15
.idea/codeStyles/Project.xml
generated
15
.idea/codeStyles/Project.xml
generated
@@ -13,6 +13,21 @@
|
||||
</option>
|
||||
</JavaCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="java.util" alias="false" withSubpackages="false" />
|
||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<MarkdownNavigatorCodeStyleSettings>
|
||||
|
||||
3
.idea/dictionaries/yan.xml
generated
3
.idea/dictionaries/yan.xml
generated
@@ -10,10 +10,7 @@
|
||||
<w>kapt</w>
|
||||
<w>kotlinc</w>
|
||||
<w>mutators</w>
|
||||
<w>parcelable</w>
|
||||
<w>parceler</w>
|
||||
<w>parcelers</w>
|
||||
<w>parcelize</w>
|
||||
<w>repl</w>
|
||||
<w>testdata</w>
|
||||
<w>uast</w>
|
||||
|
||||
20
.idea/runConfigurations/Test__KMM.xml
generated
20
.idea/runConfigurations/Test__KMM.xml
generated
@@ -1,20 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test: KMM" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="kmmTest" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -4,13 +4,12 @@
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="--tests "org.jetbrains.kotlin.js.test.ApiTest" -Poverwrite.output=true --parallel" />
|
||||
<option name="scriptParameters" value="--tests "org.jetbrains.kotlin.js.test.ApiTest" -Poverwrite.output=true" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value=":js:js.tests:cleanTest" />
|
||||
<option value=":js:js.tests:test" />
|
||||
</list>
|
||||
</option>
|
||||
|
||||
2
.idea/scopes/Apply_copyright.xml
generated
2
.idea/scopes/Apply_copyright.xml
generated
@@ -1,3 +1,3 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="Apply copyright" pattern="!file[*]:*//testData//*&&!file[*]:testData//*&&!file[*]:*.gradle.kts&&!file[*]:*.gradle&&!file[group:kotlin-ultimate]:*/&&!file[kotlin.libraries]:stdlib/api//*" />
|
||||
<scope name="Apply copyright" pattern="!file[*]:*//testData//*&&!file[*]:testData//*&&!file[*]:*.gradle.kts&&!file[*]:*.gradle&&!file[kotlin.kotlin-ultimate]:*/&&!file[kotlin.kotlin-ultimate.*]:*/&&!file[kotlin.libraries]:stdlib/api//*" />
|
||||
</component>
|
||||
1397
ChangeLog.md
1397
ChangeLog.md
File diff suppressed because it is too large
Load Diff
19
ReadMe.md
19
ReadMe.md
@@ -18,16 +18,6 @@ Welcome to [Kotlin](https://kotlinlang.org/)! Some handy links:
|
||||
* [Public Slack channel](https://slack.kotlinlang.org/)
|
||||
* [TeamCity CI build](https://teamcity.jetbrains.com/project.html?tab=projectOverview&projectId=Kotlin)
|
||||
|
||||
## Kotlin Multiplatform capabilities
|
||||
|
||||
Support for multiplatform programming is one of Kotlin’s key benefits. It reduces time spent writing and maintaining the same code for [different platforms](https://kotlinlang.org/docs/reference/mpp-supported-platforms.html) while retaining the flexibility and benefits of native programming.
|
||||
|
||||
* [Kotlin Multiplatform Mobile](https://kotlinlang.org/lp/mobile/) for sharing code between Android and iOS
|
||||
* [Getting Started with Kotlin Multiplatform Mobile Guide](https://kotlinlang.org/docs/mobile/create-first-app.html)
|
||||
* [Kotlin Multiplatform Benefits](https://kotlinlang.org/docs/reference/multiplatform.html)
|
||||
* [Share code on all platforms](https://kotlinlang.org/docs/reference/mpp-share-on-platforms.html#share-code-on-all-platforms)
|
||||
* [Share code on similar platforms](https://kotlinlang.org/docs/reference/mpp-share-on-platforms.html#share-code-on-similar-platforms)
|
||||
|
||||
## Editing Kotlin
|
||||
|
||||
* [Kotlin IntelliJ IDEA Plugin](https://kotlinlang.org/docs/tutorials/getting-started.html)
|
||||
@@ -51,12 +41,7 @@ For local development, if you're not working on bytecode generation or the stand
|
||||
|
||||
You also can use [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties) to setup `JDK_*` variables.
|
||||
|
||||
Note: The JDK 6 for MacOS is not available on Oracle's site. You can install it by
|
||||
|
||||
```bash
|
||||
$ brew tap caskroom/versions
|
||||
$ brew cask install java6
|
||||
```
|
||||
> Note: The JDK 6 for MacOS is not available on Oracle's site. You can [download it here](https://support.apple.com/kb/DL1572).
|
||||
|
||||
On Windows you might need to add long paths setting to the repo:
|
||||
|
||||
@@ -96,8 +81,6 @@ command line parameters on the first run:
|
||||
- `compilerTest` - build and run all compiler tests
|
||||
- `ideaPluginTest` - build and run all IDEA plugin tests
|
||||
|
||||
To reproduce TeamCity build use `-Pteamcity=true` flag. Local builds don't run proguard and have jar compression disabled by default.
|
||||
|
||||
**OPTIONAL:** Some artifacts, mainly Maven plugin ones, are built separately with Maven.
|
||||
Refer to [libraries/ReadMe.md](libraries/ReadMe.md) for details.
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@ buildscript {
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
if (cacheRedirectorEnabled) {
|
||||
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlinx")
|
||||
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev")
|
||||
} else {
|
||||
maven("https://dl.bintray.com/kotlin/kotlinx")
|
||||
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
@@ -28,15 +30,16 @@ repositories {
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
if (cacheRedirectorEnabled) {
|
||||
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlinx")
|
||||
} else {
|
||||
maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev")
|
||||
} else {
|
||||
maven("https://dl.bintray.com/kotlin/kotlinx")
|
||||
maven("https://dl.bintray.com/kotlin/kotlin-dev")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(kotlinStdlib())
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(projectTests(":compiler:tests-common"))
|
||||
compile(project(":compiler:cli"))
|
||||
compile(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compile(jpsStandalone()) { includeJars("jps-model") }
|
||||
@@ -70,7 +73,6 @@ benchmark {
|
||||
param("size", 1000)
|
||||
|
||||
include("CommonCallsBenchmark")
|
||||
include("ControlFlowAnalysisBenchmark")
|
||||
//include("InferenceBaselineCallsBenchmark")
|
||||
}
|
||||
|
||||
@@ -93,52 +95,3 @@ benchmark {
|
||||
register("main")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("classes") {
|
||||
doLast {
|
||||
tasks.named("mainBenchmarkJar", Zip::class.java) {
|
||||
isZip64 = true
|
||||
archiveName = "benchmarks.jar"
|
||||
}
|
||||
listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark").forEach {
|
||||
tasks.named(it, JavaExec::class.java) {
|
||||
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<JavaExec>("runBenchmark") {
|
||||
// jmhArgs example: -PjmhArgs='CommonCalls -p size=500 -p isIR=true -p useNI=true -f 1'
|
||||
val jmhArgs = if (project.hasProperty("jmhArgs")) project.property("jmhArgs").toString() else ""
|
||||
val resultFilePath = "$buildDir/benchmarks/jmh-result.json"
|
||||
val ideaHome = intellijRootDir().canonicalPath
|
||||
|
||||
val benchmarkJarPath = "$buildDir/benchmarks/main/jars/benchmarks.jar"
|
||||
args = mutableListOf("-Didea.home.path=$ideaHome", benchmarkJarPath, "-rf", "json", "-rff", resultFilePath) + jmhArgs.split("\\s".toRegex())
|
||||
main = "-jar"
|
||||
|
||||
doLast {
|
||||
if (project.kotlinBuildProperties.isTeamcityBuild) {
|
||||
val jsonArray = com.google.gson.JsonParser.parseString(File(resultFilePath).readText()).asJsonArray
|
||||
jsonArray.forEach {
|
||||
val benchmark = it.asJsonObject
|
||||
// remove unnecessary name parts from string like this "org.jetbrains.kotlin.benchmarks.CommonCallsBenchmark.benchmark"
|
||||
val name = benchmark["benchmark"].asString.removeSuffix(".benchmark").let {
|
||||
val indexOfLastDot = it.indexOfLast { it == '.' }
|
||||
it.removeRange(0..indexOfLastDot)
|
||||
}
|
||||
val params = benchmark["params"].asJsonObject
|
||||
val isIR = if (params.has("isIR")) params["isIR"].asString else "false"
|
||||
val useNI = if (params.has("useNI")) params["useNI"].asString else "false"
|
||||
val size = params["size"].asString
|
||||
val score = "%.3f".format(benchmark["primaryMetric"].asJsonObject["score"].asString.toFloat())
|
||||
|
||||
val irPostfix = if (isIR.toBoolean()) " isIR=true" else ""
|
||||
val niPostfix = if (useNI.toBoolean() && !isIR.toBoolean()) " isNI=true" else ""
|
||||
|
||||
println("""##teamcity[buildStatisticValue key='$name size=$size${irPostfix}$niPostfix' value='$score']""")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package org.jetbrains.kotlin.benchmarks
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.CharsetToolkit
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
@@ -12,6 +13,7 @@ import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
@@ -24,15 +26,21 @@ import org.jetbrains.kotlin.context.withModule
|
||||
import org.jetbrains.kotlin.context.withProject
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.createSession
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
|
||||
import org.jetbrains.kotlin.fir.java.FirLibrarySession
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.storage.ExceptionTracker
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
@@ -103,7 +111,9 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
)
|
||||
|
||||
if (isIR) {
|
||||
PsiElementFinder.EP.getPoint(env.project).unregisterExtension(JavaElementFinder::class.java)
|
||||
Extensions.getArea(env.project)
|
||||
.getExtensionPoint(PsiElementFinder.EP_NAME)
|
||||
.unregisterExtension(JavaElementFinder::class.java)
|
||||
}
|
||||
|
||||
file = createFile(
|
||||
@@ -152,7 +162,7 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
|
||||
val session = createSession(env, scope)
|
||||
val firProvider = session.firProvider as FirProviderImpl
|
||||
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider)
|
||||
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
|
||||
|
||||
val totalTransformer = FirTotalResolveProcessor(session)
|
||||
val firFile = builder.buildFirFile(file).also(firProvider::recordFile)
|
||||
@@ -160,10 +170,43 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
totalTransformer.process(listOf(firFile))
|
||||
|
||||
bh.consume(firFile.hashCode())
|
||||
env.project.extensionArea
|
||||
.getExtensionPoint<PsiElementFinder>(PsiElementFinder.EP.name)
|
||||
.unregisterExtension(FirJavaElementFinder::class.java)
|
||||
}
|
||||
|
||||
protected abstract fun buildText(): String
|
||||
}
|
||||
|
||||
fun createSession(
|
||||
environment: KotlinCoreEnvironment,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope)
|
||||
): FirSession {
|
||||
val moduleInfo = FirTestModuleInfo()
|
||||
val project = environment.project
|
||||
val provider = FirProjectSessionProvider(project)
|
||||
return FirJavaModuleBasedSession.create(moduleInfo, provider, sourceScope).also {
|
||||
createSessionForDependencies(provider, moduleInfo, librariesScope, environment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSessionForDependencies(
|
||||
provider: FirProjectSessionProvider,
|
||||
moduleInfo: FirTestModuleInfo,
|
||||
librariesScope: GlobalSearchScope,
|
||||
environment: KotlinCoreEnvironment
|
||||
) {
|
||||
val dependenciesInfo = FirTestModuleInfo()
|
||||
moduleInfo.dependencies.add(dependenciesInfo)
|
||||
FirLibrarySession.create(
|
||||
dependenciesInfo, provider, librariesScope, environment.project,
|
||||
environment.createPackagePartProvider(librariesScope)
|
||||
)
|
||||
}
|
||||
|
||||
class FirTestModuleInfo(
|
||||
override val name: Name = Name.identifier("TestModule"),
|
||||
val dependencies: MutableList<ModuleInfo> = mutableListOf(),
|
||||
override val platform: TargetPlatform = JvmPlatforms.unspecifiedJvmPlatform,
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices = JvmPlatformAnalyzerServices
|
||||
) : ModuleInfo {
|
||||
override fun dependencies(): List<ModuleInfo> = dependencies
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.benchmarks
|
||||
|
||||
import org.openjdk.jmh.annotations.*
|
||||
import org.openjdk.jmh.infra.Blackhole
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
open class ControlFlowAnalysisBenchmark : AbstractSimpleFileBenchmark() {
|
||||
@Param("1000")
|
||||
private var size: Int = 0
|
||||
|
||||
@Benchmark
|
||||
fun benchmark(bh: Blackhole) {
|
||||
analyzeGreenFile(bh)
|
||||
}
|
||||
|
||||
override fun buildText() =
|
||||
buildString {
|
||||
appendLine("fun test() {")
|
||||
for (i in 0 until size) {
|
||||
appendLine("for (i$i in 0..10) { ")
|
||||
}
|
||||
for (i in 0 until size) {
|
||||
appendLine("}")
|
||||
}
|
||||
appendLine("}")
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":core:util.runtime"))
|
||||
compileOnly(project(":compiler:backend.common.jvm"))
|
||||
compileOnly(project(":compiler:util"))
|
||||
compileOnly(project(":compiler:cli-common"))
|
||||
compileOnly(project(":compiler:frontend.java"))
|
||||
|
||||
@@ -75,7 +75,7 @@ open class IncrementalJsCache(
|
||||
override fun markDirty(removedAndCompiledSources: Collection<File>) {
|
||||
removedAndCompiledSources.forEach { sourceFile ->
|
||||
// The common prefix of all FQN parents has to be the file package
|
||||
sourceToClassesMap[sourceFile].map { it.parentOrNull()?.asString() ?: "" }.minByOrNull { it.length }?.let {
|
||||
sourceToClassesMap[sourceFile].map { it.parentOrNull()?.asString() ?: "" }.minBy { it.length }?.let {
|
||||
packageMetadata.remove(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,8 +168,6 @@ open class IncrementalJvmCache(
|
||||
constantsMap.process(kotlinClass, changesCollector)
|
||||
inlineFunctionsMap.process(kotlinClass, changesCollector)
|
||||
}
|
||||
KotlinClassHeader.Kind.UNKNOWN, KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.metadata.java.JavaClassProtoBuf
|
||||
@@ -41,7 +41,7 @@ class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeri
|
||||
childSerializer: DescriptorSerializer
|
||||
) {
|
||||
super.serializeClass(descriptor, proto, versionRequirementTable, childSerializer)
|
||||
if (descriptor.visibility == JavaDescriptorVisibilities.PACKAGE_VISIBILITY) {
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateClass, true)
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeri
|
||||
proto: ProtoBuf.Constructor.Builder,
|
||||
childSerializer: DescriptorSerializer) {
|
||||
super.serializeConstructor(descriptor, proto, childSerializer)
|
||||
if (descriptor.visibility == JavaDescriptorVisibilities.PACKAGE_VISIBILITY) {
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateConstructor, true)
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeri
|
||||
childSerializer: DescriptorSerializer
|
||||
) {
|
||||
super.serializeFunction(descriptor, proto, versionRequirementTable, childSerializer)
|
||||
if (descriptor.visibility == JavaDescriptorVisibilities.PACKAGE_VISIBILITY) {
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateMethod, true)
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeri
|
||||
childSerializer: DescriptorSerializer
|
||||
) {
|
||||
super.serializeProperty(descriptor, proto, versionRequirementTable, childSerializer)
|
||||
if (descriptor.visibility == JavaDescriptorVisibilities.PACKAGE_VISIBILITY) {
|
||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateField, true)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
class LocalFileKotlinClass private constructor(
|
||||
private val file: File,
|
||||
private val fileContents: ByteArray,
|
||||
className: ClassId,
|
||||
classVersion: Int,
|
||||
classHeader: KotlinClassHeader,
|
||||
innerClasses: InnerClassesInfo
|
||||
private val file: File,
|
||||
private val fileContents: ByteArray,
|
||||
className: ClassId,
|
||||
classVersion: Int,
|
||||
classHeader: KotlinClassHeader,
|
||||
innerClasses: InnerClassesInfo
|
||||
) : FileBasedKotlinClass(className, classVersion, classHeader, innerClasses) {
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -80,7 +80,7 @@ open class LookupStorage(
|
||||
|
||||
for (lookupSymbol in lookups.keySet().sorted()) {
|
||||
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
|
||||
val paths = lookups[lookupSymbol]
|
||||
val paths = lookups[lookupSymbol]!!
|
||||
val fileIds = paths.mapTo(TreeSet()) { pathToId[it]!! }
|
||||
fileIds.addAll(lookupMap[key] ?: emptySet())
|
||||
lookupMap[key] = fileIds
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("UNUSED_PARAMETER")
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.incremental.ProtoCompareGenerated.ProtoBufClassKind
|
||||
import org.jetbrains.kotlin.incremental.ProtoCompareGenerated.ProtoBufPackageKind
|
||||
import org.jetbrains.kotlin.incremental.storage.ProtoMapValue
|
||||
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptorVisibility
|
||||
import java.util.*
|
||||
|
||||
data class Difference(
|
||||
@@ -50,8 +49,8 @@ fun ProtoMapValue.toProtoData(packageFqName: FqName): ProtoData =
|
||||
}
|
||||
|
||||
internal val MessageLite.isPrivate: Boolean
|
||||
get() = DescriptorVisibilities.isPrivate(
|
||||
ProtoEnumFlags.descriptorVisibility(
|
||||
get() = Visibilities.isPrivate(
|
||||
ProtoEnumFlags.visibility(
|
||||
when (this) {
|
||||
is ProtoBuf.Constructor -> Flags.VISIBILITY.get(flags)
|
||||
is ProtoBuf.Function -> Flags.VISIBILITY.get(flags)
|
||||
@@ -347,4 +346,4 @@ val ProtoBuf.Class.typeTableOrNull: ProtoBuf.TypeTable?
|
||||
get() = if (hasTypeTable()) typeTable else null
|
||||
|
||||
val ProtoBuf.Package.typeTableOrNull: ProtoBuf.TypeTable?
|
||||
get() = if (hasTypeTable()) typeTable else null
|
||||
get() = if (hasTypeTable()) typeTable else null
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import java.io.File
|
||||
|
||||
open class IncrementalFileToPathConverter(val rootProjectDir: File?) : FileToPathConverter {
|
||||
//project root dir
|
||||
private val projectDirPath = rootProjectDir?.normalize()?.absolutePath
|
||||
|
||||
override fun toPath(file: File): String {
|
||||
val path = file.normalize().absolutePath
|
||||
return when {
|
||||
projectDirPath == null || !path.startsWith(projectDirPath) -> path
|
||||
else -> PROJECT_DIR_PLACEHOLDER + path.substring(projectDirPath.length)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toFile(path: String): File =
|
||||
when {
|
||||
rootProjectDir != null && path.startsWith(PROJECT_DIR_PLACEHOLDER) -> rootProjectDir.resolve(path.substring(PATH_PREFIX.length))
|
||||
else -> File(path)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val PROJECT_DIR_PLACEHOLDER = "${'$'}PROJECT_DIR$"
|
||||
private const val PATH_PREFIX = "$PROJECT_DIR_PLACEHOLDER/"
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import com.intellij.util.io.JpsPersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@ class NonCachingLazyStorage<K, V>(
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
private var storage: JpsPersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
@@ -43,7 +43,7 @@ class NonCachingLazyStorage<K, V>(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class NonCachingLazyStorage<K, V>(
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
|
||||
getStorageOrCreateNew().appendDataWithoutCache(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -79,7 +79,7 @@ class NonCachingLazyStorage<K, V>(
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@@ -101,6 +101,6 @@ class NonCachingLazyStorage<K, V>(
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
private fun createMap(): JpsPersistentHashMap<K, V> =
|
||||
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.JpsPersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
class NonCachingLazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: JpsPersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
storage = createMap()
|
||||
return storage
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendDataWithoutCache(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
} else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): JpsPersistentHashMap<K, V> =
|
||||
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
class NonCachingLazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
storage = createMap()
|
||||
return storage
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
} else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.TestWithWorkingDir
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
internal class IncrementalFileToPathConverterTest : TestWithWorkingDir() {
|
||||
|
||||
@Test
|
||||
fun testPathTransform() {
|
||||
val relativeFilePath = "testFile.txt"
|
||||
val transformedPath = testPathTransformation(workingDir.resolve("testDir"), relativeFilePath)
|
||||
|
||||
assertEquals("${'$'}PROJECT_DIR${'$'}/$relativeFilePath", transformedPath)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testComplicatedProjectRootPath() {
|
||||
val relativeFilePath = "testFile.txt"
|
||||
val transformedPath = testPathTransformation(workingDir.resolve("first/../testDir"), relativeFilePath)
|
||||
|
||||
assertEquals("${'$'}PROJECT_DIR${'$'}/$relativeFilePath", transformedPath)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInccorectProjectRootPath() {
|
||||
val relativeFilePath = "testFile.txt"
|
||||
val transformedPath = testPathTransformation(workingDir.resolve("testDir/"), relativeFilePath)
|
||||
|
||||
assertEquals("${'$'}PROJECT_DIR${'$'}/$relativeFilePath", transformedPath)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFileOutOfProject() {
|
||||
val relativeFilePath = "../testFile.txt"
|
||||
val transformedPath = testPathTransformation(workingDir.resolve("testDir"), relativeFilePath)
|
||||
|
||||
assertEquals("${workingDir.absolutePath}/testFile.txt", transformedPath)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFileWithExtraSlash() {
|
||||
val relativeFilePath = "testFile.txt/"
|
||||
val transformedPath = testPathTransformation(workingDir.resolve("testDir"), relativeFilePath)
|
||||
|
||||
assertEquals("${'$'}PROJECT_DIR${'$'}/testFile.txt", transformedPath)
|
||||
}
|
||||
|
||||
private fun testPathTransformation(projectRoot: File, relativeFilePath: String): String {
|
||||
val pathConverter = IncrementalFileToPathConverter(projectRoot)
|
||||
val testFile = projectRoot.resolve(relativeFilePath)
|
||||
val transformedPath = pathConverter.toPath(testFile)
|
||||
assertEquals(testFile.normalize().absolutePath, pathConverter.toFile(transformedPath).normalize().absolutePath)
|
||||
return transformedPath
|
||||
}
|
||||
}
|
||||
@@ -17258,7 +17258,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -17269,7 +17268,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -17465,7 +17463,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -17478,7 +17475,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -17898,7 +17894,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -17911,7 +17906,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -17924,7 +17918,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -17940,7 +17933,6 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
@@ -18315,7 +18307,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -18334,7 +18325,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -18733,7 +18723,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -18754,7 +18743,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -19651,7 +19639,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -19672,7 +19659,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -19693,7 +19679,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -19717,7 +19702,6 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
|
||||
@@ -4656,8 +4656,7 @@ public final class DebugJvmProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.metadata.Class { ... }</code>
|
||||
*
|
||||
* <pre>
|
||||
* first bit: isFunctionBodyInInterface: 0 if actual body generated in DefaultImpl, 1 - otherwise (in interface default method)
|
||||
* second bit: is all-compatibility mode or not, 1 - yes, 0 - no
|
||||
* isFunctionBodyInInterface: 0 if actual body generated in DefaultImpl, 1 - otherwise (in interface default method)
|
||||
* </pre>
|
||||
*/
|
||||
public static final
|
||||
|
||||
251
build.gradle.kts
251
build.gradle.kts
@@ -7,7 +7,7 @@ import proguard.gradle.ProGuardTask
|
||||
buildscript {
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
kotlinBootstrapFrom(BootstrapOption.SpaceBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
|
||||
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
|
||||
|
||||
repositories {
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
@@ -27,10 +27,9 @@ buildscript {
|
||||
dependencies {
|
||||
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
|
||||
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.17")
|
||||
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
|
||||
classpath("org.jetbrains.dokka:dokka-gradle-plugin:0.9.17")
|
||||
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4.17.2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +152,6 @@ rootProject.apply {
|
||||
from(rootProject.file("gradle/jps.gradle.kts"))
|
||||
from(rootProject.file("gradle/checkArtifacts.gradle.kts"))
|
||||
from(rootProject.file("gradle/checkCacheability.gradle.kts"))
|
||||
from(rootProject.file("gradle/retryPublishing.gradle.kts"))
|
||||
}
|
||||
|
||||
IdeVersionConfigurator.setCurrentIde(project)
|
||||
@@ -178,8 +176,8 @@ extra["versions.org.springframework"] = "4.2.0.RELEASE"
|
||||
extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.completion-ranking-kotlin"] = "0.1.3"
|
||||
extra["versions.r8"] = "2.0.88"
|
||||
extra["versions.completion-ranking-kotlin"] = "0.1.2"
|
||||
extra["versions.r8"] = "1.5.70"
|
||||
val immutablesVersion = "0.3.1"
|
||||
extra["versions.kotlinx-collections-immutable"] = immutablesVersion
|
||||
extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
||||
@@ -188,13 +186,12 @@ extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.4.30-dev-16766"
|
||||
extra["versions.kotlin-native"] = "1.4-M3-dev-15627"
|
||||
}
|
||||
|
||||
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
|
||||
val effectSystemEnabled by extra(project.getBooleanProperty("kotlin.compiler.effectSystemEnabled") ?: false)
|
||||
val newInferenceEnabled by extra(project.getBooleanProperty("kotlin.compiler.newInferenceEnabled") ?: false)
|
||||
val useJvmIrBackend by extra(project.getBooleanProperty("kotlin.build.useIR") ?: false)
|
||||
|
||||
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
|
||||
|
||||
@@ -222,8 +219,6 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:config",
|
||||
":compiler:config.jvm",
|
||||
":compiler:container",
|
||||
":compiler:resolution.common",
|
||||
":compiler:resolution.common.jvm",
|
||||
":compiler:resolution",
|
||||
":compiler:serialization",
|
||||
":compiler:psi",
|
||||
@@ -232,8 +227,6 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:frontend.java",
|
||||
":compiler:cli-common",
|
||||
":compiler:ir.tree",
|
||||
":compiler:ir.tree.impl",
|
||||
":compiler:ir.tree.persistent",
|
||||
":compiler:ir.psi2ir",
|
||||
":compiler:ir.backend.common",
|
||||
":compiler:backend.jvm",
|
||||
@@ -242,7 +235,6 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:ir.serialization.common",
|
||||
":compiler:ir.serialization.js",
|
||||
":compiler:ir.serialization.jvm",
|
||||
":compiler:ir.interpreter",
|
||||
":kotlin-util-io",
|
||||
":kotlin-util-klib",
|
||||
":kotlin-util-klib-metadata",
|
||||
@@ -268,22 +260,17 @@ extra["compilerModules"] = arrayOf(
|
||||
":kotlin-build-common",
|
||||
":core:metadata",
|
||||
":core:metadata.jvm",
|
||||
":core:deserialization.common",
|
||||
":core:deserialization.common.jvm",
|
||||
":core:compiler.common",
|
||||
":core:compiler.common.jvm",
|
||||
":compiler:backend.common.jvm",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":core:descriptors.runtime",
|
||||
":core:deserialization",
|
||||
":core:util.runtime",
|
||||
":core:type-system",
|
||||
":compiler:fir:cones",
|
||||
":compiler:fir:resolve",
|
||||
":compiler:fir:fir-serialization",
|
||||
":compiler:fir:fir-deserialization",
|
||||
":compiler:fir:tree",
|
||||
":compiler:fir:raw-fir:raw-fir.common",
|
||||
":compiler:fir:raw-fir:fir-common",
|
||||
":compiler:fir:raw-fir:psi2fir",
|
||||
":compiler:fir:raw-fir:light-tree2fir",
|
||||
":compiler:fir:fir2ir",
|
||||
@@ -291,11 +278,11 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:fir:java",
|
||||
":compiler:fir:jvm",
|
||||
":compiler:fir:checkers",
|
||||
":compiler:fir:entrypoint",
|
||||
":compiler:fir:analysis-tests"
|
||||
)
|
||||
|
||||
extra["compilerModulesForJps"] = listOf(
|
||||
":core:type-system",
|
||||
":kotlin-build-common",
|
||||
":kotlin-util-io",
|
||||
":kotlin-util-klib",
|
||||
@@ -304,8 +291,6 @@ extra["compilerModulesForJps"] = listOf(
|
||||
":kotlin-compiler-runner",
|
||||
":daemon-common",
|
||||
":daemon-common-new",
|
||||
":core:compiler.common",
|
||||
":core:compiler.common.jvm",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":idea:idea-jps-common",
|
||||
@@ -322,6 +307,7 @@ val coreLibProjects = listOfNotNull(
|
||||
":kotlin-stdlib",
|
||||
":kotlin-stdlib-common",
|
||||
":kotlin-stdlib-js",
|
||||
":kotlin-stdlib-js-ir",
|
||||
":kotlin-stdlib-jdk7",
|
||||
":kotlin-stdlib-jdk8",
|
||||
":kotlin-test:kotlin-test-annotations-common",
|
||||
@@ -331,6 +317,7 @@ val coreLibProjects = listOfNotNull(
|
||||
":kotlin-test:kotlin-test-junit5",
|
||||
":kotlin-test:kotlin-test-testng",
|
||||
":kotlin-test:kotlin-test-js".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
|
||||
":kotlin-test:kotlin-test-js-ir".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
|
||||
":kotlin-reflect",
|
||||
":kotlin-coroutines-experimental-compat"
|
||||
)
|
||||
@@ -341,8 +328,7 @@ val gradlePluginProjects = listOf(
|
||||
":kotlin-allopen",
|
||||
":kotlin-annotation-processing-gradle",
|
||||
":kotlin-noarg",
|
||||
":kotlin-sam-with-receiver",
|
||||
":kotlin-parcelize-compiler"
|
||||
":kotlin-sam-with-receiver"
|
||||
)
|
||||
|
||||
apply {
|
||||
@@ -366,7 +352,7 @@ fun Task.listConfigurationContents(configName: String) {
|
||||
}
|
||||
|
||||
val defaultJvmTarget = "1.8"
|
||||
val defaultJavaHome = jdkPath(if (Platform[203].orHigher()) "11" else defaultJvmTarget)
|
||||
val defaultJavaHome = jdkPath(defaultJvmTarget)
|
||||
val ignoreTestFailures by extra(project.kotlinBuildProperties.ignoreTestFailures)
|
||||
|
||||
allprojects {
|
||||
@@ -380,15 +366,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
configurations.maybeCreate("embeddedElements").apply {
|
||||
extendsFrom(configurations["embedded"])
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named("embedded-java-runtime"))
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = defaultJvmTarget
|
||||
javaHome = defaultJavaHome
|
||||
|
||||
@@ -419,6 +396,9 @@ allprojects {
|
||||
val commonCompilerArgs = listOfNotNull(
|
||||
"-Xopt-in=kotlin.RequiresOptIn",
|
||||
"-Xread-deserialized-contracts",
|
||||
"-Xjvm-default=compatibility",
|
||||
"-Xno-optimized-callable-references",
|
||||
"-Xno-kotlin-nothing-value-exception",
|
||||
"-progressive".takeIf { hasProperty("test.progressive.mode") }
|
||||
)
|
||||
|
||||
@@ -430,21 +410,9 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
val jvmCompilerArgs = listOf(
|
||||
"-Xjvm-default=compatibility",
|
||||
"-Xno-optimized-callable-references",
|
||||
"-Xno-kotlin-nothing-value-exception",
|
||||
"-Xnormalize-constructor-calls=enable"
|
||||
)
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = commonCompilerArgs + jvmCompilerArgs
|
||||
|
||||
if (useJvmIrBackend) {
|
||||
useIR = true
|
||||
freeCompilerArgs += "-Xir-binary-with-stable-abi"
|
||||
}
|
||||
freeCompilerArgs = commonCompilerArgs + listOf("-Xnormalize-constructor-calls=enable")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +442,6 @@ allprojects {
|
||||
ignore("META-INF/MANIFEST.MF")
|
||||
ignore("META-INF/compiler.version")
|
||||
ignore("META-INF/plugin.xml")
|
||||
ignore("kotlin/KotlinVersionCurrentValue.class")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,23 +491,6 @@ allprojects {
|
||||
}
|
||||
|
||||
apply(from = "$rootDir/gradle/cacheRedirector.gradle.kts")
|
||||
apply(from = "$rootDir/gradle/testRetry.gradle.kts")
|
||||
}
|
||||
}
|
||||
|
||||
gradle.buildFinished {
|
||||
val taskGraph = gradle?.taskGraph
|
||||
if (taskGraph != null) {
|
||||
taskGraph.allTasks
|
||||
.filterIsInstance<SourceTask>()
|
||||
.filter { it.didWork }
|
||||
.forEach {
|
||||
it.source.visit {
|
||||
if (file.isDirectory && file.listFiles()?.isEmpty() == true) {
|
||||
logger.warn("Empty source directories may cause build cache misses: " + file.absolutePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,12 +498,9 @@ gradle.taskGraph.whenReady {
|
||||
fun Boolean.toOnOff(): String = if (this) "on" else "off"
|
||||
val profile = if (isTeamcityBuild) "CI" else "Local"
|
||||
|
||||
val proguardMessage = "proguard is ${kotlinBuildProperties.proguard.toOnOff()}"
|
||||
val jarCompressionMessage = "jar compression is ${kotlinBuildProperties.jarCompression.toOnOff()}"
|
||||
val profileMessage = "$profile build profile is active ($proguardMessage, $jarCompressionMessage). " +
|
||||
"Use -Pteamcity=<true|false> to reproduce CI/local build"
|
||||
|
||||
logger.warn("\n\n$profileMessage")
|
||||
logger.warn("$profile build profile is active (proguard is ${kotlinBuildProperties.proguard.toOnOff()}" +
|
||||
", jar compression is ${kotlinBuildProperties.jarCompression.toOnOff()})." +
|
||||
" Use -Pteamcity=<true|false> to reproduce CI/local build")
|
||||
|
||||
allTasks.filterIsInstance<org.gradle.jvm.tasks.Jar>().forEach { task ->
|
||||
task.entryCompression = if (kotlinBuildProperties.jarCompression)
|
||||
@@ -567,10 +514,6 @@ val dist = tasks.register("dist") {
|
||||
dependsOn(":kotlin-compiler:dist")
|
||||
}
|
||||
|
||||
val syncMutedTests = tasks.register("syncMutedTests") {
|
||||
dependsOn(":compiler:tests-mutes:run")
|
||||
}
|
||||
|
||||
val copyCompilerToIdeaPlugin by task<Copy> {
|
||||
dependsOn(dist)
|
||||
into(ideaPluginDir)
|
||||
@@ -596,7 +539,7 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
listOf("clean", "assemble", "install").forEach { taskName ->
|
||||
listOf("clean", "assemble", "install", "dist").forEach { taskName ->
|
||||
register("coreLibs${taskName.capitalize()}") {
|
||||
coreLibProjects.forEach { projectName -> dependsOn("$projectName:$taskName") }
|
||||
}
|
||||
@@ -605,8 +548,6 @@ tasks {
|
||||
register("coreLibsTest") {
|
||||
(coreLibProjects + listOf(
|
||||
":kotlin-stdlib:samples",
|
||||
":kotlin-stdlib-js-ir",
|
||||
":kotlin-test:kotlin-test-js-ir".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
|
||||
":kotlin-test:kotlin-test-js:kotlin-test-js-it".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
|
||||
":kotlinx-metadata-jvm",
|
||||
":tools:binary-compatibility-validator"
|
||||
@@ -695,7 +636,6 @@ tasks {
|
||||
dependsOn(":kotlin-scripting-jsr223-test:embeddableTest")
|
||||
dependsOn(":kotlin-main-kts-test:test")
|
||||
dependsOn(":kotlin-scripting-ide-services-test:test")
|
||||
dependsOn(":kotlin-scripting-ide-services-test:embeddableTest")
|
||||
dependsOn(":kotlin-scripting-js-test:test")
|
||||
}
|
||||
|
||||
@@ -714,12 +654,9 @@ tasks {
|
||||
dependsOn("scriptingTest")
|
||||
dependsOn(":kotlin-build-common:test")
|
||||
dependsOn(":compiler:incremental-compilation-impl:test")
|
||||
dependsOn(":compiler:incremental-compilation-impl:testJvmICWithJdk11")
|
||||
dependsOn(":core:descriptors.runtime:test")
|
||||
|
||||
dependsOn("jvmCompilerIntegrationTest")
|
||||
|
||||
dependsOn(":plugins:parcelize:parcelize-compiler:test")
|
||||
}
|
||||
|
||||
register("toolsTest") {
|
||||
@@ -755,9 +692,16 @@ tasks {
|
||||
dependsOn(":jps-plugin:test")
|
||||
}
|
||||
|
||||
register("idea-plugin-main-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":idea:test")
|
||||
}
|
||||
|
||||
register("idea-plugin-additional-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":idea:idea-gradle:test",
|
||||
":idea:idea-gradle-native:test",
|
||||
":idea:idea-maven:test",
|
||||
":j2k:test",
|
||||
":nj2k:test",
|
||||
@@ -780,6 +724,17 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
register("idea-plugin-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
"idea-plugin-main-tests",
|
||||
"idea-plugin-additional-tests"
|
||||
)
|
||||
if (Ide.IJ()) {
|
||||
dependsOn("idea-new-project-wizard-tests")
|
||||
}
|
||||
}
|
||||
|
||||
register("idea-plugin-performance-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
@@ -787,49 +742,19 @@ tasks {
|
||||
)
|
||||
}
|
||||
|
||||
register("idea-fir-plugin-performance-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":idea:idea-fir-performance-tests:ideaFirPerformanceTest"
|
||||
)
|
||||
}
|
||||
|
||||
register("idea-fir-plugin-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":idea:idea-fir:test",
|
||||
":idea:idea-frontend-api:test",
|
||||
":idea:idea-frontend-fir:test",
|
||||
":idea:idea-frontend-fir:idea-fir-low-level-api:test"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
register("android-ide-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":plugins:android-extensions-ide:test",
|
||||
":idea:idea-android:test",
|
||||
":kotlin-annotation-processing:test"
|
||||
)
|
||||
}
|
||||
|
||||
register("plugins-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":kotlin-annotation-processing:test",
|
||||
":plugins:parcelize:parcelize-ide:test"
|
||||
)
|
||||
}
|
||||
|
||||
register("ideaPluginTest") {
|
||||
dependsOn(
|
||||
"mainIdeTests",
|
||||
"gradleIdeTest",
|
||||
"kaptIdeTest",
|
||||
"miscIdeTests"
|
||||
)
|
||||
}
|
||||
|
||||
register("mainIdeTests") {
|
||||
dependsOn(":idea:test")
|
||||
}
|
||||
|
||||
register("miscIdeTests") {
|
||||
dependsOn(
|
||||
":kotlin-allopen-compiler-plugin:test",
|
||||
":kotlin-noarg-compiler-plugin:test",
|
||||
":kotlin-sam-with-receiver-compiler-plugin:test",
|
||||
@@ -837,58 +762,19 @@ tasks {
|
||||
":kotlin-annotation-processing-gradle:test",
|
||||
":kotlinx-serialization-compiler-plugin:test",
|
||||
":kotlinx-serialization-ide-plugin:test",
|
||||
":idea:jvm-debugger:jvm-debugger-test:test",
|
||||
"idea-plugin-additional-tests",
|
||||
":idea:jvm-debugger:jvm-debugger-test:test"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
register("ideaPluginTest") {
|
||||
dependsOn(
|
||||
"idea-plugin-tests",
|
||||
"jps-tests",
|
||||
"plugins-tests",
|
||||
"android-ide-tests",
|
||||
":generators:test"
|
||||
)
|
||||
if (Ide.IJ()) {
|
||||
dependsOn("idea-new-project-wizard-tests")
|
||||
}
|
||||
}
|
||||
|
||||
register("kaptIdeTest") {
|
||||
dependsOn(":kotlin-annotation-processing:test")
|
||||
}
|
||||
|
||||
register("gradleIdeTest") {
|
||||
dependsOn(
|
||||
":idea:idea-gradle:test",
|
||||
":idea:idea-gradle-native:test"
|
||||
)
|
||||
}
|
||||
|
||||
register("kmmTest", AggregateTest::class) {
|
||||
dependsOn(
|
||||
":idea:idea-gradle:test",
|
||||
":idea:test",
|
||||
":compiler:test",
|
||||
":js:js.tests:test"
|
||||
)
|
||||
if (Ide.IJ193.orHigher())
|
||||
dependsOn(":kotlin-gradle-plugin-integration-tests:test")
|
||||
if (Ide.AS40.orHigher())
|
||||
dependsOn(":kotlin-ultimate:ide:android-studio-native:test")
|
||||
|
||||
testPatternFile = file("tests/mpp/kmm-patterns.csv")
|
||||
}
|
||||
|
||||
register("test") {
|
||||
doLast {
|
||||
throw GradleException("Don't use directly, use aggregate tasks *-check instead")
|
||||
}
|
||||
}
|
||||
|
||||
named("check") {
|
||||
dependsOn("test")
|
||||
}
|
||||
|
||||
named("checkBuild") {
|
||||
if (kotlinBuildProperties.isTeamcityBuild) {
|
||||
doFirst {
|
||||
println("##teamcity[setParameter name='bootstrap.kotlin.version' value='$bootstrapKotlinVersion']")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register("publishIdeArtifacts") {
|
||||
@@ -906,7 +792,6 @@ tasks {
|
||||
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:compiler-components-for-jps:publish",
|
||||
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide:publish",
|
||||
":kotlin-script-runtime:publish",
|
||||
":kotlin-script-util:publish",
|
||||
":kotlin-scripting-common:publish",
|
||||
@@ -919,12 +804,28 @@ tasks {
|
||||
":kotlin-stdlib-jdk7:publish",
|
||||
":kotlin-stdlib-jdk8:publish",
|
||||
":kotlin-reflect:publish",
|
||||
":kotlin-main-kts:publish",
|
||||
":kotlin-stdlib-js:publish",
|
||||
":kotlin-test:kotlin-test-js:publish"
|
||||
":kotlin-main-kts:publish"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
register("test") {
|
||||
doLast {
|
||||
throw GradleException("Don't use directly, use aggregate tasks *-check instead")
|
||||
}
|
||||
}
|
||||
|
||||
named("check") {
|
||||
dependsOn("test")
|
||||
}
|
||||
|
||||
named("checkBuild") {
|
||||
if (kotlinBuildProperties.isTeamcityBuild) {
|
||||
doFirst {
|
||||
println("##teamcity[setParameter name='bootstrap.kotlin.version' value='$bootstrapKotlinVersion']")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun CopySpec.setExecutablePermissions() {
|
||||
@@ -988,7 +889,7 @@ val zipPlugin by task<Zip> {
|
||||
setExecutablePermissions()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("Plugin artifacts packed to ${archiveFile.get()}")
|
||||
logger.lifecycle("Plugin artifacts packed to $archiveFile")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1157,4 +1058,4 @@ if (disableVerificationTasks) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ buildscript {
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
extra["defaultSnapshotVersion"] = kotlinBuildProperties.defaultSnapshotVersion
|
||||
kotlinBootstrapFrom(BootstrapOption.SpaceBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
|
||||
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
|
||||
|
||||
repositories {
|
||||
if (cacheRedirectorEnabled) {
|
||||
@@ -22,7 +22,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.17")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
|
||||
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
|
||||
}
|
||||
@@ -96,9 +96,8 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib", embeddedKotlinVersion))
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
|
||||
implementation("com.gradle.publish:plugin-publish-plugin:0.12.0")
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.17")
|
||||
implementation("com.gradle.publish:plugin-publish-plugin:0.11.0")
|
||||
|
||||
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
|
||||
implementation("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
|
||||
@@ -110,8 +109,6 @@ dependencies {
|
||||
implementation("org.jetbrains.intellij.deps:asm-all:8.0.1")
|
||||
|
||||
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
|
||||
|
||||
implementation("org.gradle:test-retry-gradle-plugin:1.1.9")
|
||||
}
|
||||
|
||||
samWithReceiver {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
@file:Suppress("PropertyName", "HasPlatformType", "UnstableApiUsage")
|
||||
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
|
||||
import java.io.Closeable
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.URI
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import javax.xml.stream.XMLOutputFactory
|
||||
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
plugins {
|
||||
base
|
||||
}
|
||||
@@ -179,7 +180,6 @@ val mergeSources by tasks.creating(Jar::class.java) {
|
||||
dependsOn(sources)
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
isZip64 = true
|
||||
if (!kotlinBuildProperties.isTeamcityBuild) {
|
||||
from(provider { sources.map(::zipTree) })
|
||||
}
|
||||
@@ -255,8 +255,9 @@ fun buildIvyRepositoryTask(
|
||||
inputs.files(configuration)
|
||||
|
||||
outputs.upToDateWhen {
|
||||
val repoMarker = configuration.resolvedConfiguration.resolvedArtifacts.single().moduleDirectory().resolve(".marker")
|
||||
repoMarker.exists()
|
||||
configuration.resolvedConfiguration.resolvedArtifacts.single()
|
||||
.moduleDirectory()
|
||||
.exists()
|
||||
}
|
||||
|
||||
doFirst {
|
||||
@@ -265,9 +266,8 @@ fun buildIvyRepositoryTask(
|
||||
|
||||
artifact.storeDirectory().cleanStore()
|
||||
|
||||
val repoMarker = File(moduleDirectory, ".marker")
|
||||
if (repoMarker.exists()) {
|
||||
logger.info("Path ${repoMarker.absolutePath} already exists, skipping unpacking.")
|
||||
if (moduleDirectory.exists()) {
|
||||
logger.info("Path ${moduleDirectory.absolutePath} already exists, skipping unpacking.")
|
||||
return@doFirst
|
||||
}
|
||||
|
||||
@@ -326,8 +326,6 @@ fun buildIvyRepositoryTask(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
repoMarker.createNewFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.17")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ if (target_AppCode_Clion) {
|
||||
} else if (target_AndroidStudio) {
|
||||
logger.info("Including modules for AS (mobile plugin) in buildSrc/settings.gradle")
|
||||
|
||||
include ":prepare-deps:appcode-binaries"
|
||||
include ":prepare-deps:cocoa-common-binaries"
|
||||
include ":prepare-deps:lldb-framework"
|
||||
include ":prepare-deps:lldb-frontend"
|
||||
|
||||
project(":prepare-deps:appcode-binaries").projectDir =
|
||||
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/appcode-binaries")
|
||||
project(":prepare-deps:cocoa-common-binaries").projectDir =
|
||||
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/cocoa-common-binaries")
|
||||
project(":prepare-deps:lldb-framework").projectDir =
|
||||
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-framework")
|
||||
project(":prepare-deps:lldb-frontend").projectDir =
|
||||
@@ -69,4 +69,4 @@ if (target_AppCode_Clion) {
|
||||
|
||||
} else {
|
||||
logger.info("Not including extra modules in buildSrc/settings.gradle")
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import java.io.File
|
||||
|
||||
// You can see "How To" via link: https://jetbrains.quip.com/xQ2WAUy9bZmy/How-to-use-AggregateTest-task
|
||||
open class AggregateTest : Test() { // Inherit from Test to see test results in IDEA Test viewer
|
||||
private var patterns: MutableMap<String, MutableList<String>> = mutableMapOf()
|
||||
|
||||
@InputFile
|
||||
lateinit var testPatternFile: File
|
||||
|
||||
init {
|
||||
// Set empty FileCollection to avoid NPE when initializing a base 'Test' class
|
||||
classpath = project.objects.fileCollection()
|
||||
testClassesDirs = project.objects.fileCollection()
|
||||
|
||||
project.gradle.taskGraph.whenReady {
|
||||
if (allTasks.filterIsInstance<AggregateTest>().isNotEmpty()) {
|
||||
initPatterns()
|
||||
allTasks.filterIsInstance<Test>().forEach { testTask -> subTaskConfigure(testTask) }
|
||||
|
||||
if (!project.gradle.startParameter.taskNames.all { project.tasks.findByPath(it) is AggregateTest }) {
|
||||
logger.warn("Please, don't use AggregateTest and non-AggregateTest test tasks together. You can get incorrect results.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initPatterns() {
|
||||
if (!testPatternFile.exists())
|
||||
throw GradleException("File with test patterns is not found")
|
||||
testPatternFile
|
||||
.readLines()
|
||||
.asSequence()
|
||||
.filter { it.isNotEmpty() }
|
||||
.forEach { line ->
|
||||
// patternType is exclude or include value
|
||||
val (pattern, patternType) = line.split(',').map { it.trim() }
|
||||
patterns.getOrPut(patternType) { mutableListOf() }.add(pattern)
|
||||
}
|
||||
}
|
||||
|
||||
private fun subTaskConfigure(testTask: Test) {
|
||||
testTask.outputs.upToDateWhen { false }
|
||||
testTask.ignoreFailures = true
|
||||
testTask.filter {
|
||||
isFailOnNoMatchingTests = false
|
||||
patterns["include"]?.let {
|
||||
it.forEach { pattern ->
|
||||
includeTestsMatching(pattern)
|
||||
}
|
||||
}
|
||||
patterns["exclude"]?.let {
|
||||
it.forEach { pattern ->
|
||||
excludeTestsMatching(pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@TaskAction
|
||||
override fun executeTests() {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ var Project.javaHome: String?
|
||||
|
||||
fun Project.generator(fqName: String, sourceSet: SourceSet? = null) = smartJavaExec {
|
||||
classpath = (sourceSet ?: testSourceSet).runtimeClasspath
|
||||
mainClass.set(fqName)
|
||||
main = fqName
|
||||
workingDir = rootDir
|
||||
systemProperty("line.separator", "\n")
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ fun CompatibilityPredicate.or(other: CompatibilityPredicate): CompatibilityPredi
|
||||
}
|
||||
|
||||
enum class Platform : CompatibilityPredicate {
|
||||
P183, P191, P192, P193, P201, P202, P203;
|
||||
P183, P191, P192, P193, P201, P202;
|
||||
|
||||
val version: Int = name.drop(1).toInt()
|
||||
|
||||
@@ -48,13 +48,11 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
|
||||
IJ193(Platform.P193),
|
||||
IJ201(Platform.P201),
|
||||
IJ202(Platform.P202),
|
||||
IJ203(Platform.P203),
|
||||
|
||||
AS35(Platform.P183),
|
||||
AS36(Platform.P192),
|
||||
AS40(Platform.P193),
|
||||
AS41(Platform.P201),
|
||||
AS42(Platform.P202);
|
||||
AS41(Platform.P201);
|
||||
|
||||
val kind = Kind.values().first { it.shortName == name.take(2) }
|
||||
val version = name.dropWhile { !it.isDigit() }.toInt()
|
||||
|
||||
@@ -23,10 +23,6 @@ fun JavaExec.passClasspathInJar() {
|
||||
dependsOn(classpath)
|
||||
inputs.files(classpath)
|
||||
inputs.property("main", main)
|
||||
|
||||
archiveFileName.set("$main.${this@passClasspathInJar.name}.classpath.container.jar")
|
||||
destinationDirectory.set(temporaryDir)
|
||||
|
||||
doFirst {
|
||||
val classPathString = classpath.joinToString(" ") { project.file(it).toURI().toString() }
|
||||
manifest {
|
||||
@@ -38,11 +34,16 @@ fun JavaExec.passClasspathInJar() {
|
||||
)
|
||||
}
|
||||
}
|
||||
archiveName = "$main.${this@passClasspathInJar.name}.classpath.container.$extension"
|
||||
destinationDir = temporaryDir
|
||||
}
|
||||
|
||||
dependsOn(jarTask)
|
||||
|
||||
main = "-jar"
|
||||
classpath = project.files()
|
||||
args = listOf(jarTask.outputs.files.singleFile.path) + args.orEmpty()
|
||||
doFirst {
|
||||
main = "-jar"
|
||||
|
||||
classpath = project.files()
|
||||
args = listOf(jarTask.outputs.files.singleFile.path) + args.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetContainer
|
||||
import plugins.KotlinBuildPublishingPlugin
|
||||
|
||||
|
||||
@@ -71,6 +70,18 @@ fun Project.noDefaultJar() {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Task> Project.runtimeJarArtifactBy(
|
||||
task: TaskProvider<T>,
|
||||
artifactRef: Any,
|
||||
body: ConfigurablePublishArtifact.() -> Unit = {}
|
||||
) {
|
||||
addArtifact("archives", task, artifactRef, body)
|
||||
addArtifact("runtimeJar", task, artifactRef, body)
|
||||
configurations.findByName("runtime")?.let {
|
||||
addArtifact(it.name, task, artifactRef, body)
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.runtimeJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> = runtimeJar(getOrCreateTask("jar", body)) { }
|
||||
|
||||
fun <T : Jar> Project.runtimeJar(task: TaskProvider<T>, body: T.() -> Unit = {}): TaskProvider<T> {
|
||||
@@ -91,11 +102,7 @@ fun <T : Jar> Project.runtimeJar(task: TaskProvider<T>, body: T.() -> Unit = {})
|
||||
body()
|
||||
}
|
||||
|
||||
project.addArtifact("archives", task, task)
|
||||
project.addArtifact("runtimeJar", task, task)
|
||||
project.configurations.findByName("runtime")?.let {
|
||||
project.addArtifact(it.name, task, task)
|
||||
}
|
||||
project.runtimeJarArtifactBy(task, task)
|
||||
|
||||
val runtimeJar = configurations.maybeCreate("runtimeJar").apply {
|
||||
isCanBeConsumed = true
|
||||
@@ -122,16 +129,10 @@ fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
|
||||
}
|
||||
|
||||
val sourcesJar = getOrCreateTask<Jar>("sourcesJar") {
|
||||
fun Project.mainJavaPluginSourceSet() = findJavaPluginConvention()?.sourceSets?.findByName("main")
|
||||
fun Project.mainKotlinSourceSet() =
|
||||
(extensions.findByName("kotlin") as? KotlinSourceSetContainer)?.sourceSets?.findByName("main")
|
||||
|
||||
fun Project.sources() = mainJavaPluginSourceSet()?.allSource ?: mainKotlinSourceSet()?.kotlin
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
archiveClassifier.set("sources")
|
||||
|
||||
from(project.sources())
|
||||
from(project.mainSourceSet.allSource)
|
||||
|
||||
project.configurations.findByName("embedded")?.let { embedded ->
|
||||
from(provider {
|
||||
@@ -140,7 +141,10 @@ fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
|
||||
.map { it.id.componentIdentifier }
|
||||
.filterIsInstance<ProjectComponentIdentifier>()
|
||||
.mapNotNull {
|
||||
project(it.projectPath).sources()
|
||||
project(it.projectPath)
|
||||
.findJavaPluginConvention()
|
||||
?.mainSourceSet
|
||||
?.allSource
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
// usages in build scripts are not tracked properly
|
||||
@@ -102,11 +97,9 @@ fun Project.kotlinStdlib(suffix: String? = null, classifier: String? = null): An
|
||||
dependencies.project(listOfNotNull(":kotlin-stdlib", suffix).joinToString("-"), classifier)
|
||||
}
|
||||
|
||||
fun Project.kotlinBuiltins(): Any = kotlinBuiltins(forJvm = false)
|
||||
|
||||
fun Project.kotlinBuiltins(forJvm: Boolean): Any =
|
||||
fun Project.kotlinBuiltins(): Any =
|
||||
if (kotlinBuildProperties.useBootstrapStdlib) "org.jetbrains.kotlin:builtins:$bootstrapKotlinVersion"
|
||||
else dependencies.project(":core:builtins", configuration = "runtimeElementsJvm".takeIf { forJvm })
|
||||
else dependencies.project(":core:builtins")
|
||||
|
||||
fun DependencyHandler.projectTests(name: String): ProjectDependency = project(name, configuration = "tests-jar")
|
||||
fun DependencyHandler.projectRuntimeJar(name: String): ProjectDependency = project(name, configuration = "runtimeJar")
|
||||
|
||||
@@ -80,8 +80,6 @@ fun Project.androidDxJar() = "org.jetbrains.kotlin:android-dx:${rootProject.extr
|
||||
|
||||
fun Project.jpsBuildTest() = "com.jetbrains.intellij.idea:jps-build-test:${rootProject.extra["versions.intellijSdk"]}"
|
||||
|
||||
fun Project.kotlinxCollectionsImmutable() = "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:${rootProject.extra["versions.kotlinx-collections-immutable"]}"
|
||||
|
||||
/**
|
||||
* Runtime version of annotations that are already in Kotlin stdlib (historically Kotlin has older version of this one).
|
||||
*
|
||||
@@ -167,7 +165,7 @@ fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File,
|
||||
|
||||
classpath = mainSourceSet.runtimeClasspath
|
||||
|
||||
mainClass.set("com.intellij.idea.Main")
|
||||
main = "com.intellij.idea.Main"
|
||||
|
||||
workingDir = File(intellijRootDir(), "bin")
|
||||
|
||||
@@ -180,14 +178,13 @@ fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File,
|
||||
"-Didea.system.path=$ideaSandboxDir",
|
||||
"-Didea.config.path=$ideaSandboxConfigDir",
|
||||
"-Didea.tooling.debug=true",
|
||||
"-Dfus.internal.test.mode=true",
|
||||
"-Dapple.laf.useScreenMenuBar=true",
|
||||
"-Dapple.awt.graphics.UseQuartz=true",
|
||||
"-Dsun.io.useCanonCaches=false",
|
||||
"-Dplugin.path=${ideaPluginDir.absolutePath}"
|
||||
)
|
||||
|
||||
if (Platform[201].orHigher() && !isIntellijUltimateSdkAvailable()) {
|
||||
if (Platform[201].orHigher()) {
|
||||
jvmArgs("-Didea.platform.prefix=Idea")
|
||||
}
|
||||
|
||||
|
||||
@@ -9,16 +9,12 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.publish.PublicationContainer
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import plugins.KotlinBuildPublishingPlugin
|
||||
import plugins.configureRepository
|
||||
import java.util.*
|
||||
|
||||
internal const val PLUGIN_MARKER_SUFFIX = ".gradle.plugin"
|
||||
|
||||
@UseExperimental(ExperimentalStdlibApi::class)
|
||||
fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
|
||||
val pluginDevelopment = extensions.getByType<PluginBundleExtension>()
|
||||
val publishingExtension = extensions.getByType<PublishingExtension>()
|
||||
@@ -29,10 +25,6 @@ fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
|
||||
if (withEmptyJars) {
|
||||
addEmptyJarArtifacts(markerPublication)
|
||||
}
|
||||
|
||||
tasks.named<PublishToMavenRepository>(
|
||||
"publish${markerPublication.name.capitalize(Locale.ROOT)}PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository"
|
||||
).configureRepository()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@ import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
|
||||
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.plugins.signing.Sign
|
||||
import org.gradle.plugins.signing.SigningExtension
|
||||
import org.gradle.plugins.signing.SigningPlugin
|
||||
import java.util.*
|
||||
@@ -108,27 +106,38 @@ class KotlinBuildPublishingPlugin @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val signingRequired = provider {
|
||||
project.findProperty("signingRequired")?.toString()?.toBoolean()
|
||||
?: project.property("isSonatypeRelease") as Boolean
|
||||
}
|
||||
|
||||
configure<SigningExtension> {
|
||||
setRequired(signingRequired)
|
||||
sign(extensions.getByType<PublishingExtension>().publications[PUBLICATION_NAME])
|
||||
useGpgCmd()
|
||||
}
|
||||
setRequired(provider {
|
||||
project.findProperty("signingRequired")?.toString()?.toBoolean()
|
||||
?: project.property("isSonatypeRelease") as Boolean
|
||||
})
|
||||
|
||||
tasks.withType<Sign>().configureEach {
|
||||
setOnlyIf { signingRequired.get() }
|
||||
sign(extensions.getByType<PublishingExtension>().publications[PUBLICATION_NAME])
|
||||
}
|
||||
|
||||
tasks.register("install") {
|
||||
dependsOn(tasks.named("publishToMavenLocal"))
|
||||
}
|
||||
|
||||
tasks.named<PublishToMavenRepository>("publish${PUBLICATION_NAME}PublicationTo${REPOSITORY_NAME}Repository")
|
||||
.configureRepository()
|
||||
tasks.named<PublishToMavenRepository>("publish${PUBLICATION_NAME}PublicationTo${REPOSITORY_NAME}Repository") {
|
||||
dependsOn(project.rootProject.tasks.named("preparePublication"))
|
||||
doFirst {
|
||||
val preparePublication = project.rootProject.tasks.named("preparePublication").get()
|
||||
val username: String? by preparePublication.extra
|
||||
val password: String? by preparePublication.extra
|
||||
val repoUrl: String by preparePublication.extra
|
||||
|
||||
repository.apply {
|
||||
url = uri(repoUrl)
|
||||
if (url.scheme != "file" && username != null && password != null) {
|
||||
credentials {
|
||||
this.username = username
|
||||
this.password = password
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -143,24 +152,4 @@ class KotlinBuildPublishingPlugin @Inject constructor(
|
||||
fun humanReadableName(project: Project) =
|
||||
project.name.split("-").joinToString(separator = " ") { it.capitalize(Locale.ROOT) }
|
||||
}
|
||||
}
|
||||
|
||||
fun TaskProvider<PublishToMavenRepository>.configureRepository() = configure {
|
||||
dependsOn(project.rootProject.tasks.named("preparePublication"))
|
||||
doFirst {
|
||||
val preparePublication = project.rootProject.tasks.named("preparePublication").get()
|
||||
val username: String? by preparePublication.extra
|
||||
val password: String? by preparePublication.extra
|
||||
val repoUrl: String by preparePublication.extra
|
||||
|
||||
repository.apply {
|
||||
url = project.uri(repoUrl)
|
||||
if (url.scheme != "file" && username != null && password != null) {
|
||||
credentials {
|
||||
this.username = username
|
||||
this.password = password
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,6 @@ open class PublishedKotlinModule : Plugin<Project> {
|
||||
configure<SigningExtension> {
|
||||
isRequired = signingRequired
|
||||
sign(configurations["archives"])
|
||||
useGpgCmd()
|
||||
}
|
||||
|
||||
tasks.named<Sign>("signArchives").configure {
|
||||
|
||||
@@ -31,47 +31,6 @@ import java.lang.Character.isUpperCase
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
fun Task.dependsOnKotlinPluginInstall() {
|
||||
dependsOn(
|
||||
":kotlin-allopen:install",
|
||||
":kotlin-noarg:install",
|
||||
":kotlin-sam-with-receiver:install",
|
||||
":kotlin-android-extensions:install",
|
||||
":kotlin-parcelize-compiler:install",
|
||||
":kotlin-build-common:install",
|
||||
":kotlin-compiler-embeddable:install",
|
||||
":native:kotlin-native-utils:install",
|
||||
":kotlin-util-klib:install",
|
||||
":kotlin-util-io:install",
|
||||
":kotlin-compiler-runner:install",
|
||||
":kotlin-daemon-embeddable:install",
|
||||
":kotlin-daemon-client:install",
|
||||
":kotlin-gradle-plugin-api:install",
|
||||
":kotlin-gradle-plugin:install",
|
||||
":kotlin-gradle-plugin-model:install",
|
||||
":kotlin-reflect:install",
|
||||
":kotlin-annotation-processing-gradle:install",
|
||||
":kotlin-test:kotlin-test-common:install",
|
||||
":kotlin-test:kotlin-test-annotations-common:install",
|
||||
":kotlin-test:kotlin-test-jvm:install",
|
||||
":kotlin-test:kotlin-test-js:install",
|
||||
":kotlin-test:kotlin-test-junit:install",
|
||||
":kotlin-gradle-subplugin-example:install",
|
||||
":kotlin-stdlib-common:install",
|
||||
":kotlin-stdlib:install",
|
||||
":kotlin-stdlib-jdk8:install",
|
||||
":kotlin-stdlib-js:install",
|
||||
":examples:annotation-processor-example:install",
|
||||
":kotlin-script-runtime:install",
|
||||
":kotlin-scripting-common:install",
|
||||
":kotlin-scripting-jvm:install",
|
||||
":kotlin-scripting-compiler-embeddable:install",
|
||||
":kotlin-scripting-compiler-impl-embeddable:install",
|
||||
":kotlin-test-js-runner:install",
|
||||
":native:kotlin-klib-commonizer-embeddable:install"
|
||||
)
|
||||
}
|
||||
|
||||
fun Project.projectTest(
|
||||
taskName: String = "test",
|
||||
parallel: Boolean = false,
|
||||
|
||||
@@ -6,23 +6,25 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:cli"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:backend"))
|
||||
compile(kotlinStdlib())
|
||||
compile(project(":kotlin-reflect"))
|
||||
compile(projectTests(":compiler:tests-common"))
|
||||
compile(commonDep("junit:junit"))
|
||||
|
||||
Platform[193].orLower {
|
||||
compileOnly(intellijDep()) { includeJars("openapi") }
|
||||
}
|
||||
|
||||
testCompile(project(":compiler:incremental-compilation-impl"))
|
||||
testCompile(project(":core:descriptors"))
|
||||
testCompile(project(":core:descriptors.jvm"))
|
||||
testCompile(project(":compiler:util"))
|
||||
testCompile(project(":compiler:cli"))
|
||||
testCompile(project(":compiler:frontend"))
|
||||
testCompile(project(":compiler:backend"))
|
||||
testCompile(project(":compiler:incremental-compilation-impl"))
|
||||
testCompile(project(":compiler:frontend.java"))
|
||||
|
||||
testCompile(kotlinStdlib())
|
||||
testCompile(project(":kotlin-reflect"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
|
||||
testCompile(projectTests(":jps-plugin"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
|
||||
Platform[193].orLower {
|
||||
testCompile(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
|
||||
}
|
||||
@@ -42,7 +44,7 @@ dependencies {
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { }
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.junit.runners.AllTests;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
//@RunWith(AllTests.class)
|
||||
@RunWith(AllTests.class)
|
||||
public class AndroidRunner {
|
||||
|
||||
private static PathManager pathManager;
|
||||
|
||||
@@ -294,7 +294,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
val kind = KotlinBaseTest.extractConfigurationKind(testFiles)
|
||||
val jdkKind = KotlinBaseTest.getTestJdkKind(testFiles)
|
||||
val keyConfiguration = CompilerConfiguration()
|
||||
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
|
||||
CodegenTestCase.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
|
||||
|
||||
val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
|
||||
val compiler = if (isJvm8Target) {
|
||||
@@ -303,7 +303,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
val filesHolder = holders.getOrPut(key) {
|
||||
FilesWriter(compiler, KotlinTestUtils.newConfiguration(kind, jdkKind, KotlinTestUtils.getAnnotationsJar()).apply {
|
||||
println("Creating new configuration by $key")
|
||||
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, this)
|
||||
CodegenTestCase.updateConfigurationByDirectivesInTestFiles(testFiles, this)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -23,7 +24,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.getExceptionMessage
|
||||
import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
|
||||
@@ -55,8 +55,14 @@ object CodegenUtil {
|
||||
@JvmOverloads
|
||||
fun getNonPrivateTraitMethods(descriptor: ClassDescriptor, copy: Boolean = true): Map<FunctionDescriptor, FunctionDescriptor> {
|
||||
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||
for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) {
|
||||
if (declaration !is CallableMemberDescriptor) continue
|
||||
|
||||
val traitMember = findInterfaceImplementation(declaration)
|
||||
if (traitMember == null ||
|
||||
Visibilities.isPrivate(traitMember.visibility) ||
|
||||
traitMember.visibility == Visibilities.INVISIBLE_FAKE) continue
|
||||
|
||||
for ((declaration, traitMember) in getNonPrivateTraitMembersForDelegation(descriptor)) {
|
||||
assert(traitMember.modality !== Modality.ABSTRACT) { "Cannot delegate to abstract trait method: $declaration" }
|
||||
|
||||
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
|
||||
@@ -65,7 +71,7 @@ object CodegenUtil {
|
||||
if (copy)
|
||||
copyFunctions(
|
||||
declaration, traitMember, declaration.containingDeclaration, traitMember.modality,
|
||||
DescriptorVisibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, true
|
||||
Visibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, true
|
||||
)
|
||||
else mapMembers(declaration, traitMember)
|
||||
)
|
||||
@@ -74,13 +80,13 @@ object CodegenUtil {
|
||||
}
|
||||
|
||||
fun copyFunctions(
|
||||
inheritedMember: CallableMemberDescriptor,
|
||||
traitMember: CallableMemberDescriptor,
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: DescriptorVisibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
inheritedMember: CallableMemberDescriptor,
|
||||
traitMember: CallableMemberDescriptor,
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
): Map<FunctionDescriptor, FunctionDescriptor> =
|
||||
mapMembers(inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides), traitMember)
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.util.findImplementationFromInterface
|
||||
import org.jetbrains.kotlin.util.findInterfaceImplementation
|
||||
|
||||
fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
descriptor: FunctionDescriptor,
|
||||
@@ -83,4 +81,60 @@ open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F
|
||||
override fun toString(): String {
|
||||
return descriptor.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a fake override in a class, returns an overridden declaration with implementation in trait, such that a method delegating to that
|
||||
* trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake
|
||||
* override of any trait implementation or such method was already generated into the superclass or is a method from Any.
|
||||
*/
|
||||
fun findInterfaceImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
if (descriptor.kind.isReal) return null
|
||||
if (isOrOverridesSynthesized(descriptor)) return null
|
||||
|
||||
val implementation = findImplementationFromInterface(descriptor) ?: return null
|
||||
val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null
|
||||
|
||||
if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) {
|
||||
// If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited
|
||||
return null
|
||||
}
|
||||
|
||||
return immediateConcreteSuper
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function
|
||||
* that should be called when the given fake override is called.
|
||||
*/
|
||||
fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
val overridden = OverridingUtil.getOverriddenDeclarations(descriptor)
|
||||
val filtered = OverridingUtil.filterOutOverridden(overridden)
|
||||
|
||||
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
|
||||
|
||||
if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a fake override and its implementation (non-abstract declaration) somewhere in supertypes,
|
||||
* returns the first immediate super function of the given fake override which overrides that implementation.
|
||||
* The returned function should be called from TImpl-bridges generated for the given fake override.
|
||||
*/
|
||||
fun firstSuperMethodFromKotlin(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
implementation: CallableMemberDescriptor
|
||||
): CallableMemberDescriptor? {
|
||||
return descriptor.overriddenDescriptors.firstOrNull { overridden ->
|
||||
overridden.modality != Modality.ABSTRACT &&
|
||||
(overridden == implementation || OverridingUtil.overrides(
|
||||
overridden,
|
||||
implementation,
|
||||
overridden.module.isTypeRefinementEnabled(),
|
||||
true
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":core:compiler.common.jvm"))
|
||||
api(project(":compiler:config.jvm"))
|
||||
api(intellijCoreDep()) { includeJars("asm-all", "guava", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
@@ -1,450 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
||||
import org.jetbrains.kotlin.descriptors.Visibility;
|
||||
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class AsmUtil {
|
||||
private static final int NO_FLAG_LOCAL = 0;
|
||||
public static final int NO_FLAG_PACKAGE_PRIVATE = 0;
|
||||
|
||||
@NotNull
|
||||
private static final Map<Visibility, Integer> visibilityToAccessFlag = ImmutableMap.<Visibility, Integer>builder()
|
||||
.put(Visibilities.Private.INSTANCE, ACC_PRIVATE)
|
||||
.put(Visibilities.PrivateToThis.INSTANCE, ACC_PRIVATE)
|
||||
.put(Visibilities.Protected.INSTANCE, ACC_PROTECTED)
|
||||
.put(JavaVisibilities.ProtectedStaticVisibility.INSTANCE, ACC_PROTECTED)
|
||||
.put(JavaVisibilities.ProtectedAndPackage.INSTANCE, ACC_PROTECTED)
|
||||
.put(Visibilities.Public.INSTANCE, ACC_PUBLIC)
|
||||
.put(Visibilities.Internal.INSTANCE, ACC_PUBLIC)
|
||||
.put(Visibilities.Local.INSTANCE, NO_FLAG_LOCAL)
|
||||
.put(JavaVisibilities.PackageVisibility.INSTANCE, NO_FLAG_PACKAGE_PRIVATE)
|
||||
.build();
|
||||
|
||||
public static final String CAPTURED_PREFIX = "$";
|
||||
|
||||
public static final String THIS = "this";
|
||||
|
||||
public static final String THIS_IN_DEFAULT_IMPLS = "$this";
|
||||
|
||||
public static final String LABELED_THIS_FIELD = THIS + "_";
|
||||
|
||||
public static final String CAPTURED_LABELED_THIS_FIELD = CAPTURED_PREFIX + LABELED_THIS_FIELD;
|
||||
|
||||
public static final String INLINE_DECLARATION_SITE_THIS = "this_";
|
||||
|
||||
public static final String LABELED_THIS_PARAMETER = CAPTURED_PREFIX + THIS + "$";
|
||||
|
||||
public static final String CAPTURED_THIS_FIELD = "this$0";
|
||||
|
||||
public static final String RECEIVER_PARAMETER_NAME = "$receiver";
|
||||
|
||||
/*
|
||||
This is basically an old convention. Starting from Kotlin 1.3, it was replaced with `$this_<label>`.
|
||||
Note that it is still used for inlined callable references and anonymous callable extension receivers
|
||||
even in 1.3.
|
||||
*/
|
||||
public static final String CAPTURED_RECEIVER_FIELD = "receiver$0";
|
||||
|
||||
// For non-inlined callable references ('kotlin.jvm.internal.CallableReference' has a 'receiver' field)
|
||||
public static final String BOUND_REFERENCE_RECEIVER = "receiver";
|
||||
|
||||
public static final String LOCAL_FUNCTION_VARIABLE_PREFIX = "$fun$";
|
||||
|
||||
private static final ImmutableMap<Integer, JvmPrimitiveType> primitiveTypeByAsmSort;
|
||||
private static final ImmutableMap<Type, Type> primitiveTypeByBoxedType;
|
||||
|
||||
static {
|
||||
ImmutableMap.Builder<Integer, JvmPrimitiveType> typeBySortBuilder = ImmutableMap.builder();
|
||||
ImmutableMap.Builder<Type, Type> typeByWrapperBuilder = ImmutableMap.builder();
|
||||
for (JvmPrimitiveType primitiveType : JvmPrimitiveType.values()) {
|
||||
Type asmType = Type.getType(primitiveType.getDesc());
|
||||
typeBySortBuilder.put(asmType.getSort(), primitiveType);
|
||||
typeByWrapperBuilder.put(asmTypeByFqNameWithoutInnerClasses(primitiveType.getWrapperFqName()), asmType);
|
||||
}
|
||||
primitiveTypeByAsmSort = typeBySortBuilder.build();
|
||||
primitiveTypeByBoxedType = typeByWrapperBuilder.build();
|
||||
}
|
||||
|
||||
private AsmUtil() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getCapturedFieldName(@NotNull String originalName) {
|
||||
return CAPTURED_PREFIX + originalName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getLabeledThisName(@NotNull String callableName, @NotNull String prefix, @NotNull String defaultName) {
|
||||
if (!Name.isValidIdentifier(callableName)) {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
return prefix + CommonVariableAsmNameManglingUtils.mangleNameIfNeeded(callableName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type boxType(@NotNull Type type) {
|
||||
Type boxedType = boxPrimitiveType(type);
|
||||
return boxedType != null ? boxedType : type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type boxPrimitiveType(@NotNull Type type) {
|
||||
JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort());
|
||||
return jvmPrimitiveType != null ? asmTypeByFqNameWithoutInnerClasses(jvmPrimitiveType.getWrapperFqName()) : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type unboxType(@NotNull Type boxedType) {
|
||||
Type primitiveType = unboxPrimitiveTypeOrNull(boxedType);
|
||||
if (primitiveType == null) {
|
||||
throw new UnsupportedOperationException("Unboxing: " + boxedType);
|
||||
}
|
||||
return primitiveType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type unboxPrimitiveTypeOrNull(@NotNull Type boxedType) {
|
||||
return primitiveTypeByBoxedType.get(boxedType);
|
||||
}
|
||||
|
||||
public static boolean isBoxedPrimitiveType(@NotNull Type boxedType) {
|
||||
return primitiveTypeByBoxedType.get(boxedType) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type unboxUnlessPrimitive(@NotNull Type boxedOrPrimitiveType) {
|
||||
if (isPrimitive(boxedOrPrimitiveType)) return boxedOrPrimitiveType;
|
||||
return unboxType(boxedOrPrimitiveType);
|
||||
}
|
||||
|
||||
public static boolean isBoxedTypeOf(@NotNull Type boxedType, @NotNull Type unboxedType) {
|
||||
return unboxPrimitiveTypeOrNull(boxedType) == unboxedType;
|
||||
}
|
||||
|
||||
public static boolean isIntPrimitive(Type type) {
|
||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isIntOrLongPrimitive(Type type) {
|
||||
return isIntPrimitive(type) || type == Type.LONG_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isPrimitive(Type type) {
|
||||
return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type correctElementType(@NotNull Type type) {
|
||||
String internalName = type.getInternalName();
|
||||
assert internalName.charAt(0) == '[';
|
||||
return Type.getType(internalName.substring(1));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type getArrayType(@NotNull Type componentType) {
|
||||
return Type.getType("[" + componentType.getDescriptor());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PrimitiveType asmPrimitiveTypeToLangPrimitiveType(Type type) {
|
||||
JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort());
|
||||
return jvmPrimitiveType != null ? jvmPrimitiveType.getPrimitiveType() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Method method(@NotNull String name, @NotNull Type returnType, @NotNull Type... parameterTypes) {
|
||||
return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes));
|
||||
}
|
||||
|
||||
public static Type stringValueOfType(Type type) {
|
||||
int sort = type.getSort();
|
||||
return sort == Type.OBJECT || sort == Type.ARRAY
|
||||
? OBJECT_TYPE
|
||||
: sort == Type.BYTE || sort == Type.SHORT ? Type.INT_TYPE : type;
|
||||
}
|
||||
|
||||
public static void genThrow(@NotNull InstructionAdapter v, @NotNull String exception, @Nullable String message) {
|
||||
v.anew(Type.getObjectType(exception));
|
||||
v.dup();
|
||||
if (message != null) {
|
||||
v.aconst(message);
|
||||
v.invokespecial(exception, "<init>", "(Ljava/lang/String;)V", false);
|
||||
}
|
||||
else {
|
||||
v.invokespecial(exception, "<init>", "()V", false);
|
||||
}
|
||||
v.athrow();
|
||||
}
|
||||
|
||||
public static void genStringBuilderConstructor(InstructionAdapter v) {
|
||||
v.visitTypeInsn(NEW, "java/lang/StringBuilder");
|
||||
v.dup();
|
||||
v.invokespecial("java/lang/StringBuilder", "<init>", "()V", false);
|
||||
}
|
||||
|
||||
public static void genInvertBoolean(InstructionAdapter v) {
|
||||
v.iconst(1);
|
||||
v.xor(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
public static void numConst(int value, Type type, InstructionAdapter v) {
|
||||
if (type == Type.FLOAT_TYPE) {
|
||||
v.fconst(value);
|
||||
}
|
||||
else if (type == Type.DOUBLE_TYPE) {
|
||||
v.dconst(value);
|
||||
}
|
||||
else if (type == Type.LONG_TYPE) {
|
||||
v.lconst(value);
|
||||
}
|
||||
else if (type == Type.CHAR_TYPE || type == Type.BYTE_TYPE || type == Type.SHORT_TYPE || type == Type.INT_TYPE) {
|
||||
v.iconst(value);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Primitive numeric type expected, got: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public static void swap(InstructionAdapter v, Type stackTop, Type afterTop) {
|
||||
if (stackTop.getSize() == 1) {
|
||||
if (afterTop.getSize() == 1) {
|
||||
v.swap();
|
||||
}
|
||||
else {
|
||||
v.dupX2();
|
||||
v.pop();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (afterTop.getSize() == 1) {
|
||||
v.dup2X1();
|
||||
}
|
||||
else {
|
||||
v.dup2X2();
|
||||
}
|
||||
v.pop2();
|
||||
}
|
||||
}
|
||||
|
||||
public static void pushDefaultValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
v.visitInsn(defaultValueOpcode(type));
|
||||
}
|
||||
|
||||
public static int defaultValueOpcode(@NotNull Type type) {
|
||||
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
||||
return ACONST_NULL;
|
||||
}
|
||||
if (type.getSort() == Type.FLOAT) {
|
||||
return FCONST_0;
|
||||
}
|
||||
if (type.getSort() == Type.DOUBLE) {
|
||||
return DCONST_0;
|
||||
}
|
||||
if (type.getSort() == Type.LONG) {
|
||||
return LCONST_0;
|
||||
}
|
||||
return ICONST_0;
|
||||
}
|
||||
|
||||
public static Type comparisonOperandType(Type left, Type right) {
|
||||
if (left == Type.DOUBLE_TYPE || right == Type.DOUBLE_TYPE) return Type.DOUBLE_TYPE;
|
||||
if (left == Type.FLOAT_TYPE || right == Type.FLOAT_TYPE) return Type.FLOAT_TYPE;
|
||||
if (left == Type.LONG_TYPE || right == Type.LONG_TYPE) return Type.LONG_TYPE;
|
||||
if (left == Type.CHAR_TYPE || right == Type.CHAR_TYPE) return Type.CHAR_TYPE;
|
||||
return Type.INT_TYPE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type numberFunctionOperandType(@NotNull Type expectedType) {
|
||||
if (expectedType == Type.SHORT_TYPE || expectedType == Type.BYTE_TYPE || expectedType == Type.CHAR_TYPE) {
|
||||
return Type.INT_TYPE;
|
||||
}
|
||||
return expectedType;
|
||||
}
|
||||
|
||||
public static void pop(@NotNull MethodVisitor v, @NotNull Type type) {
|
||||
if (type.getSize() == 2) {
|
||||
v.visitInsn(Opcodes.POP2);
|
||||
}
|
||||
else {
|
||||
v.visitInsn(Opcodes.POP);
|
||||
}
|
||||
}
|
||||
|
||||
public static void pop2(@NotNull MethodVisitor v, @NotNull Type topOfStack, @NotNull Type afterTop) {
|
||||
if (topOfStack.getSize() == 1 && afterTop.getSize() == 1) {
|
||||
v.visitInsn(POP2);
|
||||
} else {
|
||||
pop(v, topOfStack);
|
||||
pop(v, afterTop);
|
||||
}
|
||||
}
|
||||
|
||||
public static void pop2(@NotNull MethodVisitor v, @NotNull Type type) {
|
||||
if (type.getSize() == 2) {
|
||||
v.visitInsn(Opcodes.POP2);
|
||||
v.visitInsn(Opcodes.POP2);
|
||||
}
|
||||
else {
|
||||
v.visitInsn(Opcodes.POP2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void dup(@NotNull InstructionAdapter v, @NotNull Type type) {
|
||||
dup(v, type.getSize());
|
||||
}
|
||||
|
||||
private static void dup(@NotNull InstructionAdapter v, int size) {
|
||||
if (size == 2) {
|
||||
v.dup2();
|
||||
}
|
||||
else if (size == 1) {
|
||||
v.dup();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void dupx(@NotNull InstructionAdapter v, @NotNull Type type) {
|
||||
dupx(v, type.getSize());
|
||||
}
|
||||
|
||||
private static void dupx(@NotNull InstructionAdapter v, int size) {
|
||||
if (size == 2) {
|
||||
v.dup2X2();
|
||||
}
|
||||
else if (size == 1) {
|
||||
v.dupX1();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate the element afterTop and push it on the top of the stack.
|
||||
public static void dupSecond(@NotNull InstructionAdapter v, @NotNull Type topOfStack, @NotNull Type afterTop) {
|
||||
if (afterTop.getSize() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (topOfStack.getSize() == 0) {
|
||||
dup(v, afterTop);
|
||||
} else if (topOfStack.getSize() == 1 && afterTop.getSize() == 1) {
|
||||
v.dup2();
|
||||
v.pop();
|
||||
} else {
|
||||
swap(v, topOfStack, afterTop);
|
||||
if (topOfStack.getSize() == 1 && afterTop.getSize() == 2) {
|
||||
v.dup2X1();
|
||||
} else if (topOfStack.getSize() == 2 && afterTop.getSize() == 1) {
|
||||
v.dupX2();
|
||||
} else /* top = 2, after top = 2 */ {
|
||||
v.dup2X2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void dup(@NotNull InstructionAdapter v, @NotNull Type topOfStack, @NotNull Type afterTop) {
|
||||
if (topOfStack.getSize() == 0 && afterTop.getSize() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (topOfStack.getSize() == 0) {
|
||||
dup(v, afterTop);
|
||||
}
|
||||
else if (afterTop.getSize() == 0) {
|
||||
dup(v, topOfStack);
|
||||
}
|
||||
else if (afterTop.getSize() == 1) {
|
||||
if (topOfStack.getSize() == 1) {
|
||||
dup(v, 2);
|
||||
}
|
||||
else {
|
||||
v.dup2X1();
|
||||
v.pop2();
|
||||
v.dupX2();
|
||||
v.dupX2();
|
||||
v.pop();
|
||||
v.dup2X1();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Note: it's possible to write dup3 and dup4
|
||||
throw new UnsupportedOperationException("Don't know how generate dup3/dup4 for: " + topOfStack + " and " + afterTop);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeAnnotationData(
|
||||
@NotNull AnnotationVisitor av, @NotNull String[] data, @NotNull String[] strings
|
||||
) {
|
||||
AnnotationVisitor dataVisitor = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME);
|
||||
for (String string : data) {
|
||||
dataVisitor.visit(null, string);
|
||||
}
|
||||
dataVisitor.visitEnd();
|
||||
|
||||
AnnotationVisitor stringsVisitor = av.visitArray(JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME);
|
||||
for (String string : strings) {
|
||||
stringsVisitor.visit(null, string);
|
||||
}
|
||||
stringsVisitor.visitEnd();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
|
||||
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeByClassId(@NotNull ClassId classId) {
|
||||
return Type.getObjectType(classId.asString().replace('.', '$'));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String internalNameByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
|
||||
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();
|
||||
}
|
||||
|
||||
|
||||
public static void wrapJavaClassIntoKClass(@NotNull InstructionAdapter v) {
|
||||
v.invokestatic(REFLECTION, "getOrCreateKotlinClass", Type.getMethodDescriptor(K_CLASS_TYPE, getType(Class.class)), false);
|
||||
}
|
||||
|
||||
public static void wrapJavaClassesIntoKClasses(@NotNull InstructionAdapter v) {
|
||||
v.invokestatic(REFLECTION, "getOrCreateKotlinClasses", Type.getMethodDescriptor(K_CLASS_ARRAY_TYPE, getType(Class[].class)), false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Integer getVisibilityAccessFlag(Visibility visibility) {
|
||||
return visibilityToAccessFlag.get(visibility);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:JvmName("CommonVariableAsmNameManglingUtils")
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.resolve.jvm.checkers.isValidDalvikCharacter
|
||||
|
||||
fun mangleNameIfNeeded(name: String): String {
|
||||
if (name.all { it.isValidCharacter() }) {
|
||||
return name
|
||||
}
|
||||
|
||||
return buildString {
|
||||
for (c in name) {
|
||||
if (c.isValidCharacter()) {
|
||||
append(c)
|
||||
} else {
|
||||
val hexString = Integer.toHexString(c.toInt())
|
||||
assert(hexString.length <= 4)
|
||||
append("_u").append(hexString)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Char.isValidCharacter(): Boolean {
|
||||
return this != '$' && this != '-' && isValidDalvikCharacter(this)
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.signature
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmTypeFactory
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
object AsmTypeFactory : JvmTypeFactory<Type> {
|
||||
override fun boxType(possiblyPrimitiveType: Type): Type =
|
||||
AsmUtil.boxType(possiblyPrimitiveType)
|
||||
|
||||
override fun createFromString(representation: String): Type =
|
||||
Type.getType(representation)
|
||||
|
||||
override fun createPrimitiveType(primitiveType: PrimitiveType): Type =
|
||||
AsmTypes.valueTypeForPrimitive(primitiveType)
|
||||
|
||||
override fun createObjectType(internalName: String): Type =
|
||||
Type.getObjectType(internalName)
|
||||
|
||||
override fun toString(type: Type): String =
|
||||
type.descriptor
|
||||
|
||||
override val javaLangClassType: Type
|
||||
get() = AsmTypes.JAVA_CLASS_TYPE
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:JvmName("DalvikIdentifierUtils")
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
fun isValidDalvikIdentifier(identifier: String): Boolean = identifier.all { isValidDalvikCharacter(it) }
|
||||
|
||||
// https://source.android.com/devices/tech/dalvik/dex-format.html#string-syntax
|
||||
fun isValidDalvikCharacter(c: Char): Boolean = when (c) {
|
||||
in 'A'..'Z' -> true
|
||||
in 'a'..'z' -> true
|
||||
in '0'..'9' -> true
|
||||
'$', '-', '_' -> true
|
||||
in '\u00a1' .. '\u1fff' -> true
|
||||
in '\u2010' .. '\u2027' -> true
|
||||
in '\u2030' .. '\ud7ff' -> true
|
||||
in '\ue000' .. '\uffef' -> true
|
||||
else -> false
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmDescriptorTypeWriter
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.load.kotlin.mapBuiltInType
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
interface TypeMappingContext<Writer : JvmDescriptorTypeWriter<Type>> {
|
||||
val typeContext: TypeSystemCommonBackendContextForTypeMapping
|
||||
|
||||
fun getClassInternalName(typeConstructor: TypeConstructorMarker): String
|
||||
fun Writer.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode)
|
||||
}
|
||||
|
||||
object AbstractTypeMapper {
|
||||
fun <Writer : JvmDescriptorTypeWriter<Type>> mapClass(context: TypeMappingContext<Writer>, typeConstructor: TypeConstructorMarker): Type {
|
||||
return with(context.typeContext) {
|
||||
when {
|
||||
typeConstructor.isClassTypeConstructor() -> {
|
||||
mapType(context, typeConstructor.defaultType(), TypeMappingMode.CLASS_DECLARATION)
|
||||
}
|
||||
typeConstructor.isTypeParameter() -> {
|
||||
mapType(context, typeConstructor.defaultType())
|
||||
}
|
||||
else -> error("Unknown type constructor: $typeConstructor")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <Writer : JvmDescriptorTypeWriter<Type>> mapType(
|
||||
context: TypeMappingContext<Writer>,
|
||||
type: KotlinTypeMarker,
|
||||
mode: TypeMappingMode = TypeMappingMode.DEFAULT,
|
||||
sw: Writer? = null
|
||||
): Type = context.typeContext.mapType(context, type, mode, sw)
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapType(
|
||||
context: TypeMappingContext<Writer>,
|
||||
type: KotlinTypeMarker,
|
||||
mode: TypeMappingMode = TypeMappingMode.DEFAULT,
|
||||
sw: Writer? = null
|
||||
): Type {
|
||||
if (type !is SimpleTypeMarker) {
|
||||
error("Unexpected type: $type (original Kotlin type=$type of ${type.let { it::class }})")
|
||||
}
|
||||
if (type.isSuspendFunction()) {
|
||||
val argumentsCount = type.argumentsCount()
|
||||
val argumentsList = type.asArgumentList()
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments") // Workaround for KT-42175
|
||||
val arguments = buildList<KotlinTypeMarker> {
|
||||
for (i in 0 until (argumentsCount - 1)) {
|
||||
this += argumentsList[i].adjustedType()
|
||||
}
|
||||
this += continuationTypeConstructor().typeWithArguments(argumentsList[argumentsCount - 1].adjustedType())
|
||||
this += nullableAnyType()
|
||||
}
|
||||
val runtimeFunctionType = functionNTypeConstructor(arguments.size - 1).typeWithArguments(arguments)
|
||||
return mapType(context, runtimeFunctionType, mode, sw)
|
||||
}
|
||||
|
||||
mapBuiltInType(type, AsmTypeFactory, mode)?.let { builtInType ->
|
||||
return boxTypeIfNeeded(builtInType, mode.needPrimitiveBoxing).also { asmType ->
|
||||
with(context) { sw?.writeGenericType(type, asmType, mode) }
|
||||
}
|
||||
}
|
||||
|
||||
val typeConstructor = type.typeConstructor()
|
||||
|
||||
when {
|
||||
type.isArrayOrNullableArray() -> {
|
||||
val typeArgument = type.asArgumentList()[0]
|
||||
val (variance, memberType) = when {
|
||||
typeArgument.isStarProjection() -> Variance.OUT_VARIANCE to nullableAnyType()
|
||||
else -> typeArgument.getVariance().toVariance() to typeArgument.getType()
|
||||
}
|
||||
require(memberType is SimpleTypeMarker)
|
||||
|
||||
val arrayElementType: Type
|
||||
sw?.writeArrayType()
|
||||
if (variance == Variance.IN_VARIANCE) {
|
||||
arrayElementType = AsmTypes.OBJECT_TYPE
|
||||
sw?.writeClass(arrayElementType)
|
||||
} else {
|
||||
arrayElementType = mapType(context, memberType, mode.toGenericArgumentMode(variance, ofArray = true), sw)
|
||||
}
|
||||
sw?.writeArrayEnd()
|
||||
return AsmUtil.getArrayType(arrayElementType)
|
||||
}
|
||||
|
||||
typeConstructor.isClassTypeConstructor() -> {
|
||||
if (typeConstructor.isInlineClass() && !mode.needInlineClassWrapping) {
|
||||
val expandedType = computeExpandedTypeForInlineClass(type)
|
||||
require(expandedType is SimpleTypeMarker?)
|
||||
if (expandedType != null) {
|
||||
return mapType(context, expandedType, mode.wrapInlineClassesMode(), sw)
|
||||
}
|
||||
}
|
||||
|
||||
val asmType = if (mode.isForAnnotationParameter && type.isKClass())
|
||||
AsmTypes.JAVA_CLASS_TYPE
|
||||
else
|
||||
Type.getObjectType(context.getClassInternalName(typeConstructor))
|
||||
|
||||
with(context) { sw?.writeGenericType(type, asmType, mode) }
|
||||
return asmType
|
||||
}
|
||||
|
||||
typeConstructor.isTypeParameter() -> {
|
||||
val typeParameter = typeConstructor as TypeParameterMarker
|
||||
return mapType(context, typeParameter.representativeUpperBound(), mode, null).also { asmType ->
|
||||
sw?.writeTypeVariable(typeParameter.getName(), asmType)
|
||||
}
|
||||
}
|
||||
|
||||
else -> throw UnsupportedOperationException("Unknown type $type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun boxTypeIfNeeded(possiblyPrimitiveType: Type, needBoxedType: Boolean): Type =
|
||||
if (needBoxedType) AsmUtil.boxType(possiblyPrimitiveType) else possiblyPrimitiveType
|
||||
|
||||
private fun TypeVariance.toVariance(): Variance = when (this) {
|
||||
TypeVariance.IN -> Variance.IN_VARIANCE
|
||||
TypeVariance.OUT -> Variance.OUT_VARIANCE
|
||||
TypeVariance.INV -> Variance.INVARIANT
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ dependencies {
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":compiler:serialization"))
|
||||
api(project(":compiler:backend.common.jvm"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "asm-all", "guava", rootProject = rootProject) }
|
||||
compileOnly(intellijDep()) { includeJars("trove4j", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class AccessorForCompanionObjectInstanceFieldDescriptor(
|
||||
null, null, emptyList(), emptyList(),
|
||||
companionObjectDescriptor.defaultType,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.LOCAL
|
||||
Visibilities.LOCAL
|
||||
)
|
||||
}
|
||||
|
||||
@@ -41,4 +41,4 @@ class AccessorForCompanionObjectInstanceFieldDescriptor(
|
||||
): FunctionDescriptorImpl {
|
||||
throw UnsupportedOperationException("Accessor for companion object $companionObjectDescriptor should not be substituted")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,11 +42,11 @@ class AccessorForConstructorDescriptor(
|
||||
override fun substitute(substitutor: TypeSubstitutor) = super.substitute(substitutor) as ClassConstructorDescriptor
|
||||
|
||||
override fun copy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: DescriptorVisibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
): AccessorForConstructorDescriptor {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
@@ -61,7 +61,7 @@ class AccessorForConstructorDescriptor(
|
||||
copyValueParameters(calleeDescriptor),
|
||||
calleeDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.LOCAL
|
||||
Visibilities.LOCAL
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class AccessorForFunctionDescriptor(
|
||||
copyValueParameters(calleeDescriptor),
|
||||
calleeDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.LOCAL
|
||||
Visibilities.LOCAL
|
||||
)
|
||||
|
||||
isSuspend = calleeDescriptor.isSuspend
|
||||
|
||||
@@ -43,7 +43,7 @@ open class AccessorForPropertyDescriptor private constructor(
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.LOCAL,
|
||||
Visibilities.LOCAL,
|
||||
calleeDescriptor.isVar,
|
||||
Name.identifier("access$$accessorSuffix"),
|
||||
CallableMemberDescriptor.Kind.DECLARATION,
|
||||
@@ -111,7 +111,7 @@ open class AccessorForPropertyDescriptor private constructor(
|
||||
property,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.LOCAL,
|
||||
Visibilities.LOCAL,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -136,7 +136,7 @@ open class AccessorForPropertyDescriptor private constructor(
|
||||
property,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.LOCAL,
|
||||
Visibilities.LOCAL,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
|
||||
@@ -90,18 +90,12 @@ public abstract class AnnotationCodegen {
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
private final ModuleDescriptor module;
|
||||
private final GenerationState state;
|
||||
private final boolean skipNullabilityAnnotations;
|
||||
|
||||
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state) {
|
||||
this(innerClassConsumer, state, false);
|
||||
}
|
||||
|
||||
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state, boolean skipNullabilityAnnotations) {
|
||||
this.innerClassConsumer = innerClassConsumer;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.module = state.getModule();
|
||||
this.state = state;
|
||||
this.skipNullabilityAnnotations = skipNullabilityAnnotations;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,16 +105,6 @@ public abstract class AnnotationCodegen {
|
||||
@Nullable Annotated annotated,
|
||||
@Nullable Type returnType,
|
||||
@Nullable KotlinType typeForTypeAnnotations
|
||||
) {
|
||||
genAnnotations(annotated, returnType, typeForTypeAnnotations, null, Collections.emptyList());
|
||||
}
|
||||
|
||||
public void genAnnotations(
|
||||
@Nullable Annotated annotated,
|
||||
@Nullable Type returnType,
|
||||
@Nullable KotlinType typeForTypeAnnotations,
|
||||
@Nullable DeclarationDescriptorWithVisibility parameterContainer,
|
||||
@NotNull List<String> additionalVisibleAnnotations
|
||||
) {
|
||||
if (annotated == null) return;
|
||||
|
||||
@@ -142,7 +126,7 @@ public abstract class AnnotationCodegen {
|
||||
&& !applicableTargets.contains(KotlinTarget.CLASS)
|
||||
&& !applicableTargets.contains(KotlinTarget.ANNOTATION_CLASS)) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) annotated;
|
||||
if (classDescriptor.getVisibility() == DescriptorVisibilities.LOCAL) {
|
||||
if (classDescriptor.getVisibility() == Visibilities.LOCAL) {
|
||||
assert applicableTargets.contains(KotlinTarget.EXPRESSION) :
|
||||
"Inconsistent target list for object literal annotation: " + applicableTargets + " on " + annotated;
|
||||
continue;
|
||||
@@ -155,28 +139,22 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
for (String annotation : additionalVisibleAnnotations) {
|
||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, annotation, true);
|
||||
annotationDescriptorsAlreadyPresent.add(annotation);
|
||||
}
|
||||
|
||||
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent, parameterContainer);
|
||||
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent);
|
||||
generateTypeAnnotations(annotated, typeForTypeAnnotations);
|
||||
}
|
||||
|
||||
private void generateAdditionalAnnotations(
|
||||
@NotNull Annotated annotated,
|
||||
@Nullable Type returnType,
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent,
|
||||
@Nullable DeclarationDescriptorWithVisibility parameterContainer
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent
|
||||
) {
|
||||
if (annotated instanceof CallableDescriptor) {
|
||||
generateAdditionalCallableAnnotations((CallableDescriptor) annotated, returnType, annotationDescriptorsAlreadyPresent, parameterContainer);
|
||||
generateAdditionalCallableAnnotations((CallableDescriptor) annotated, returnType, annotationDescriptorsAlreadyPresent);
|
||||
}
|
||||
else if (annotated instanceof FieldDescriptor) {
|
||||
generateAdditionalCallableAnnotations(
|
||||
((FieldDescriptor) annotated).getCorrespondingProperty(), returnType, annotationDescriptorsAlreadyPresent,
|
||||
parameterContainer);
|
||||
((FieldDescriptor) annotated).getCorrespondingProperty(), returnType, annotationDescriptorsAlreadyPresent
|
||||
);
|
||||
}
|
||||
else if (annotated instanceof ClassDescriptor) {
|
||||
generateAdditionalClassAnnotations(annotationDescriptorsAlreadyPresent, (ClassDescriptor) annotated);
|
||||
@@ -186,15 +164,11 @@ public abstract class AnnotationCodegen {
|
||||
private void generateAdditionalCallableAnnotations(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@Nullable Type returnType,
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent,
|
||||
@Nullable DeclarationDescriptorWithVisibility parameterContainer
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent
|
||||
) {
|
||||
// No need to annotate privates, synthetic accessors and their parameters
|
||||
if (isInvisibleFromTheOutside(descriptor)) return;
|
||||
if (descriptor instanceof ParameterDescriptor &&
|
||||
isInvisibleFromTheOutside(parameterContainer != null ? parameterContainer : descriptor.getContainingDeclaration())) {
|
||||
return;
|
||||
}
|
||||
if (descriptor instanceof ValueParameterDescriptor && isInvisibleFromTheOutside(descriptor.getContainingDeclaration())) return;
|
||||
|
||||
// No need to annotate annotation methods since they're always non-null
|
||||
if (descriptor instanceof PropertyGetterDescriptor &&
|
||||
@@ -202,7 +176,7 @@ public abstract class AnnotationCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
if (returnType != null && !AsmUtil.isPrimitive(returnType) && !skipNullabilityAnnotations) {
|
||||
if (returnType != null && !AsmUtil.isPrimitive(returnType)) {
|
||||
generateNullabilityAnnotation(descriptor.getReturnType(), annotationDescriptorsAlreadyPresent);
|
||||
}
|
||||
}
|
||||
@@ -221,7 +195,7 @@ public abstract class AnnotationCodegen {
|
||||
private static boolean isInvisibleFromTheOutside(@Nullable DeclarationDescriptor descriptor) {
|
||||
if (isAccessor(descriptor)) return true;
|
||||
if (descriptor instanceof MemberDescriptor) {
|
||||
return DescriptorAsmUtil.getVisibilityAccessFlag((MemberDescriptor) descriptor) == Opcodes.ACC_PRIVATE;
|
||||
return AsmUtil.getVisibilityAccessFlag((MemberDescriptor) descriptor) == Opcodes.ACC_PRIVATE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -248,17 +222,17 @@ public abstract class AnnotationCodegen {
|
||||
if (!TypeUtils.isNullableType(flexibleType.getLowerBound()) && TypeUtils.isNullableType(flexibleType.getUpperBound())) {
|
||||
AnnotationDescriptor notNull = type.getAnnotations().findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION);
|
||||
if (notNull != null) {
|
||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, Type.getType(NotNull.class).getDescriptor(), false);
|
||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, NotNull.class);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
generateAnnotationIfNotPresent(
|
||||
annotationDescriptorsAlreadyPresent,
|
||||
TypeUtils.isNullableType(type) ? Type.getType(Nullable.class).getDescriptor() : Type.getType(NotNull.class).getDescriptor(),
|
||||
false
|
||||
);
|
||||
boolean isNullableType = TypeUtils.isNullableType(type);
|
||||
|
||||
Class<?> annotationClass = isNullableType ? Nullable.class : NotNull.class;
|
||||
|
||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, annotationClass);
|
||||
}
|
||||
|
||||
private static final Map<JvmTarget, Map<KotlinTarget, ElementType>> annotationTargetMaps = new EnumMap<>(JvmTarget.class);
|
||||
@@ -338,13 +312,10 @@ public abstract class AnnotationCodegen {
|
||||
visitor.visitEnd();
|
||||
}
|
||||
|
||||
private void generateAnnotationIfNotPresent(
|
||||
Set<String> annotationDescriptorsAlreadyPresent,
|
||||
String annotationDescriptor,
|
||||
boolean visible
|
||||
) {
|
||||
if (!annotationDescriptorsAlreadyPresent.contains(annotationDescriptor)) {
|
||||
visitAnnotation(annotationDescriptor, visible).visitEnd();
|
||||
private void generateAnnotationIfNotPresent(Set<String> annotationDescriptorsAlreadyPresent, Class<?> annotationClass) {
|
||||
String descriptor = Type.getType(annotationClass).getDescriptor();
|
||||
if (!annotationDescriptorsAlreadyPresent.contains(descriptor)) {
|
||||
visitAnnotation(descriptor, false).visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,16 +600,7 @@ public abstract class AnnotationCodegen {
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
return forMethod(mv, innerClassConsumer, state, false);
|
||||
}
|
||||
|
||||
public static AnnotationCodegen forMethod(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state,
|
||||
boolean skipNullabilityAnnotations
|
||||
) {
|
||||
return new AnnotationCodegen(innerClassConsumer, state, skipNullabilityAnnotations) {
|
||||
return new AnnotationCodegen(innerClassConsumer, state) {
|
||||
@NotNull
|
||||
@Override
|
||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||
@@ -658,16 +620,7 @@ public abstract class AnnotationCodegen {
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
return forField(fv, innerClassConsumer, state, false);
|
||||
}
|
||||
|
||||
public static AnnotationCodegen forField(
|
||||
@NotNull FieldVisitor fv,
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state,
|
||||
boolean skipNullabilityAnnotations
|
||||
) {
|
||||
return new AnnotationCodegen(innerClassConsumer, state, skipNullabilityAnnotations) {
|
||||
return new AnnotationCodegen(innerClassConsumer, state) {
|
||||
@NotNull
|
||||
@Override
|
||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||
@@ -686,10 +639,9 @@ public abstract class AnnotationCodegen {
|
||||
int parameter,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state,
|
||||
boolean skipNullabilityAnnotations
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
return new AnnotationCodegen(innerClassConsumer, state, skipNullabilityAnnotations) {
|
||||
return new AnnotationCodegen(innerClassConsumer, state) {
|
||||
@NotNull
|
||||
@Override
|
||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||
|
||||
1335
compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java
Normal file
1335
compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -43,7 +42,7 @@ interface Callable {
|
||||
}
|
||||
}
|
||||
|
||||
fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||
fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -38,8 +39,6 @@ import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedS
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
|
||||
import static org.jetbrains.kotlin.util.DeclarationUtilKt.findImplementationFromInterface;
|
||||
import static org.jetbrains.kotlin.util.DeclarationUtilKt.findInterfaceImplementation;
|
||||
|
||||
public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject> {
|
||||
@NotNull
|
||||
@@ -126,7 +125,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
|
||||
if (memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
|
||||
if (!member.getKind().isReal() && findInterfaceImplementation(member) == null) {
|
||||
if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) {
|
||||
if (member instanceof FunctionDescriptor) {
|
||||
functionCodegen.generateBridges((FunctionDescriptor) member);
|
||||
}
|
||||
@@ -237,12 +236,12 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
@NotNull GenerationState state,
|
||||
boolean isErasedInlineClass
|
||||
) {
|
||||
CallableMemberDescriptor actualImplementation =
|
||||
interfaceFun.getKind().isReal() ? interfaceFun : findImplementationFromInterface(interfaceFun);
|
||||
assert actualImplementation != null : "Can't find actual implementation for " + interfaceFun;
|
||||
// Skip Java 8 default methods
|
||||
if (CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(actualImplementation) ||
|
||||
JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(actualImplementation, state.getJvmDefaultMode())) {
|
||||
if (CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) ||
|
||||
JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(
|
||||
DescriptorUtils.unwrapFakeOverrideToAnyDeclaration(interfaceFun), state.getJvmDefaultMode()
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
@@ -51,9 +50,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CallableReferenceUtilKt.*;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
@@ -141,7 +139,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
|
||||
this.asmType = typeMapper.mapClass(classDescriptor);
|
||||
|
||||
visibilityFlag = DescriptorAsmUtil.getVisibilityAccessFlagForClass(classDescriptor);
|
||||
visibilityFlag = AsmUtil.getVisibilityAccessFlagForClass(classDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -368,11 +366,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
value = StackValue.local(slot, type, bridgeParameterKotlinTypes.get(i));
|
||||
slot += type.getSize();
|
||||
}
|
||||
if (InlineClassesCodegenUtilKt.isInlineClassWithUnderlyingTypeAnyOrAnyN(parameterType) &&
|
||||
functionReferenceCall == null
|
||||
) {
|
||||
parameterType = InlineClassesUtilsKt.unsubstitutedUnderlyingParameter(parameterType).getType();
|
||||
}
|
||||
value.put(typeMapper.mapType(calleeParameter), parameterType, iv);
|
||||
}
|
||||
|
||||
@@ -596,8 +589,4 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
MemberScope scope = functionClass.getDefaultType().getMemberScope();
|
||||
return scope.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND).iterator().next();
|
||||
}
|
||||
|
||||
public boolean isCallableReference() {
|
||||
return functionReferenceTarget != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMapper
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
||||
@@ -52,13 +52,13 @@ import java.util.*
|
||||
* Kotlin's read-only collections. This is required on JVM because Kotlin's read-only collections are mapped to mutable JDK collections
|
||||
*/
|
||||
class CollectionStubMethodGenerator(
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
private val descriptor: ClassDescriptor
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
private val descriptor: ClassDescriptor
|
||||
) {
|
||||
private data class TasksToGenerate(
|
||||
val methodStubsToGenerate: Set<JvmMethodGenericSignature>,
|
||||
val syntheticStubsToGenerate: Set<JvmMethodGenericSignature>,
|
||||
val bridgesToGenerate: Set<FunctionDescriptor>
|
||||
val methodStubsToGenerate: Set<JvmMethodGenericSignature>,
|
||||
val syntheticStubsToGenerate: Set<JvmMethodGenericSignature>,
|
||||
val bridgesToGenerate: Set<FunctionDescriptor>
|
||||
)
|
||||
|
||||
companion object {
|
||||
@@ -70,9 +70,9 @@ class CollectionStubMethodGenerator(
|
||||
val superCollectionClasses = findRelevantSuperCollectionClasses()
|
||||
if (superCollectionClasses.isEmpty()) return NO_TASKS
|
||||
|
||||
val existingMethodsInSuperclasses = descriptor.getAllSuperclassesWithoutAny().flatMap { superClass ->
|
||||
val tasksFromSuperClass = CollectionStubMethodGenerator(typeMapper, superClass).computeTasksToGenerate()
|
||||
(tasksFromSuperClass.methodStubsToGenerate + tasksFromSuperClass.syntheticStubsToGenerate).map { stub -> stub.asmMethod }
|
||||
val existingMethodsInSuperclasses = descriptor.getAllSuperclassesWithoutAny().flatMap {
|
||||
val tasksFromSuperClass = CollectionStubMethodGenerator(typeMapper, it).computeTasksToGenerate()
|
||||
(tasksFromSuperClass.methodStubsToGenerate + tasksFromSuperClass.syntheticStubsToGenerate).map { it.asmMethod }
|
||||
}
|
||||
|
||||
val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
||||
@@ -126,42 +126,43 @@ class CollectionStubMethodGenerator(
|
||||
val genericSignatureInfo = overriddenMethod.getSpecialSignatureInfo()
|
||||
|
||||
val specialGenericSignature =
|
||||
genericSignatureInfo?.replaceValueParametersIn(overriddenMethodSignature.genericsSignature)
|
||||
genericSignatureInfo?.replaceValueParametersIn(overriddenMethodSignature.genericsSignature)
|
||||
?: overriddenMethodSignature.genericsSignature
|
||||
|
||||
val (asmMethod, valueParameters) =
|
||||
// if current method has special generic signature,
|
||||
// like `Collection.remove(E): Boolean` in Kotlin, use original signature to obtain `remove(Object)`
|
||||
if (genericSignatureInfo?.isObjectReplacedWithTypeParameter == true)
|
||||
Pair(originalSignature.asmMethod, originalSignature.valueParameters)
|
||||
else
|
||||
Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters)
|
||||
// if current method has special generic signature,
|
||||
// like `Collection.remove(E): Boolean` in Kotlin, use original signature to obtain `remove(Object)`
|
||||
if (genericSignatureInfo?.isObjectReplacedWithTypeParameter ?: false)
|
||||
Pair(originalSignature.asmMethod, originalSignature.valueParameters)
|
||||
else
|
||||
Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters)
|
||||
|
||||
JvmMethodGenericSignature(
|
||||
asmMethod,
|
||||
valueParameters,
|
||||
specialGenericSignature
|
||||
asmMethod,
|
||||
valueParameters,
|
||||
specialGenericSignature
|
||||
)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
method.signature()
|
||||
}
|
||||
|
||||
if (commonSignature.asmMethod !in existingMethodsInSuperclasses &&
|
||||
// If original method already defined in a superclass we mustn't care about specialized version
|
||||
// The same way we do not generate specialized version in a common case like:
|
||||
// open class A<T> : MutableList<T> {
|
||||
// fun add(x: T) = true
|
||||
// }
|
||||
// class B : A<String>() // No 'B.add(String)Z'
|
||||
originalSignature.asmMethod !in existingMethodsInSuperclasses
|
||||
) {
|
||||
// If original method already defined in a superclass we mustn't care about specialized version
|
||||
// The same way we do not generate specialized version in a common case like:
|
||||
// open class A<T> : MutableList<T> {
|
||||
// fun add(x: T) = true
|
||||
// }
|
||||
// class B : A<String>() // No 'B.add(String)Z'
|
||||
originalSignature.asmMethod !in existingMethodsInSuperclasses) {
|
||||
methodStubsToGenerate.add(commonSignature)
|
||||
|
||||
if (originalSignature.asmMethod != commonSignature.asmMethod) {
|
||||
syntheticStubsToGenerate.add(originalSignature)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// If the fake override is non-abstract, its implementation is already present in the class or inherited from one of its
|
||||
// super classes, but is not related to the MutableCollection hierarchy. So maybe it uses more specific return types
|
||||
// and we may need to generate some bridges
|
||||
@@ -191,13 +192,13 @@ class CollectionStubMethodGenerator(
|
||||
|
||||
private fun isDefaultInJdk(method: FunctionDescriptor) =
|
||||
method.modality != Modality.ABSTRACT &&
|
||||
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
|
||||
it.kind == FAKE_OVERRIDE || KotlinBuiltIns.isBuiltIn(it)
|
||||
}
|
||||
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
|
||||
it.kind == FAKE_OVERRIDE || KotlinBuiltIns.isBuiltIn(it)
|
||||
}
|
||||
|
||||
private data class CollectionClassPair(
|
||||
val readOnlyClass: TypeConstructor,
|
||||
val mutableClass: TypeConstructor
|
||||
val readOnlyClass: TypeConstructor,
|
||||
val mutableClass: TypeConstructor
|
||||
)
|
||||
|
||||
private fun findRelevantSuperCollectionClasses(): Collection<CollectionClassPair> {
|
||||
@@ -205,14 +206,14 @@ class CollectionStubMethodGenerator(
|
||||
|
||||
val collectionClasses = with(descriptor.builtIns) {
|
||||
listOf(
|
||||
collection to mutableCollection,
|
||||
set to mutableSet,
|
||||
list to mutableList,
|
||||
map to mutableMap,
|
||||
mapEntry to mutableMapEntry,
|
||||
iterable to mutableIterable,
|
||||
iterator to mutableIterator,
|
||||
listIterator to mutableListIterator
|
||||
collection to mutableCollection,
|
||||
set to mutableSet,
|
||||
list to mutableList,
|
||||
map to mutableMap,
|
||||
mapEntry to mutableMapEntry,
|
||||
iterable to mutableIterable,
|
||||
iterator to mutableIterator,
|
||||
listIterator to mutableListIterator
|
||||
).map { (readOnly, mutable) ->
|
||||
pair(readOnly.typeConstructor, mutable.typeConstructor)
|
||||
}
|
||||
@@ -233,16 +234,15 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun findFakeOverridesForMethodsFromMutableCollection(
|
||||
klass: ClassDescriptor,
|
||||
mutableCollectionTypeConstructor: TypeConstructor
|
||||
klass: ClassDescriptor,
|
||||
mutableCollectionTypeConstructor: TypeConstructor
|
||||
): List<FunctionDescriptor> {
|
||||
val result = ArrayList<FunctionDescriptor>()
|
||||
|
||||
generateOverridesInAClass(klass, object : NonReportingOverrideStrategy() {
|
||||
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
|
||||
if (fakeOverride !is FunctionDescriptor) return
|
||||
val foundOverriddenFromDirectSuperClass =
|
||||
fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionTypeConstructor) ?: return
|
||||
val foundOverriddenFromDirectSuperClass = fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionTypeConstructor) ?: return
|
||||
if (foundOverriddenFromDirectSuperClass.kind == DECLARATION) {
|
||||
// For regular classes there should no be fake overrides having return types incompatible with return types of their
|
||||
// overridden, while here it's possible to create declaration like `fun remove(e: E): ImmutableCollection<E>`
|
||||
@@ -254,29 +254,23 @@ class CollectionStubMethodGenerator(
|
||||
// `fun iterator(): CharIterator` defined in read-only collection
|
||||
// The problem is that 'CharIterator' is not a subtype of 'MutableIterator' while from Java's point of view it is,
|
||||
// so we must hack our subtyping a little bit
|
||||
val newDescriptor =
|
||||
if (READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(
|
||||
fakeOverride.returnType!!,
|
||||
foundOverriddenFromDirectSuperClass.returnType!!
|
||||
)
|
||||
)
|
||||
fakeOverride
|
||||
else
|
||||
foundOverriddenFromDirectSuperClass.copy(
|
||||
fakeOverride.containingDeclaration,
|
||||
foundOverriddenFromDirectSuperClass.modality,
|
||||
foundOverriddenFromDirectSuperClass.visibility,
|
||||
fakeOverride.kind, false
|
||||
)
|
||||
val newDescriptor =
|
||||
if (READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(
|
||||
fakeOverride.returnType!!, foundOverriddenFromDirectSuperClass.returnType!!))
|
||||
fakeOverride
|
||||
else
|
||||
foundOverriddenFromDirectSuperClass.copy(
|
||||
fakeOverride.containingDeclaration,
|
||||
foundOverriddenFromDirectSuperClass.modality,
|
||||
foundOverriddenFromDirectSuperClass.visibility,
|
||||
fakeOverride.kind, false)
|
||||
|
||||
newDescriptor.overriddenDescriptors =
|
||||
fakeOverride.overriddenDescriptors.filter { superDescriptor ->
|
||||
// filter out incompatible descriptors, e.g. `fun remove(e: E): ImmutableCollection<E>` for `fun remove(e: E): Boolean`
|
||||
READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(
|
||||
newDescriptor.returnType!!,
|
||||
superDescriptor.returnType!!
|
||||
)
|
||||
}
|
||||
fakeOverride.overriddenDescriptors.filter {
|
||||
superDescriptor ->
|
||||
// filter out incompatible descriptors, e.g. `fun remove(e: E): ImmutableCollection<E>` for `fun remove(e: E): Boolean`
|
||||
READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(newDescriptor.returnType!!, superDescriptor.returnType!!)
|
||||
}
|
||||
|
||||
result.add(newDescriptor)
|
||||
}
|
||||
@@ -304,11 +298,11 @@ class CollectionStubMethodGenerator(
|
||||
private fun generateOverridesInAClass(classDescriptor: ClassDescriptor, strategy: OverridingStrategy) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val membersFromSupertypesByName =
|
||||
classDescriptor.typeConstructor.supertypes.flatMapTo(linkedSetOf()) { type ->
|
||||
DescriptorUtils.getAllDescriptors(type.memberScope).filter {
|
||||
it is PropertyDescriptor || it is SimpleFunctionDescriptor
|
||||
} as List<CallableMemberDescriptor>
|
||||
}.groupBy { it.name }
|
||||
classDescriptor.typeConstructor.supertypes.flatMapTo(linkedSetOf()) { type ->
|
||||
DescriptorUtils.getAllDescriptors(type.memberScope).filter {
|
||||
it is PropertyDescriptor || it is SimpleFunctionDescriptor
|
||||
} as List<CallableMemberDescriptor>
|
||||
}.groupBy { it.name }
|
||||
|
||||
for ((name, fromSupertypes) in membersFromSupertypesByName) {
|
||||
OverridingUtil.DEFAULT.generateOverridesInFunctionGroup(name, fromSupertypes, emptyList(), classDescriptor, strategy)
|
||||
@@ -327,7 +321,7 @@ class CollectionStubMethodGenerator(
|
||||
)
|
||||
|
||||
child.modality = Modality.FINAL
|
||||
child.visibility = DescriptorVisibilities.PUBLIC
|
||||
child.visibility = Visibilities.PUBLIC
|
||||
val typeParameters = descriptor.typeConstructor.parameters
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
|
||||
@@ -336,16 +330,15 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(typeConstructor: TypeConstructor): FunctionDescriptor? =
|
||||
this.overriddenDescriptors.firstOrNull {
|
||||
(it.containingDeclaration as? ClassDescriptor)?.typeConstructor == typeConstructor
|
||||
}
|
||||
this.overriddenDescriptors.firstOrNull {
|
||||
(it.containingDeclaration as? ClassDescriptor)?.typeConstructor == typeConstructor
|
||||
}
|
||||
|
||||
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType {
|
||||
return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, classDescriptor, typeArguments)
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.signature(): JvmMethodGenericSignature =
|
||||
typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION)
|
||||
private fun FunctionDescriptor.signature(): JvmMethodGenericSignature = typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION)
|
||||
|
||||
private fun generateMethodStub(v: ClassBuilder, signature: JvmMethodGenericSignature, synthetic: Boolean) {
|
||||
assert(descriptor.kind != ClassKind.INTERFACE) { "No stubs should be generated for interface ${descriptor.fqNameUnsafe}" }
|
||||
@@ -356,10 +349,9 @@ class CollectionStubMethodGenerator(
|
||||
val mv = v.newMethod(CollectionStub, access, asmMethod.name, asmMethod.descriptor, genericSignature, null)
|
||||
mv.visitCode()
|
||||
AsmUtil.genThrow(
|
||||
InstructionAdapter(mv),
|
||||
"java/lang/UnsupportedOperationException",
|
||||
"Operation is not supported for read-only collection"
|
||||
)
|
||||
InstructionAdapter(mv),
|
||||
"java/lang/UnsupportedOperationException",
|
||||
"Operation is not supported for read-only collection")
|
||||
FunctionCodegen.endVisit(mv, "built-in stub for $signature")
|
||||
}
|
||||
}
|
||||
@@ -368,7 +360,7 @@ private val READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER = KotlinTypeCheckerImpl.
|
||||
val firstClass = x.declarationDescriptor as? ClassDescriptor ?: return@withAxioms x == y
|
||||
val secondClass = y.declarationDescriptor as? ClassDescriptor ?: return@withAxioms x == y
|
||||
|
||||
val j2k = JavaToKotlinClassMapper
|
||||
val j2k = JavaToKotlinClassMap
|
||||
val firstReadOnly = if (j2k.isMutable(firstClass)) j2k.convertMutableToReadOnly(firstClass) else firstClass
|
||||
val secondReadOnly = if (j2k.isMutable(secondClass)) j2k.convertMutableToReadOnly(secondClass) else secondClass
|
||||
firstReadOnly.typeConstructor == secondReadOnly.typeConstructor
|
||||
|
||||
@@ -298,7 +298,7 @@ public class ConstructorCodegen {
|
||||
|
||||
int k = 1;
|
||||
for (FieldInfo info : argsFromClosure) {
|
||||
k = DescriptorAsmUtil.genAssignInstanceFieldFromParam(info, k, iv);
|
||||
k = AsmUtil.genAssignInstanceFieldFromParam(info, k, iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,8 +127,8 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
substituteCount: Int
|
||||
) {
|
||||
val typeMapper = state.typeMapper
|
||||
val isStatic = DescriptorAsmUtil.isStaticMethod(contextKind, functionDescriptor)
|
||||
val baseMethodFlags = DescriptorAsmUtil.getCommonCallableFlags(functionDescriptor, state) and Opcodes.ACC_VARARGS.inv()
|
||||
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
|
||||
val baseMethodFlags = AsmUtil.getCommonCallableFlags(functionDescriptor, state) and Opcodes.ACC_VARARGS.inv()
|
||||
val remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount)
|
||||
val remainingParametersDeclarations =
|
||||
remainingParameters.map { DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtParameter }
|
||||
@@ -153,18 +153,18 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
signature.genericsSignature,
|
||||
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper)
|
||||
)
|
||||
val skipNullabilityAnnotations = flags and Opcodes.ACC_PRIVATE != 0 || flags and Opcodes.ACC_SYNTHETIC != 0
|
||||
|
||||
AnnotationCodegen.forMethod(mv, memberCodegen, state, skipNullabilityAnnotations)
|
||||
.genAnnotations(functionDescriptor, signature.returnType, functionDescriptor.returnType)
|
||||
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(
|
||||
functionDescriptor,
|
||||
signature.returnType,
|
||||
functionDescriptor.returnType
|
||||
)
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.KAPT3) {
|
||||
mv.visitAnnotation(ANNOTATION_TYPE_DESCRIPTOR_FOR_JVM_OVERLOADS_GENERATED_METHODS, false)
|
||||
}
|
||||
|
||||
FunctionCodegen.generateParameterAnnotations(
|
||||
functionDescriptor, mv, signature, remainingParameters, memberCodegen, state, skipNullabilityAnnotations
|
||||
)
|
||||
FunctionCodegen.generateParameterAnnotations(functionDescriptor, mv, signature, remainingParameters, memberCodegen, state)
|
||||
|
||||
if (!state.classBuilderMode.generateBodies) {
|
||||
FunctionCodegen.generateLocalVariablesForParameters(
|
||||
@@ -268,7 +268,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
|
||||
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
||||
|
||||
if (DescriptorVisibilities.isPrivate(constructorDescriptor.visibility)) return false
|
||||
if (Visibilities.isPrivate(constructorDescriptor.visibility)) return false
|
||||
|
||||
if (constructorDescriptor.valueParameters.isEmpty()) return false
|
||||
if (classOrObject is KtClass && hasSecondaryConstructorsWithNoParameters(classOrObject)) return false
|
||||
|
||||
@@ -1,897 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil;
|
||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.InlineClassManglingRulesKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isToArrayFromCollection;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineWithReified;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmSyntheticAnnotation;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class DescriptorAsmUtil {
|
||||
private DescriptorAsmUtil() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNameForCapturedReceiverField(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings
|
||||
) {
|
||||
return getLabeledThisNameForReceiver(
|
||||
descriptor, bindingContext, languageVersionSettings, LABELED_THIS_FIELD, CAPTURED_RECEIVER_FIELD);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNameForReceiverParameter(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings
|
||||
) {
|
||||
return getLabeledThisNameForReceiver(
|
||||
descriptor, bindingContext, languageVersionSettings, LABELED_THIS_PARAMETER, RECEIVER_PARAMETER_NAME);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getLabeledThisNameForReceiver(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings,
|
||||
@NotNull String prefix,
|
||||
@NotNull String defaultName
|
||||
) {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.NewCapturedReceiverFieldNamingConvention)) {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
Name callableName = null;
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
String labelName = bindingContext.get(CodegenBinding.CALL_LABEL_FOR_LAMBDA_ARGUMENT, (FunctionDescriptor) descriptor);
|
||||
if (labelName != null) {
|
||||
return getLabeledThisName(labelName, prefix, defaultName);
|
||||
}
|
||||
|
||||
if (descriptor instanceof VariableAccessorDescriptor) {
|
||||
VariableAccessorDescriptor accessor = (VariableAccessorDescriptor) descriptor;
|
||||
callableName = accessor.getCorrespondingVariable().getName();
|
||||
}
|
||||
}
|
||||
|
||||
if (callableName == null) {
|
||||
callableName = descriptor.getName();
|
||||
}
|
||||
|
||||
if (callableName.isSpecial()) {
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
return getLabeledThisName(callableName.asString(), prefix, defaultName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type boxType(@NotNull Type type, @NotNull KotlinType kotlinType, @NotNull KotlinTypeMapper typeMapper) {
|
||||
if (InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
return typeMapper.mapTypeAsDeclaration(kotlinType);
|
||||
}
|
||||
|
||||
Type boxedPrimitiveType = boxPrimitiveType(type);
|
||||
return boxedPrimitiveType != null ? boxedPrimitiveType : type;
|
||||
}
|
||||
|
||||
public static boolean isPrimitiveNumberClassDescriptor(DeclarationDescriptor descriptor) {
|
||||
if (!(descriptor instanceof ClassDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
return isPrimitiveClass((ClassDescriptor) descriptor) && !isBoolean((ClassDescriptor) descriptor);
|
||||
}
|
||||
|
||||
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind, JvmDefaultMode jvmDefaultMode) {
|
||||
return (functionDescriptor.getModality() == Modality.ABSTRACT ||
|
||||
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !JvmAnnotationUtilKt
|
||||
.isCompiledToJvmDefault(functionDescriptor, jvmDefaultMode)))
|
||||
&& !isStaticMethod(kind, functionDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isStaticMethod(OwnerKind kind, CallableMemberDescriptor functionDescriptor) {
|
||||
return isStaticKind(kind) ||
|
||||
KotlinTypeMapper.isStaticAccessor(functionDescriptor) ||
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isStaticKind(OwnerKind kind) {
|
||||
return kind == OwnerKind.PACKAGE || kind == OwnerKind.DEFAULT_IMPLS || kind == OwnerKind.ERASED_INLINE_CLASS;
|
||||
}
|
||||
|
||||
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) {
|
||||
return getMethodAsmFlags(functionDescriptor, kind, state.getDeprecationProvider(), state.getJvmDefaultMode());
|
||||
}
|
||||
|
||||
public static int getMethodAsmFlags(
|
||||
FunctionDescriptor functionDescriptor,
|
||||
OwnerKind kind,
|
||||
DeprecationResolver deprecationResolver,
|
||||
JvmDefaultMode jvmDefaultMode
|
||||
) {
|
||||
int flags = getCommonCallableFlags(functionDescriptor, kind, deprecationResolver);
|
||||
|
||||
for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.METHOD_FLAGS) {
|
||||
flags |= flagAnnotation.getJvmFlag(functionDescriptor.getOriginal());
|
||||
}
|
||||
|
||||
if (functionDescriptor.getOriginal().isExternal()) {
|
||||
flags |= Opcodes.ACC_NATIVE;
|
||||
}
|
||||
|
||||
if (CodegenUtilKt.isJvmStaticInCompanionObject(functionDescriptor)) {
|
||||
// Native method will be a member of the class, the companion object method will be delegated to it
|
||||
flags &= ~Opcodes.ACC_NATIVE;
|
||||
}
|
||||
|
||||
if (functionDescriptor.getModality() == Modality.FINAL && !(functionDescriptor instanceof ConstructorDescriptor)) {
|
||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||
if (!(containingDeclaration instanceof ClassDescriptor) ||
|
||||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.INTERFACE) {
|
||||
flags |= ACC_FINAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (isStaticMethod(kind, functionDescriptor)) {
|
||||
flags |= ACC_STATIC;
|
||||
}
|
||||
|
||||
if (isAbstractMethod(functionDescriptor, kind, jvmDefaultMode)) {
|
||||
flags |= ACC_ABSTRACT;
|
||||
}
|
||||
|
||||
if (KotlinTypeMapper.isAccessor(functionDescriptor) ||
|
||||
hasJvmSyntheticAnnotation(functionDescriptor) ||
|
||||
isInlineClassWrapperConstructor(functionDescriptor, kind) ||
|
||||
InlineClassDescriptorResolver.isSynthesizedBoxMethod(functionDescriptor) ||
|
||||
InlineClassDescriptorResolver.isSynthesizedUnboxMethod(functionDescriptor)
|
||||
) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
private static boolean isInlineClassWrapperConstructor(@NotNull FunctionDescriptor functionDescriptor, @Nullable OwnerKind kind) {
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor)) return false;
|
||||
ClassDescriptor classDescriptor = ((ConstructorDescriptor) functionDescriptor).getConstructedClass();
|
||||
return classDescriptor.isInline() && kind == OwnerKind.IMPLEMENTATION;
|
||||
}
|
||||
|
||||
public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor, @NotNull GenerationState state) {
|
||||
return getCommonCallableFlags(functionDescriptor, null, state.getDeprecationProvider());
|
||||
}
|
||||
|
||||
private static int getCommonCallableFlags(
|
||||
FunctionDescriptor functionDescriptor,
|
||||
@Nullable OwnerKind kind,
|
||||
@NotNull DeprecationResolver deprecationResolver
|
||||
) {
|
||||
int flags = getVisibilityAccessFlag(functionDescriptor, kind);
|
||||
flags |= getVarargsFlag(functionDescriptor);
|
||||
flags |= getDeprecatedAccessFlag(functionDescriptor);
|
||||
if (deprecationResolver.isDeprecatedHidden(functionDescriptor) ||
|
||||
isInlineWithReified(functionDescriptor) ||
|
||||
functionDescriptor.isSuspend() && functionDescriptor.getVisibility().equals(DescriptorVisibilities.PRIVATE)) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static int getVisibilityAccessFlag(@NotNull MemberDescriptor descriptor) {
|
||||
return getVisibilityAccessFlag(descriptor, null);
|
||||
}
|
||||
|
||||
private static int getVisibilityAccessFlag(@NotNull MemberDescriptor descriptor, @Nullable OwnerKind kind) {
|
||||
Integer specialCase = specialCaseVisibility(descriptor, kind);
|
||||
if (specialCase != null) {
|
||||
return specialCase;
|
||||
}
|
||||
DescriptorVisibility visibility = descriptor.getVisibility();
|
||||
Integer defaultMapping = getVisibilityAccessFlag(visibility);
|
||||
if (defaultMapping == null) {
|
||||
throw new IllegalStateException(visibility + " is not a valid visibility in backend for " + DescriptorRenderer.DEBUG_TEXT.render(descriptor));
|
||||
}
|
||||
return defaultMapping;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Integer getVisibilityAccessFlag(DescriptorVisibility visibility) {
|
||||
return AsmUtil.getVisibilityAccessFlag(visibility.getDelegate());
|
||||
}
|
||||
|
||||
/*
|
||||
Use this method to get visibility flag for class to define it in byte code (v.defineClass method).
|
||||
For other cases use getVisibilityAccessFlag(MemberDescriptor descriptor)
|
||||
Classes in byte code should be public or package private
|
||||
*/
|
||||
public static int getVisibilityAccessFlagForClass(@NotNull ClassDescriptor descriptor) {
|
||||
if (descriptor instanceof SyntheticClassDescriptorForLambda) {
|
||||
return getVisibilityAccessFlagForAnonymous(descriptor);
|
||||
}
|
||||
if (descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
if (descriptor.getVisibility() == DescriptorVisibilities.PUBLIC ||
|
||||
descriptor.getVisibility() == DescriptorVisibilities.PROTECTED ||
|
||||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
|
||||
descriptor.getVisibility() == DescriptorVisibilities.LOCAL ||
|
||||
descriptor.getVisibility() == DescriptorVisibilities.INTERNAL) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
private static int getVisibilityAccessFlagForAnonymous(@NotNull ClassDescriptor descriptor) {
|
||||
return InlineUtil.isInlineOrContainingInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
public static int getSyntheticAccessFlagForLambdaClass(@NotNull ClassDescriptor descriptor) {
|
||||
return descriptor instanceof SyntheticClassDescriptorForLambda &&
|
||||
((SyntheticClassDescriptorForLambda) descriptor).isCallableReference() ? ACC_SYNTHETIC : 0;
|
||||
}
|
||||
|
||||
public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) {
|
||||
int visibility =
|
||||
innerClass instanceof SyntheticClassDescriptorForLambda
|
||||
? getVisibilityAccessFlagForAnonymous(innerClass)
|
||||
: innerClass.getVisibility() == DescriptorVisibilities.LOCAL
|
||||
? ACC_PUBLIC
|
||||
: getVisibilityAccessFlag(innerClass);
|
||||
return visibility |
|
||||
getSyntheticAccessFlagForLambdaClass(innerClass) |
|
||||
innerAccessFlagsForModalityAndKind(innerClass) |
|
||||
(innerClass.isInner() ? 0 : ACC_STATIC);
|
||||
}
|
||||
|
||||
private static int innerAccessFlagsForModalityAndKind(@NotNull ClassDescriptor innerClass) {
|
||||
switch (innerClass.getKind()) {
|
||||
case INTERFACE:
|
||||
return ACC_ABSTRACT | ACC_INTERFACE;
|
||||
case ENUM_CLASS:
|
||||
return ACC_FINAL | ACC_ENUM;
|
||||
case ANNOTATION_CLASS:
|
||||
return ACC_ABSTRACT | ACC_ANNOTATION | ACC_INTERFACE;
|
||||
default:
|
||||
Modality modality = innerClass.getModality();
|
||||
if (modality == Modality.FINAL) {
|
||||
return ACC_FINAL;
|
||||
}
|
||||
else if (modality == Modality.ABSTRACT || modality == Modality.SEALED) {
|
||||
return ACC_ABSTRACT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getDeprecatedAccessFlag(@NotNull MemberDescriptor descriptor) {
|
||||
if (descriptor instanceof PropertyAccessorDescriptor) {
|
||||
return KotlinBuiltIns.isDeprecated(descriptor)
|
||||
? ACC_DEPRECATED
|
||||
: getDeprecatedAccessFlag(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty());
|
||||
}
|
||||
else if (KotlinBuiltIns.isDeprecated(descriptor)) {
|
||||
return ACC_DEPRECATED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int getVarargsFlag(FunctionDescriptor functionDescriptor) {
|
||||
if (!functionDescriptor.getValueParameters().isEmpty()
|
||||
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
|
||||
.getVarargElementType() != null) {
|
||||
return ACC_VARARGS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor, @Nullable OwnerKind kind) {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
DescriptorVisibility memberVisibility = memberDescriptor.getVisibility();
|
||||
|
||||
if (JvmCodegenUtil.isNonIntrinsicPrivateCompanionObjectInInterface(memberDescriptor)) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof FunctionDescriptor &&
|
||||
isInlineClassWrapperConstructor((FunctionDescriptor) memberDescriptor, kind)) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (kind != OwnerKind.ERASED_INLINE_CLASS &&
|
||||
memberDescriptor instanceof ConstructorDescriptor &&
|
||||
!(memberDescriptor instanceof AccessorForConstructorDescriptor) &&
|
||||
InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters((ConstructorDescriptor) memberDescriptor)
|
||||
) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (isInlineOnlyPrivateInBytecode(memberDescriptor)) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (memberVisibility == DescriptorVisibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (isEnumEntry(memberDescriptor)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
if (isToArrayFromCollection(memberDescriptor)) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof ConstructorDescriptor && isAnonymousObject(memberDescriptor.getContainingDeclaration())) {
|
||||
return getVisibilityAccessFlagForAnonymous((ClassDescriptor) memberDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof SyntheticJavaPropertyDescriptor) {
|
||||
return getVisibilityAccessFlag(((SyntheticJavaPropertyDescriptor) memberDescriptor).getGetMethod());
|
||||
}
|
||||
if (memberDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) memberDescriptor).getCorrespondingProperty();
|
||||
if (property instanceof SyntheticJavaPropertyDescriptor) {
|
||||
FunctionDescriptor method = memberDescriptor == property.getGetter()
|
||||
? ((SyntheticJavaPropertyDescriptor) property).getGetMethod()
|
||||
: ((SyntheticJavaPropertyDescriptor) property).getSetMethod();
|
||||
assert method != null : "No get/set method in SyntheticJavaPropertyDescriptor: " + property;
|
||||
return getVisibilityAccessFlag(method);
|
||||
}
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof CallableDescriptor && memberVisibility == DescriptorVisibilities.PROTECTED) {
|
||||
for (CallableDescriptor overridden : DescriptorUtils.getAllOverriddenDescriptors((CallableDescriptor) memberDescriptor)) {
|
||||
if (isJvmInterface(overridden.getContainingDeclaration())) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DescriptorVisibilities.isPrivate(memberVisibility)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof FunctionDescriptor && ((FunctionDescriptor) memberDescriptor).isSuspend()) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof AccessorForCompanionObjectInstanceFieldDescriptor) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof ConstructorDescriptor && isEnumEntry(containingDeclaration)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void genClosureFields(
|
||||
@NotNull CalculatedClosure closure,
|
||||
ClassBuilder v,
|
||||
KotlinTypeMapper typeMapper,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings
|
||||
) {
|
||||
List<Pair<String, Type>> allFields = new ArrayList<>();
|
||||
|
||||
ClassifierDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
allFields.add(Pair.create(CAPTURED_THIS_FIELD, typeMapper.mapType(captureThis)));
|
||||
}
|
||||
|
||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||
if (captureReceiverType != null && !CallableReferenceUtilKt.isForCallableReference(closure)) {
|
||||
String fieldName = closure.getCapturedReceiverFieldName(typeMapper.getBindingContext(), languageVersionSettings);
|
||||
allFields.add(Pair.create(fieldName, typeMapper.mapType(captureReceiverType)));
|
||||
}
|
||||
|
||||
allFields.addAll(closure.getRecordedFields());
|
||||
genClosureFields(allFields, v);
|
||||
}
|
||||
|
||||
public static void genClosureFields(List<Pair<String, Type>> allFields, ClassBuilder builder) {
|
||||
int access = NO_FLAG_PACKAGE_PRIVATE | ACC_SYNTHETIC | ACC_FINAL;
|
||||
for (Pair<String, Type> field : allFields) {
|
||||
builder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, field.first, field.second.getDescriptor(), null, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static int genAssignInstanceFieldFromParam(FieldInfo info, int index, InstructionAdapter iv) {
|
||||
return genAssignInstanceFieldFromParam(info, index, iv, 0, false);
|
||||
}
|
||||
|
||||
public static int genAssignInstanceFieldFromParam(
|
||||
FieldInfo info,
|
||||
int index,
|
||||
InstructionAdapter iv,
|
||||
int ownerIndex,
|
||||
boolean cast
|
||||
) {
|
||||
assert !info.isStatic();
|
||||
Type fieldType = info.getFieldType();
|
||||
KotlinType fieldKotlinType = info.getFieldKotlinType();
|
||||
KotlinType nullableAny;
|
||||
if (fieldKotlinType != null) {
|
||||
nullableAny = fieldKotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||
} else {
|
||||
nullableAny = null;
|
||||
}
|
||||
|
||||
iv.load(ownerIndex, info.getOwnerType());//this
|
||||
if (cast) {
|
||||
iv.load(index, AsmTypes.OBJECT_TYPE); //param
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, nullableAny, fieldType, fieldKotlinType, iv);
|
||||
} else {
|
||||
iv.load(index, fieldType); //param
|
||||
}
|
||||
iv.visitFieldInsn(PUTFIELD, info.getOwnerInternalName(), info.getFieldName(), fieldType.getDescriptor());
|
||||
index += fieldType.getSize();
|
||||
return index;
|
||||
}
|
||||
|
||||
public static void genInvokeAppendMethod(
|
||||
@NotNull StringConcatGenerator generator,
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper,
|
||||
@NotNull StackValue stackValue
|
||||
) {
|
||||
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper);
|
||||
if (specializedToString != null) {
|
||||
stackValue.put(type, kotlinType, generator.getMv());
|
||||
specializedToString.genInvokeInstruction(generator.getMv());
|
||||
generator.invokeAppend(AsmTypes.JAVA_STRING_TYPE);
|
||||
}
|
||||
else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||
stackValue.put(type, kotlinType, generator.getMv());
|
||||
StackValue.coerce(type, kotlinType, OBJECT_TYPE, nullableAnyType, generator.getMv());
|
||||
generator.invokeAppend(OBJECT_TYPE);
|
||||
}
|
||||
else {
|
||||
generator.putValueOrProcessConstant(stackValue, type, kotlinType);
|
||||
}
|
||||
}
|
||||
|
||||
public static StackValue genToString(
|
||||
@NotNull StackValue receiver,
|
||||
@NotNull Type receiverType,
|
||||
@Nullable KotlinType receiverKotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper
|
||||
) {
|
||||
return StackValue.operation(JAVA_STRING_TYPE, v -> {
|
||||
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(receiverKotlinType, typeMapper);
|
||||
if (specializedToString != null) {
|
||||
receiver.put(receiverType, receiverKotlinType, v);
|
||||
specializedToString.genInvokeInstruction(v);
|
||||
return null;
|
||||
}
|
||||
|
||||
Type type;
|
||||
KotlinType kotlinType;
|
||||
if (receiverKotlinType != null && InlineClassesUtilsKt.isInlineClassType(receiverKotlinType)) {
|
||||
type = OBJECT_TYPE;
|
||||
kotlinType = receiverKotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||
}
|
||||
else {
|
||||
type = stringValueOfType(receiverType);
|
||||
kotlinType = null;
|
||||
}
|
||||
|
||||
receiver.put(type, kotlinType, v);
|
||||
v.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;", false);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CallableMethod getSpecializedToStringCallableMethodOrNull(
|
||||
@Nullable KotlinType receiverKotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper
|
||||
) {
|
||||
if (typeMapper == null) return null;
|
||||
|
||||
if (receiverKotlinType == null) return null;
|
||||
if (!InlineClassesUtilsKt.isInlineClassType(receiverKotlinType)) return null;
|
||||
if (receiverKotlinType.isMarkedNullable()) return null;
|
||||
|
||||
DeclarationDescriptor receiverTypeDescriptor = receiverKotlinType.getConstructor().getDeclarationDescriptor();
|
||||
assert receiverTypeDescriptor instanceof ClassDescriptor && ((ClassDescriptor) receiverTypeDescriptor).isInline() :
|
||||
"Inline class type expected: " + receiverKotlinType;
|
||||
ClassDescriptor receiverClassDescriptor = (ClassDescriptor) receiverTypeDescriptor;
|
||||
FunctionDescriptor toStringDescriptor = receiverClassDescriptor.getUnsubstitutedMemberScope()
|
||||
.getContributedFunctions(Name.identifier("toString"), NoLookupLocation.FROM_BACKEND)
|
||||
.stream()
|
||||
.filter(
|
||||
f -> f.getValueParameters().size() == 0
|
||||
&& KotlinBuiltIns.isString(f.getReturnType())
|
||||
&& f.getDispatchReceiverParameter() != null
|
||||
&& f.getExtensionReceiverParameter() == null
|
||||
)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AssertionError("'toString' not found in member scope of " + receiverClassDescriptor));
|
||||
|
||||
return typeMapper.mapToCallableMethod(toStringDescriptor, false, OwnerKind.ERASED_INLINE_CLASS);
|
||||
}
|
||||
|
||||
public static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) {
|
||||
if (type.getSort() == Type.ARRAY) {
|
||||
Type elementType = correctElementType(type);
|
||||
if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) {
|
||||
iv.invokestatic("java/util/Arrays", "hashCode", "([Ljava/lang/Object;)I", false);
|
||||
}
|
||||
else {
|
||||
iv.invokestatic("java/util/Arrays", "hashCode", "(" + type.getDescriptor() + ")I", false);
|
||||
}
|
||||
}
|
||||
else if (type.getSort() == Type.OBJECT) {
|
||||
iv.invokevirtual("java/lang/Object", "hashCode", "()I", false);
|
||||
}
|
||||
else if (type.getSort() == Type.BOOLEAN) {
|
||||
Label end = new Label();
|
||||
iv.dup();
|
||||
iv.ifeq(end);
|
||||
iv.pop();
|
||||
iv.iconst(1);
|
||||
iv.mark(end);
|
||||
}
|
||||
else {
|
||||
if (JvmTarget.JVM_1_6 == jvmTarget) {
|
||||
if (type.getSort() == Type.LONG) {
|
||||
genLongHashCode(mv, iv);
|
||||
}
|
||||
else if (type.getSort() == Type.DOUBLE) {
|
||||
iv.invokestatic("java/lang/Double", "doubleToLongBits", "(D)J", false);
|
||||
genLongHashCode(mv, iv);
|
||||
}
|
||||
else if (type.getSort() == Type.FLOAT) {
|
||||
iv.invokestatic("java/lang/Float", "floatToIntBits", "(F)I", false);
|
||||
}
|
||||
else { // byte short char int
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
HashCode.Companion.invokeHashCode(iv, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void genLongHashCode(MethodVisitor mv, InstructionAdapter iv) {
|
||||
iv.dup2();
|
||||
iv.iconst(32);
|
||||
iv.ushr(Type.LONG_TYPE);
|
||||
iv.xor(Type.LONG_TYPE);
|
||||
mv.visitInsn(L2I);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue genEqualsForExpressionsOnStack(
|
||||
@NotNull IElementType opToken,
|
||||
@NotNull StackValue left,
|
||||
@NotNull StackValue right
|
||||
) {
|
||||
Type leftType = left.type;
|
||||
Type rightType = right.type;
|
||||
if (isPrimitive(leftType) && leftType == rightType) {
|
||||
return StackValue.cmp(opToken, leftType, left, right);
|
||||
}
|
||||
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
left.put(AsmTypes.OBJECT_TYPE, left.kotlinType, v);
|
||||
right.put(AsmTypes.OBJECT_TYPE, right.kotlinType, v);
|
||||
return genAreEqualCall(v, opToken);
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BranchedValue genTotalOrderEqualsForExpressionOnStack(
|
||||
@NotNull StackValue left,
|
||||
@NotNull StackValue right,
|
||||
@NotNull Type asmType
|
||||
) {
|
||||
return new BranchedValue(left, right, asmType, Opcodes.IFEQ) {
|
||||
@Override
|
||||
public void condJump(@NotNull Label jumpLabel, @NotNull InstructionAdapter iv, boolean jumpIfFalse) {
|
||||
if (asmType.getSort() == Type.FLOAT) {
|
||||
left.put(asmType, kotlinType, iv);
|
||||
right.put(asmType, kotlinType, iv);
|
||||
iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
|
||||
iv.visitJumpInsn(patchOpcode(jumpIfFalse ? Opcodes.IFNE : Opcodes.IFEQ, iv), jumpLabel);
|
||||
} else if (asmType.getSort() == Type.DOUBLE) {
|
||||
left.put(asmType, kotlinType, iv);
|
||||
right.put(asmType, kotlinType, iv);
|
||||
iv.invokestatic("java/lang/Double", "compare", "(DD)I", false);
|
||||
iv.visitJumpInsn(patchOpcode(jumpIfFalse ? Opcodes.IFNE : Opcodes.IFEQ, iv), jumpLabel);
|
||||
} else {
|
||||
StackValue value = genEqualsForExpressionsOnStack(KtTokens.EQEQ, left, right);
|
||||
BranchedValue.Companion.condJump(value, jumpLabel, jumpIfFalse, iv);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue genEqualsBoxedOnStack(@NotNull IElementType opToken) {
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> genAreEqualCall(v, opToken));
|
||||
}
|
||||
|
||||
public static void genAreEqualCall(InstructionAdapter v) {
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Unit genAreEqualCall(InstructionAdapter v, @NotNull IElementType opToken) {
|
||||
genAreEqualCall(v);
|
||||
|
||||
if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
genInvertBoolean(v);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
public static void genIEEE754EqualForNullableTypesCall(InstructionAdapter v, Type left, Type right) {
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(" + left.getDescriptor() + right.getDescriptor() + ")Z", false);
|
||||
}
|
||||
|
||||
public static void genIncrement(Type baseType, int myDelta, InstructionAdapter v) {
|
||||
Type operationType = numberFunctionOperandType(baseType);
|
||||
numConst(myDelta, operationType, v);
|
||||
v.add(operationType);
|
||||
StackValue.coerce(operationType, baseType, v);
|
||||
}
|
||||
|
||||
static void genNotNullAssertionsForParameters(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull FrameMap frameMap
|
||||
) {
|
||||
if (state.isParamAssertionsDisabled()) return;
|
||||
// currently when resuming a suspend function we pass default values instead of real arguments (i.e. nulls for references)
|
||||
if (descriptor.isSuspend()) return;
|
||||
|
||||
if (getVisibilityAccessFlag(descriptor) == ACC_PRIVATE) {
|
||||
// Private method is not accessible from other classes, no assertions needed,
|
||||
// unless we have a private operator function, in which we should generate a parameter assertion for an extension receiver.
|
||||
|
||||
// HACK: this provides "fail fast" behavior for operator functions.
|
||||
// Such functions can be invoked in operator conventions desugaring,
|
||||
// which is currently done on ad hoc basis in ExpressionCodegen.
|
||||
|
||||
if (state.isReceiverAssertionsDisabled()) return;
|
||||
if (descriptor.isOperator()) {
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
String name = getNameForReceiverParameter(descriptor, state.getBindingContext(), state.getLanguageVersionSettings());
|
||||
genParamAssertion(v, state, frameMap, receiverParameter, name, descriptor);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
String name = getNameForReceiverParameter(descriptor, state.getBindingContext(), state.getLanguageVersionSettings());
|
||||
genParamAssertion(v, state, frameMap, receiverParameter, name, descriptor);
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) {
|
||||
genParamAssertion(v, state, frameMap, parameter, parameter.getName().asString(), descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void genParamAssertion(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull ParameterDescriptor parameter,
|
||||
@NotNull String name,
|
||||
@NotNull FunctionDescriptor containingDeclaration
|
||||
) {
|
||||
KotlinType type = parameter.getType();
|
||||
if (isNullableType(type) || InlineClassesUtilsKt.isNullableUnderlyingType(type)) return;
|
||||
|
||||
Type asmType = state.getTypeMapper().mapType(type);
|
||||
if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) {
|
||||
StackValue value;
|
||||
if (JvmCodegenUtil.isDeclarationOfBigArityFunctionInvoke(containingDeclaration) ||
|
||||
JvmCodegenUtil.isDeclarationOfBigArityCreateCoroutineMethod(containingDeclaration)) {
|
||||
int index = getIndexOfParameterInVarargInvokeArray(parameter);
|
||||
value = StackValue.arrayElement(
|
||||
OBJECT_TYPE, null, StackValue.local(1, getArrayType(OBJECT_TYPE)), StackValue.constant(index)
|
||||
);
|
||||
}
|
||||
else {
|
||||
int index = frameMap.getIndex(parameter);
|
||||
value = StackValue.local(index, asmType);
|
||||
}
|
||||
value.put(asmType, v);
|
||||
v.visitLdcInsn(name);
|
||||
String methodName = state.getUnifiedNullChecks() ? "checkNotNullParameter" : "checkParameterIsNotNull";
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, methodName, "(Ljava/lang/Object;Ljava/lang/String;)V", false);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue genNotNullAssertions(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull StackValue stackValue,
|
||||
@Nullable RuntimeAssertionInfo runtimeAssertionInfo
|
||||
) {
|
||||
if (state.isCallAssertionsDisabled()) return stackValue;
|
||||
if (runtimeAssertionInfo == null || !runtimeAssertionInfo.getNeedNotNullAssertion()) return stackValue;
|
||||
|
||||
return new StackValue(stackValue.type, stackValue.kotlinType) {
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type innerType = stackValue.type;
|
||||
KotlinType innerKotlinType = stackValue.kotlinType;
|
||||
stackValue.put(innerType, innerKotlinType, v);
|
||||
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
|
||||
v.dup();
|
||||
v.visitLdcInsn(runtimeAssertionInfo.getMessage());
|
||||
String methodName = state.getUnifiedNullChecks() ? "checkNotNullExpressionValue" : "checkExpressionValueIsNotNull";
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, methodName, "(Ljava/lang/Object;Ljava/lang/String;)V", false);
|
||||
}
|
||||
StackValue.coerce(innerType, innerKotlinType, type, kotlinType, v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static int getIndexOfParameterInVarargInvokeArray(@NotNull ParameterDescriptor parameter) {
|
||||
if (parameter instanceof ReceiverParameterDescriptor) return 0;
|
||||
|
||||
DeclarationDescriptor container = parameter.getContainingDeclaration();
|
||||
assert parameter instanceof ValueParameterDescriptor : "Non-extension-receiver parameter must be a value parameter: " + parameter;
|
||||
int extensionShift = ((CallableDescriptor) container).getExtensionReceiverParameter() == null ? 0 : 1;
|
||||
|
||||
return extensionShift + ((ValueParameterDescriptor) parameter).getIndex();
|
||||
}
|
||||
|
||||
// At the beginning of the vararg invoke of a function with big arity N, generates an assert that the vararg parameter has N elements
|
||||
public static void generateVarargInvokeArityAssert(InstructionAdapter v, int functionArity) {
|
||||
Label start = new Label();
|
||||
v.load(1, getArrayType(OBJECT_TYPE));
|
||||
v.arraylength();
|
||||
v.iconst(functionArity);
|
||||
v.ificmpeq(start);
|
||||
v.visitLdcInsn("Vararg argument must contain " + functionArity + " elements.");
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwIllegalArgument", "(Ljava/lang/String;)V", false);
|
||||
v.visitLabel(start);
|
||||
}
|
||||
|
||||
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||
isObject(propertyDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
public static int getVisibilityForBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
if (isDelegate || isExtensionProperty) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
else {
|
||||
return propertyDescriptor.isLateInit() || isConstOrHasJvmFieldAnnotation(propertyDescriptor)
|
||||
? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor))
|
||||
: ACC_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
private static MemberDescriptor descriptorForVisibility(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
if (!propertyDescriptor.isVar()) {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
else {
|
||||
return propertyDescriptor.getSetter() != null ? propertyDescriptor.getSetter() : propertyDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
|
||||
return propertyDescriptor.isConst()
|
||||
&& isCompanionObject(propertyContainer) && isJvmInterface(propertyContainer.getContainingDeclaration())
|
||||
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public static void writeAnnotationData(
|
||||
@NotNull AnnotationVisitor av,
|
||||
@NotNull DescriptorSerializer serializer,
|
||||
@NotNull MessageLite message
|
||||
) {
|
||||
writeAnnotationData(av, message, (JvmStringTable) serializer.getStringTable());
|
||||
}
|
||||
|
||||
public static void writeAnnotationData(
|
||||
@NotNull AnnotationVisitor av, @NotNull MessageLite message, @NotNull JvmStringTable stringTable
|
||||
) {
|
||||
AsmUtil.writeAnnotationData(av, JvmProtoBufUtil.writeData(message, stringTable), ArrayUtil.toStringArray(stringTable.getStrings()));
|
||||
}
|
||||
|
||||
public static void putJavaLangClassInstance(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
) {
|
||||
if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
v.aconst(boxType(type, kotlinType, typeMapper));
|
||||
}
|
||||
else if (isPrimitive(type)) {
|
||||
v.getstatic(AsmUtil.boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
|
||||
}
|
||||
else {
|
||||
v.aconst(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getReceiverIndex(@NotNull CodegenContext context, @NotNull CallableMemberDescriptor descriptor) {
|
||||
OwnerKind kind = context.getContextKind();
|
||||
//Trait always should have this descriptor
|
||||
return kind != OwnerKind.DEFAULT_IMPLS && isStaticMethod(kind, descriptor) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.genTotalOrderEqualsForExpressionOnStack
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genTotalOrderEqualsForExpressionOnStack
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
|
||||
@@ -51,9 +51,9 @@ import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||
import org.jetbrains.kotlin.load.kotlin.DescriptorBasedTypeSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.MethodSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
@@ -97,11 +97,8 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.boxType;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.*;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.boxType;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
|
||||
@@ -176,7 +173,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class BlockStackElement {
|
||||
static class BlockStackElement {
|
||||
}
|
||||
|
||||
static class LoopBlockStackElement extends BlockStackElement {
|
||||
@@ -315,8 +312,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
stackValue = suspendFunctionTypeWrapperIfNeeded(selector, stackValue);
|
||||
|
||||
stackValue = coerceAndBoxInlineClassIfNeeded(selector, stackValue);
|
||||
|
||||
RuntimeAssertionInfo runtimeAssertionInfo = null;
|
||||
if (selector instanceof KtExpression) {
|
||||
KtExpression expression = (KtExpression) selector;
|
||||
@@ -365,53 +360,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return stackValue;
|
||||
}
|
||||
|
||||
private StackValue coerceAndBoxInlineClassIfNeeded(KtElement selector, StackValue stackValue) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(selector, bindingContext);
|
||||
if (resolvedCall == null) return stackValue;
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
if (!(descriptor instanceof FunctionDescriptor)) return stackValue;
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
if (!functionDescriptor.isSuspend()) return stackValue;
|
||||
|
||||
KotlinType unboxedInlineClass = CoroutineCodegenUtilKt
|
||||
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(functionDescriptor, typeMapper);
|
||||
|
||||
StackValue stackValueToWrap = stackValue;
|
||||
KotlinType originalKotlinType;
|
||||
if (unboxedInlineClass != null) {
|
||||
originalKotlinType = unboxedInlineClass;
|
||||
} else {
|
||||
originalKotlinType = stackValueToWrap.kotlinType;
|
||||
}
|
||||
Type originalType;
|
||||
if (unboxedInlineClass != null) {
|
||||
originalType = typeMapper.mapType(unboxedInlineClass);
|
||||
} else {
|
||||
originalType = stackValueToWrap.type;
|
||||
}
|
||||
|
||||
stackValue = new StackValue(originalType, originalKotlinType) {
|
||||
@Override
|
||||
public void putSelector(
|
||||
@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v
|
||||
) {
|
||||
if (((originalKotlinType != null && InlineClassesUtilsKt.isInlineClassType(originalKotlinType)) ||
|
||||
(kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)))
|
||||
) {
|
||||
stackValueToWrap.put(v);
|
||||
// Suspend functions always return Ljava/lang/Object;, so, before inline-class boxing/unboxing we need to generate CHECKCAST
|
||||
StackValue.coerce(OBJECT_TYPE, originalType, v);
|
||||
// Box/unbox inline class
|
||||
StackValue.coerce(originalType, originalKotlinType, type, kotlinType, v);
|
||||
} else {
|
||||
// No inline class -> usual coerce is enough
|
||||
stackValueToWrap.put(type, kotlinType, v);
|
||||
}
|
||||
}
|
||||
};
|
||||
return stackValue;
|
||||
}
|
||||
|
||||
public StackValue gen(KtElement expr) {
|
||||
StackValue tempVar = tempVariables.get(expr);
|
||||
return tempVar != null ? tempVar : genQualified(StackValue.none(), expr);
|
||||
@@ -925,27 +873,28 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
else {
|
||||
return StackValue.operation(type, v -> {
|
||||
StringConcatGenerator generator = StringConcatGenerator.Companion.create(state, v);
|
||||
generator.genStringBuilderConstructorIfNeded();
|
||||
invokeAppendForEntries(generator, entries);
|
||||
generator.genToString();
|
||||
genStringBuilderConstructor(v);
|
||||
invokeAppendForEntries(v, entries);
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeAppendForEntries(StringConcatGenerator generator, List<StringTemplateEntry> entries) {
|
||||
private void invokeAppendForEntries(InstructionAdapter v, List<StringTemplateEntry> entries) {
|
||||
for (StringTemplateEntry entry : entries) {
|
||||
if (entry instanceof StringTemplateEntry.Expression) {
|
||||
invokeAppend(generator, ((StringTemplateEntry.Expression) entry).expression);
|
||||
invokeAppend(v, ((StringTemplateEntry.Expression) entry).expression);
|
||||
}
|
||||
else {
|
||||
String value = ((StringTemplateEntry.Constant) entry).value;
|
||||
if (value.length() == 1) {
|
||||
generator.putValueOrProcessConstant(StackValue.constant(value.charAt(0), Type.CHAR_TYPE, null));
|
||||
v.iconst(value.charAt(0));
|
||||
genInvokeAppendMethod(v, Type.CHAR_TYPE, null);
|
||||
}
|
||||
else {
|
||||
generator.addStringConstant(value);
|
||||
v.aconst(value);
|
||||
genInvokeAppendMethod(v, JAVA_STRING_TYPE, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1527,7 +1476,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
assert !functionIndex.isEmpty();
|
||||
|
||||
String localVariableName = AsmUtil.LOCAL_FUNCTION_VARIABLE_PREFIX
|
||||
+ CommonVariableAsmNameManglingUtils.mangleNameIfNeeded(functionDescriptor.getName().asString())
|
||||
+ VariableAsmNameManglingUtils.mangleNameIfNeeded(functionDescriptor.getName().asString())
|
||||
+ "$" + functionIndex;
|
||||
|
||||
v.visitLocalVariable(localVariableName, type.getDescriptor(), null, scopeStart, blockEnd, index);
|
||||
@@ -1705,38 +1654,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type returnType;
|
||||
KotlinType returnKotlinType;
|
||||
if (isNonLocalReturn) {
|
||||
// This is inline lambda. Find inline-site and check, whether it is suspend functions returning unboxed inline class
|
||||
CodegenContext<?> inlineSiteContext = this.context.getFirstCrossInlineOrNonInlineContext();
|
||||
KotlinType originalInlineClass = null;
|
||||
boolean invokeSuspendOfLambda = false;
|
||||
FunctionDescriptor inlineSiteDescriptor = null;
|
||||
if (inlineSiteContext instanceof MethodContext) {
|
||||
inlineSiteDescriptor = ((MethodContext) inlineSiteContext).getFunctionDescriptor();
|
||||
originalInlineClass = CoroutineCodegenUtilKt
|
||||
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(inlineSiteDescriptor, typeMapper);
|
||||
invokeSuspendOfLambda = CoroutineCodegenUtilKt.isInvokeSuspendOfLambda(inlineSiteDescriptor);
|
||||
}
|
||||
if (originalInlineClass != null) {
|
||||
returnType = typeMapper.mapType(originalInlineClass);
|
||||
returnKotlinType = originalInlineClass;
|
||||
} else if (!invokeSuspendOfLambda) {
|
||||
returnType = nonLocalReturn.returnType.getType();
|
||||
returnKotlinType = nonLocalReturn.returnType.getKotlinType();
|
||||
} else {
|
||||
returnType = OBJECT_TYPE;
|
||||
returnKotlinType = inlineSiteDescriptor.getReturnType();
|
||||
}
|
||||
returnType = nonLocalReturn.returnType.getType();
|
||||
returnKotlinType = nonLocalReturn.returnType.getKotlinType();
|
||||
}
|
||||
else {
|
||||
KotlinType originalInlineClass = CoroutineCodegenUtilKt
|
||||
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(context.getFunctionDescriptor(), typeMapper);
|
||||
if (originalInlineClass != null) {
|
||||
returnType = typeMapper.mapType(originalInlineClass);
|
||||
returnKotlinType = originalInlineClass;
|
||||
} else {
|
||||
returnType = this.returnType;
|
||||
returnKotlinType = this.context.getFunctionDescriptor().getReturnType();
|
||||
}
|
||||
returnType = this.returnType;
|
||||
returnKotlinType = typeMapper.getReturnValueType(this.context.getFunctionDescriptor());
|
||||
}
|
||||
StackValue valueToReturn = returnedExpression != null ? gen(returnedExpression) : StackValue.none();
|
||||
|
||||
@@ -1791,7 +1714,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return new NonLocalReturnInfo(
|
||||
new JvmKotlinType(
|
||||
typeMapper.mapReturnType(containingFunction),
|
||||
containingFunction.getReturnType()
|
||||
typeMapper.getReturnValueType(containingFunction)
|
||||
),
|
||||
FIRST_FUN_LABEL
|
||||
);
|
||||
@@ -1821,27 +1744,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
FunctionDescriptor originalSuspendLambdaDescriptor = getOriginalSuspendLambdaDescriptorFromContext(context);
|
||||
boolean isVoidCoroutineLambda =
|
||||
originalSuspendLambdaDescriptor != null && DescriptorBasedTypeSignatureMappingKt
|
||||
.hasVoidReturnType(originalSuspendLambdaDescriptor);
|
||||
|
||||
KotlinType originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass =
|
||||
CoroutineCodegenUtilKt.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(
|
||||
context.getFunctionDescriptor(), typeMapper);
|
||||
originalSuspendLambdaDescriptor != null && TypeSignatureMappingKt.hasVoidReturnType(originalSuspendLambdaDescriptor);
|
||||
|
||||
// If generating body for named block-bodied function or Unit-typed coroutine lambda, generate it as sequence of statements
|
||||
Type typeForExpression =
|
||||
isBlockedNamedFunction || isVoidCoroutineLambda
|
||||
? Type.VOID_TYPE
|
||||
: originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass != null
|
||||
? typeMapper.mapType(originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass)
|
||||
: returnType;
|
||||
: returnType;
|
||||
|
||||
KotlinType kotlinTypeForExpression =
|
||||
isBlockedNamedFunction || isVoidCoroutineLambda
|
||||
? null
|
||||
: originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass != null
|
||||
? originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass
|
||||
: context.getFunctionDescriptor().getReturnType();
|
||||
: typeMapper.getReturnValueType(context.getFunctionDescriptor());
|
||||
|
||||
gen(expr, typeForExpression, kotlinTypeForExpression);
|
||||
|
||||
@@ -1995,21 +1909,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
StackValue localOrCaptured = findLocalOrCapturedValue(descriptor);
|
||||
if (localOrCaptured != null) {
|
||||
if (descriptor instanceof ValueParameterDescriptor) {
|
||||
KotlinType inlineClassType = ((ValueParameterDescriptor) descriptor).getType();
|
||||
if (InlineClassesCodegenUtilKt.isInlineClassWithUnderlyingTypeAnyOrAnyN(inlineClassType) &&
|
||||
InlineClassesCodegenUtilKt.isGenericParameter((CallableDescriptor) descriptor) &&
|
||||
// TODO: HACK around bridgeGenerationCrossinline
|
||||
!(context instanceof InlineLambdaContext) &&
|
||||
// Do not unbox parameters of suspend lambda, they are unboxed in `invoke` method
|
||||
!CoroutineCodegenUtilKt.isInvokeSuspendOfLambda(context.getFunctionDescriptor())
|
||||
) {
|
||||
KotlinType underlyingType = InlineClassesUtilsKt.underlyingRepresentation(
|
||||
(ClassDescriptor) inlineClassType.getConstructor().getDeclarationDescriptor()).getType();
|
||||
return StackValue.underlyingValueOfInlineClass(
|
||||
typeMapper.mapType(underlyingType), underlyingType, localOrCaptured);
|
||||
}
|
||||
}
|
||||
return localOrCaptured;
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
||||
@@ -2275,14 +2174,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
boolean isBackingFieldMovedFromCompanion = DescriptorsJvmAbiUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
boolean isBackingFieldMovedFromCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
AccessorKind fieldAccessorKind;
|
||||
if (skipLateinitAssertion) {
|
||||
fieldAccessorKind = AccessorKind.LATEINIT_INTRINSIC;
|
||||
}
|
||||
else if (isBackingFieldMovedFromCompanion &&
|
||||
(forceField ||
|
||||
(DescriptorVisibilities.isPrivate(propertyDescriptor.getVisibility()) &&
|
||||
(Visibilities.isPrivate(propertyDescriptor.getVisibility()) &&
|
||||
isDefaultAccessor(propertyDescriptor.getGetter()) && isDefaultAccessor(propertyDescriptor.getSetter())))) {
|
||||
fieldAccessorKind = JvmCodegenUtil.isDebuggerContext(context) ? AccessorKind.NORMAL : AccessorKind.IN_CLASS_COMPANION;
|
||||
}
|
||||
@@ -2295,7 +2194,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
fieldAccessorKind = AccessorKind.NORMAL;
|
||||
}
|
||||
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
|
||||
DescriptorAsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
|
||||
AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
|
||||
boolean isSuper = superCallTarget != null;
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
|
||||
@@ -2308,7 +2207,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
CodegenContext<?> backingFieldContext = getBackingFieldContext(fieldAccessorKind, containingDeclaration);
|
||||
boolean isPrivateProperty =
|
||||
fieldAccessorKind != AccessorKind.NORMAL &&
|
||||
(DescriptorAsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty) & ACC_PRIVATE) != 0;
|
||||
(AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty) & ACC_PRIVATE) != 0;
|
||||
DeclarationDescriptor ownerDescriptor;
|
||||
boolean skipPropertyAccessors;
|
||||
|
||||
@@ -2325,9 +2224,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
if (isBackingFieldMovedFromCompanion && context.getContextDescriptor() instanceof AccessorForPropertyBackingField) {
|
||||
CodegenContext<?> parentContext = backingFieldContext.getParentContext();
|
||||
propertyDescriptor =
|
||||
parentContext.getAccessor(propertyDescriptor, AccessorKind.IN_CLASS_COMPANION, delegateType, superCallTarget);
|
||||
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getParentContext()
|
||||
.getAccessor(propertyDescriptor, AccessorKind.IN_CLASS_COMPANION, delegateType, superCallTarget);
|
||||
}
|
||||
else {
|
||||
propertyDescriptor =
|
||||
@@ -2355,7 +2253,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
skipPropertyAccessors = forceField;
|
||||
|
||||
if (JvmCodegenUtil.isDebuggerContext(context)
|
||||
&& DescriptorVisibilities.isPrivate(propertyDescriptor.getVisibility())
|
||||
&& Visibilities.isPrivate(propertyDescriptor.getVisibility())
|
||||
&& bindingContext.get(BACKING_FIELD_REQUIRED, propertyDescriptor) == Boolean.TRUE
|
||||
) {
|
||||
skipPropertyAccessors = true;
|
||||
@@ -2714,7 +2612,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
SuspensionPointKind suspensionPointKind =
|
||||
CoroutineCodegenUtilKt.isSuspensionPoint(resolvedCall, this, state.getLanguageVersionSettings());
|
||||
boolean maybeSuspensionPoint = suspensionPointKind != SuspensionPointKind.NEVER && !insideCallableReference();
|
||||
boolean maybeSuspensionPoint = suspensionPointKind != SuspensionPointKind.NEVER;
|
||||
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
|
||||
if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) {
|
||||
putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, maybeSuspensionPoint, isConstructor);
|
||||
@@ -2758,23 +2656,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
||||
|
||||
if (maybeSuspensionPoint) {
|
||||
// The order is important! Do not reorder!
|
||||
// CoroutineTransformerMethodVisitor expects the marker exactly in this order.
|
||||
addReturnsUnitMarkerIfNecessary(v, resolvedCall);
|
||||
addSuspendMarker(v, false, suspensionPointKind == SuspensionPointKind.NOT_INLINE);
|
||||
addUnboxInlineClassMarkersIfNeeded(v, resolvedCall.getResultingDescriptor(), typeMapper);
|
||||
addInlineMarker(v, false);
|
||||
}
|
||||
|
||||
// If a suspend function returns unboxed inline class, we should check for COROUTINE_SUSPENDED and only then box the inline class.
|
||||
if (insideCallableReference() && resolvedCall.getResultingDescriptor() instanceof FunctionDescriptor) {
|
||||
KotlinType unboxedInlineClass = CoroutineCodegenUtilKt.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(
|
||||
(FunctionDescriptor) resolvedCall.getResultingDescriptor(), typeMapper);
|
||||
if (unboxedInlineClass != null) {
|
||||
CoroutineCodegenUtilKt.generateCoroutineSuspendedCheck(v, state.getLanguageVersionSettings());
|
||||
}
|
||||
}
|
||||
|
||||
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
if (state.getUseKotlinNothingValueException()) {
|
||||
@@ -2788,10 +2674,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
private boolean insideCallableReference() {
|
||||
return (parentCodegen instanceof ClosureCodegen) && ((ClosureCodegen) parentCodegen).isCallableReference();
|
||||
}
|
||||
|
||||
private void putReceiverAndInlineMarkerIfNeeded(
|
||||
@NotNull Callable callableMethod,
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@@ -2860,7 +2742,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
myFrameMap.leaveTemp(firstReceiverType);
|
||||
}
|
||||
|
||||
callableMethod.afterReceiverGeneration(v, myFrameMap, state);
|
||||
callableMethod.afterReceiverGeneration(v, myFrameMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2953,7 +2835,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
TypeApproximator approximator = new TypeApproximator(state.getModule().getBuiltIns());
|
||||
|
||||
KotlinType approximatedType =
|
||||
TypeUtils.contains(type, (containedType) -> CapturedTypeConstructorKt.isCaptured(containedType)) ?
|
||||
CapturedTypeConstructorKt.isCaptured(type) ?
|
||||
(KotlinType) approximator.approximateToSuperType(
|
||||
type, TypeApproximatorConfiguration.InternalTypesApproximation.INSTANCE
|
||||
) : null;
|
||||
@@ -3054,7 +2936,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return null;
|
||||
}
|
||||
|
||||
int accessFlag = DescriptorAsmUtil.getVisibilityAccessFlag(companionObjectDescriptor);
|
||||
int accessFlag = AsmUtil.getVisibilityAccessFlag(companionObjectDescriptor);
|
||||
|
||||
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();
|
||||
boolean isInlineMethodContext = context.isInlineMethodContext();
|
||||
@@ -4024,7 +3906,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type rightType = right754Type.isNullable ? AsmUtil.boxType(right754Type.type) : right754Type.type;
|
||||
gen(right, rightType);
|
||||
|
||||
DescriptorAsmUtil.genIEEE754EqualForNullableTypesCall(v, leftType, rightType);
|
||||
AsmUtil.genIEEE754EqualForNullableTypesCall(v, leftType, rightType);
|
||||
|
||||
if (opToken == KtTokens.EXCLEQ) {
|
||||
genInvertBoolean(v);
|
||||
@@ -4221,14 +4103,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
TypeAndNullability right754Type = calcTypeForIeee754ArithmeticIfNeeded(right, getRightOperandType(primitiveNumericComparisonInfo));
|
||||
boolean isSame754ArithmeticTypes = left754Type != null && right754Type != null && left754Type.type.equals(right754Type.type);
|
||||
boolean properIeee754Comparisons = shouldUseProperIeee754Comparisons();
|
||||
boolean isStandardCompareTo = primitiveNumericComparisonInfo != null;
|
||||
|
||||
if (properIeee754Comparisons && isStandardCompareTo && left754Type != null && right754Type != null) {
|
||||
if (properIeee754Comparisons && left754Type != null && right754Type != null) {
|
||||
type = comparisonOperandType(left754Type.type, right754Type.type);
|
||||
//type = comparisonOperandType(leftType, rightType);
|
||||
leftValue = gen(left);
|
||||
rightValue = gen(right);
|
||||
}
|
||||
else if (!properIeee754Comparisons && isStandardCompareTo &&
|
||||
else if (!properIeee754Comparisons &&
|
||||
state.getIntrinsics().getIntrinsic((FunctionDescriptor) resolvedCall.getResultingDescriptor()) instanceof CompareTo &&
|
||||
((isPrimitive(leftType) && isPrimitive(rightType)) || isSame754ArithmeticTypes)) {
|
||||
type = isSame754ArithmeticTypes ? left754Type.type : comparisonOperandType(leftType, rightType);
|
||||
leftValue = gen(left);
|
||||
@@ -4321,7 +4204,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeAppend(StringConcatGenerator generator, KtExpression expr) {
|
||||
public void invokeAppend(InstructionAdapter v, KtExpression expr) {
|
||||
expr = KtPsiUtil.safeDeparenthesize(expr);
|
||||
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
||||
@@ -4335,29 +4218,28 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type leftType = expressionType(left);
|
||||
|
||||
if (leftType.equals(JAVA_STRING_TYPE)) {
|
||||
invokeAppend(generator, left);
|
||||
invokeAppend(generator, right);
|
||||
invokeAppend(v, left);
|
||||
invokeAppend(v, right);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expr instanceof KtStringTemplateExpression) {
|
||||
List<StringTemplateEntry> entries = preprocessStringTemplate((KtStringTemplateExpression) expr);
|
||||
invokeAppendForEntries(generator, entries);
|
||||
invokeAppendForEntries(v, entries);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Type exprType = expressionType(expr);
|
||||
KotlinType exprKotlinType = kotlinType(expr);
|
||||
StackValue value;
|
||||
if (compileTimeConstant != null) {
|
||||
value = StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType);
|
||||
StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType).put(exprType, exprKotlinType, v);
|
||||
} else {
|
||||
value = gen(expr);
|
||||
gen(expr, exprType, exprKotlinType);
|
||||
}
|
||||
|
||||
genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper, value);
|
||||
genInvokeAppendMethod(v, exprType, exprKotlinType, typeMapper);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -5169,9 +5051,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateAsCast(
|
||||
v, rightKotlinType, boxedRightType, safeAs, state.getLanguageVersionSettings(), state.getUnifiedNullChecks()
|
||||
);
|
||||
CodegenUtilKt.generateAsCast(v, rightKotlinType, boxedRightType, safeAs, state.getLanguageVersionSettings());
|
||||
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMappingUtilsKt;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
@@ -25,7 +24,7 @@ public class FieldInfo {
|
||||
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
||||
}
|
||||
|
||||
if (isNonCompanionObject(classDescriptor) || CompanionObjectMappingUtilsKt.isMappedIntrinsicCompanionObject(CompanionObjectMapping.INSTANCE, classDescriptor)) {
|
||||
if (isNonCompanionObject(classDescriptor) || CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject(classDescriptor)) {
|
||||
return createSingletonViaInstance(classDescriptor, typeMapper, JvmAbi.INSTANCE_FIELD);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,10 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
@@ -67,15 +70,13 @@ import java.io.StringWriter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.boxType;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.generateBridgeForMainFunctionIfNecessary;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.isAccessor;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION;
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityUtilsKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
|
||||
@@ -85,8 +86,6 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class FunctionCodegen {
|
||||
private static final String JAVA_LANG_DEPRECATED = Type.getType(Deprecated.class).getDescriptor();
|
||||
|
||||
public final GenerationState state;
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
private final BindingContext bindingContext;
|
||||
@@ -194,10 +193,6 @@ public class FunctionCodegen {
|
||||
if (origin.getOriginKind() == JvmDeclarationOriginKind.SAM_DELEGATION) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
boolean isCompatibilityStubInDefaultImpls = isCompatibilityStubInDefaultImpls(functionDescriptor, methodContext, state.getJvmDefaultMode());
|
||||
if (isCompatibilityStubInDefaultImpls) {
|
||||
flags |= ACC_DEPRECATED;
|
||||
}
|
||||
|
||||
if (functionDescriptor.isExternal() && owner instanceof MultifileClassFacadeContext) {
|
||||
// Native methods are only defined in facades and do not need package part implementations
|
||||
@@ -206,13 +201,12 @@ public class FunctionCodegen {
|
||||
|
||||
MethodVisitor mv =
|
||||
strategy.wrapMethodVisitor(
|
||||
newMethod(
|
||||
origin,
|
||||
flags,
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
strategy.skipGenericSignature() ? null : jvmSignature.getGenericsSignature(),
|
||||
getThrownExceptions(functionDescriptor, typeMapper)
|
||||
newMethod(origin,
|
||||
flags,
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
strategy.skipGenericSignature() ? null : jvmSignature.getGenericsSignature(),
|
||||
getThrownExceptions(functionDescriptor, typeMapper)
|
||||
),
|
||||
flags, asmMethod.getName(),
|
||||
asmMethod.getDescriptor()
|
||||
@@ -220,14 +214,8 @@ public class FunctionCodegen {
|
||||
|
||||
recordMethodForFunctionIfAppropriate(functionDescriptor, asmMethod);
|
||||
|
||||
boolean skipNullabilityAnnotations =
|
||||
(flags & ACC_PRIVATE) != 0 || (flags & ACC_SYNTHETIC) != 0 ||
|
||||
InlineClassDescriptorResolver.isSpecializedEqualsMethod(functionDescriptor);
|
||||
generateMethodAnnotationsIfRequired(
|
||||
functionDescriptor, asmMethod, jvmSignature, mv,
|
||||
isCompatibilityStubInDefaultImpls ? Collections.singletonList(JAVA_LANG_DEPRECATED) : Collections.emptyList(),
|
||||
skipNullabilityAnnotations
|
||||
);
|
||||
generateMethodAnnotationsIfRequired(functionDescriptor, asmMethod, jvmSignature, mv);
|
||||
|
||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||
|
||||
if (contextKind != OwnerKind.ERASED_INLINE_CLASS) {
|
||||
@@ -288,9 +276,7 @@ public class FunctionCodegen {
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull JvmMethodGenericSignature jvmSignature,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull List<String> additionalVisibleAnnotations,
|
||||
boolean skipNullabilityAnnotations
|
||||
@NotNull MethodVisitor mv
|
||||
) {
|
||||
FunctionDescriptor annotationsOwner;
|
||||
if (shouldHideConstructorDueToInlineClassTypeValueParameters(functionDescriptor)) {
|
||||
@@ -305,14 +291,10 @@ public class FunctionCodegen {
|
||||
annotationsOwner = functionDescriptor;
|
||||
}
|
||||
|
||||
AnnotationCodegen.forMethod(mv, memberCodegen, state, skipNullabilityAnnotations)
|
||||
.genAnnotations(annotationsOwner, asmMethod.getReturnType(), functionDescriptor.getReturnType(), null, additionalVisibleAnnotations);
|
||||
AnnotationCodegen.forMethod(mv, memberCodegen, state)
|
||||
.genAnnotations(annotationsOwner, asmMethod.getReturnType(), functionDescriptor.getReturnType());
|
||||
|
||||
generateParameterAnnotations(
|
||||
annotationsOwner, mv, jvmSignature,
|
||||
annotationsOwner.getValueParameters(),
|
||||
memberCodegen, state, skipNullabilityAnnotations
|
||||
);
|
||||
generateParameterAnnotations(annotationsOwner, mv, jvmSignature, memberCodegen, state);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -506,14 +488,25 @@ public class FunctionCodegen {
|
||||
return descriptor != null && !InlineUtil.isInlineOrContainingInline(descriptor);
|
||||
}
|
||||
|
||||
public static void generateParameterAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
generateParameterAnnotations(
|
||||
functionDescriptor, mv, jvmSignature, functionDescriptor.getValueParameters(), innerClassConsumer, state
|
||||
);
|
||||
}
|
||||
|
||||
public static void generateParameterAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@NotNull MemberCodegen<?> memberCodegen,
|
||||
@NotNull GenerationState state,
|
||||
boolean skipNullabilityAnnotations
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
if (isAccessor(functionDescriptor)) return;
|
||||
|
||||
@@ -523,7 +516,6 @@ public class FunctionCodegen {
|
||||
|
||||
Asm7UtilKt.visitAnnotableParameterCount(mv, kotlinParameterTypes.size() - syntheticParameterCount);
|
||||
|
||||
boolean isDefaultImpl = OwnerKind.DEFAULT_IMPLS == memberCodegen.context.getContextKind();
|
||||
for (int i = 0; i < kotlinParameterTypes.size(); i++) {
|
||||
JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
|
||||
JvmMethodParameterKind kind = parameterSignature.getKind();
|
||||
@@ -536,18 +528,13 @@ public class FunctionCodegen {
|
||||
? iterator.next()
|
||||
: kind == JvmMethodParameterKind.RECEIVER
|
||||
? JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter()
|
||||
: kind == JvmMethodParameterKind.THIS && isDefaultImpl
|
||||
? JvmCodegenUtil.getDirectMember(functionDescriptor).getDispatchReceiverParameter()
|
||||
: null;
|
||||
: null;
|
||||
|
||||
if (annotated != null) {
|
||||
//noinspection ConstantConditions
|
||||
int parameterIndex = i - syntheticParameterCount;
|
||||
AnnotationCodegen
|
||||
.forParameter(parameterIndex, mv, memberCodegen, state, skipNullabilityAnnotations)
|
||||
.genAnnotations(
|
||||
annotated, parameterSignature.getAsmType(), annotated.getReturnType(), functionDescriptor,
|
||||
Collections.emptyList()
|
||||
);
|
||||
AnnotationCodegen.forParameter(parameterIndex, mv, innerClassConsumer, state)
|
||||
.genAnnotations(annotated, parameterSignature.getAsmType(), annotated.getReturnType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,7 +598,7 @@ public class FunctionCodegen {
|
||||
else if (isCompatibilityStubInDefaultImpls(functionDescriptor, context, jvmDefaultMode)) {
|
||||
FunctionDescriptor compatibility = ((DefaultImplsClassContext) context.getParentContext()).getInterfaceContext()
|
||||
.getAccessorForJvmDefaultCompatibility(functionDescriptor);
|
||||
int flags = DescriptorAsmUtil.getMethodAsmFlags(functionDescriptor, OwnerKind.DEFAULT_IMPLS, context.getState());
|
||||
int flags = AsmUtil.getMethodAsmFlags(functionDescriptor, OwnerKind.DEFAULT_IMPLS, context.getState());
|
||||
assert (flags & Opcodes.ACC_ABSTRACT) == 0 : "Interface method with body should be non-abstract" + functionDescriptor;
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(compatibility, false);
|
||||
|
||||
@@ -619,7 +606,7 @@ public class FunctionCodegen {
|
||||
true, mv,
|
||||
method.getAsmMethod(),
|
||||
method.getOwner().getInternalName(),
|
||||
true, signature.getReturnType());
|
||||
true);
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else {
|
||||
@@ -723,8 +710,10 @@ public class FunctionCodegen {
|
||||
@NotNull JvmDefaultMode jvmDefaultMode
|
||||
) {
|
||||
return OwnerKind.DEFAULT_IMPLS == context.getContextKind() &&
|
||||
jvmDefaultMode.isCompatibility() &&
|
||||
JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(functionDescriptor, jvmDefaultMode);
|
||||
JvmAnnotationUtilKt
|
||||
.isCompiledToJvmDefault(DescriptorUtils.unwrapFakeOverrideToAnyDeclaration(functionDescriptor),
|
||||
jvmDefaultMode) &&
|
||||
jvmDefaultMode.isCompatibility();
|
||||
}
|
||||
|
||||
private static void generateLocalVariableTable(
|
||||
@@ -763,7 +752,7 @@ public class FunctionCodegen {
|
||||
generateLocalVariablesForParameters(mv,
|
||||
jvmMethodSignature, functionDescriptor,
|
||||
thisType, methodBegin, methodEnd, functionDescriptor.getValueParameters(),
|
||||
DescriptorAsmUtil.isStaticMethod(ownerKind, functionDescriptor), state
|
||||
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), state
|
||||
);
|
||||
}
|
||||
|
||||
@@ -811,7 +800,7 @@ public class FunctionCodegen {
|
||||
: nameForDestructuredParameter;
|
||||
break;
|
||||
case RECEIVER:
|
||||
parameterName = DescriptorAsmUtil.getNameForReceiverParameter(
|
||||
parameterName = AsmUtil.getNameForReceiverParameter(
|
||||
functionDescriptor, typeMapper.getBindingContext(), state.getLanguageVersionSettings());
|
||||
break;
|
||||
case OUTER:
|
||||
@@ -860,8 +849,7 @@ public class FunctionCodegen {
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull String classToDelegateTo,
|
||||
int opcode,
|
||||
boolean isInterface,
|
||||
@NotNull Type returnType
|
||||
boolean isInterface
|
||||
) {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
Type[] argTypes = asmMethod.getArgumentTypes();
|
||||
@@ -883,8 +871,7 @@ public class FunctionCodegen {
|
||||
paramIndex += argType.getSize();
|
||||
}
|
||||
iv.visitMethodInsn(opcode, classToDelegateTo, asmMethod.getName(), asmMethod.getDescriptor(), isInterface);
|
||||
StackValue.onStack(asmMethod.getReturnType()).coerceTo(returnType, null, iv);
|
||||
iv.areturn(returnType);
|
||||
iv.areturn(asmMethod.getReturnType());
|
||||
}
|
||||
|
||||
private static void generateDelegateToStaticErasedVersion(
|
||||
@@ -923,19 +910,7 @@ public class FunctionCodegen {
|
||||
@NotNull String classToDelegateTo,
|
||||
boolean isInterfaceMethodCall
|
||||
) {
|
||||
generateDelegateToStaticMethodBody(isStatic, mv, asmMethod, classToDelegateTo, isInterfaceMethodCall, asmMethod.getReturnType());
|
||||
}
|
||||
|
||||
|
||||
private static void generateDelegateToStaticMethodBody(
|
||||
boolean isStatic,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull String classToDelegateTo,
|
||||
boolean isInterfaceMethodCall,
|
||||
@NotNull Type returnType
|
||||
) {
|
||||
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall, returnType);
|
||||
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall);
|
||||
}
|
||||
|
||||
private static boolean needIndexForVar(JvmMethodParameterKind kind) {
|
||||
@@ -1062,7 +1037,7 @@ public class FunctionCodegen {
|
||||
// or all return types are supertypes of inline class (and can't be inline classes).
|
||||
|
||||
for (DescriptorBasedFunctionHandleForJvm handle : bridge.getOriginalFunctions()) {
|
||||
return handle.getDescriptor().getReturnType();
|
||||
return state.getTypeMapper().getReturnValueType(handle.getDescriptor());
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode().mightBeIncorrectCode) {
|
||||
@@ -1154,7 +1129,7 @@ public class FunctionCodegen {
|
||||
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
|
||||
// $default methods are never protected to be accessible from subclass nested classes
|
||||
int visibilityFlag =
|
||||
DescriptorVisibilities.isPrivate(functionDescriptor.getVisibility()) || isInlineOnlyPrivateInBytecode(functionDescriptor)
|
||||
Visibilities.isPrivate(functionDescriptor.getVisibility()) || isInlineOnlyPrivateInBytecode(functionDescriptor)
|
||||
? AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
||||
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor &&
|
||||
@@ -1413,7 +1388,7 @@ public class FunctionCodegen {
|
||||
if (isVarargInvoke) {
|
||||
assert argTypes.length == 1 && argTypes[0].equals(AsmUtil.getArrayType(OBJECT_TYPE)) :
|
||||
"Vararg invoke must have one parameter of type [Ljava/lang/Object;: " + bridge;
|
||||
DescriptorAsmUtil.generateVarargInvokeArityAssert(iv, originalArgTypes.length);
|
||||
AsmUtil.generateVarargInvokeArityAssert(iv, originalArgTypes.length);
|
||||
}
|
||||
else {
|
||||
assert argTypes.length == originalArgTypes.length :
|
||||
@@ -1459,7 +1434,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
KotlinType returnValueType = descriptor.getReturnType();
|
||||
KotlinType returnValueType = state.getTypeMapper().getReturnValueType(descriptor);
|
||||
StackValue.coerce(delegateTo.getReturnType(), returnValueType, bridge.getReturnType(), bridgeReturnType, iv);
|
||||
iv.areturn(bridge.getReturnType());
|
||||
|
||||
@@ -1618,7 +1593,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
//noinspection ConstantConditions
|
||||
StackValue stackValue = DescriptorAsmUtil.genNotNullAssertions(
|
||||
StackValue stackValue = AsmUtil.genNotNullAssertions(
|
||||
state,
|
||||
StackValue.onStack(delegateToMethod.getReturnType(), delegatedTo.getReturnType()),
|
||||
RuntimeAssertionInfo.create(
|
||||
@@ -1679,16 +1654,13 @@ public class FunctionCodegen {
|
||||
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
|
||||
containingDeclaration;
|
||||
|
||||
// Fake overrides in interfaces should be expanded to implementation to make proper default check
|
||||
if (JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(memberDescriptor, mode)) {
|
||||
if (JvmAnnotationUtilKt.isCompiledToJvmDefault(memberDescriptor, mode)) {
|
||||
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
|
||||
(kind == OwnerKind.DEFAULT_IMPLS &&
|
||||
(isSynthetic || //TODO: move synthetic method generation into interface
|
||||
(mode.isCompatibility() && !JvmAnnotationUtilKt.hasJvmDefaultNoCompatibilityAnnotation(containingDeclaration))));
|
||||
(kind == OwnerKind.DEFAULT_IMPLS && (isSynthetic || mode.isCompatibility()));
|
||||
} else {
|
||||
switch (kind) {
|
||||
case DEFAULT_IMPLS: return true;
|
||||
case IMPLEMENTATION: return !DescriptorVisibilities.isPrivate(memberDescriptor.getVisibility()) && !isDefault && !isSynthetic;
|
||||
case IMPLEMENTATION: return !Visibilities.isPrivate(memberDescriptor.getVisibility()) && !isDefault && !isSynthetic;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.FunctionsFromAnyGenerator;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
@@ -30,12 +30,10 @@ import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -48,7 +46,6 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
private final GenerationState generationState;
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
private final JvmKotlinType underlyingType;
|
||||
private final boolean isInErasedInlineClass;
|
||||
|
||||
public FunctionsFromAnyGeneratorImpl(
|
||||
@NotNull KtClassOrObject declaration,
|
||||
@@ -70,28 +67,23 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
typeMapper.mapType(descriptor),
|
||||
InlineClassesUtilsKt.substitutedUnderlyingType(descriptor.getDefaultType())
|
||||
);
|
||||
this.isInErasedInlineClass = fieldOwnerContext.getContextKind() == OwnerKind.ERASED_INLINE_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateToStringMethod(
|
||||
@NotNull FunctionDescriptor function,
|
||||
@NotNull List<? extends PropertyDescriptor> properties
|
||||
@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties
|
||||
) {
|
||||
MethodContext context = fieldOwnerContext.intoFunction(function);
|
||||
JvmDeclarationOrigin methodOrigin = JvmDeclarationOriginKt.OtherOrigin(function);
|
||||
String toStringMethodName = mapFunctionName(function);
|
||||
String toStringMethodDesc = getToStringDesc();
|
||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), toStringMethodName, toStringMethodDesc, null, null);
|
||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), toStringMethodName, getToStringDesc(), null, null);
|
||||
|
||||
if (!isInErasedInlineClass && classDescriptor.isInline()) {
|
||||
if (fieldOwnerContext.getContextKind() != OwnerKind.ERASED_INLINE_CLASS && classDescriptor.isInline()) {
|
||||
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isInErasedInlineClass) {
|
||||
visitEndForAnnotationVisitor(mv.visitAnnotation(Type.getDescriptor(NotNull.class), false));
|
||||
}
|
||||
visitEndForAnnotationVisitor(mv.visitAnnotation(Type.getDescriptor(NotNull.class), false));
|
||||
|
||||
if (!generationState.getClassBuilderMode().generateBodies) {
|
||||
FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration());
|
||||
@@ -101,19 +93,18 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
mv.visitCode();
|
||||
genStringBuilderConstructor(iv);
|
||||
|
||||
StringConcatGenerator generator = StringConcatGenerator.Companion.create(generationState, iv);
|
||||
generator.genStringBuilderConstructorIfNeded();
|
||||
boolean first = true;
|
||||
|
||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||
if (first) {
|
||||
generator.addStringConstant(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
||||
iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
generator.addStringConstant(", " + propertyDescriptor.getName().asString() + "=");
|
||||
iv.aconst(", " + propertyDescriptor.getName().asString() + "=");
|
||||
}
|
||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE, null);
|
||||
|
||||
JvmKotlinType type = genOrLoadOnStack(iv, context, propertyDescriptor, 0);
|
||||
Type asmType = type.getType();
|
||||
@@ -132,23 +123,16 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType();
|
||||
}
|
||||
}
|
||||
genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper, StackValue.onStack(asmType));
|
||||
genInvokeAppendMethod(iv, asmType, kotlinType, typeMapper);
|
||||
}
|
||||
|
||||
generator.addStringConstant(")");
|
||||
iv.aconst(")");
|
||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE, null);
|
||||
|
||||
generator.genToString();
|
||||
iv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
iv.areturn(JAVA_STRING_TYPE);
|
||||
|
||||
FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration());
|
||||
|
||||
recordMethodForFunctionIfRequired(function, toStringMethodName, toStringMethodDesc);
|
||||
}
|
||||
|
||||
private void recordMethodForFunctionIfRequired(@NotNull FunctionDescriptor function, @NotNull String name, @NotNull String desc) {
|
||||
if (isInErasedInlineClass) {
|
||||
v.getSerializationBindings().put(JvmSerializationBindings.METHOD_FOR_FUNCTION, function, new Method(name, desc));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,10 +142,9 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
MethodContext context = fieldOwnerContext.intoFunction(function);
|
||||
JvmDeclarationOrigin methodOrigin = JvmDeclarationOriginKt.OtherOrigin(function);
|
||||
String hashCodeMethodName = mapFunctionName(function);
|
||||
String hashCodeMethodDesc = getHashCodeDesc();
|
||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), hashCodeMethodName, hashCodeMethodDesc, null, null);
|
||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), hashCodeMethodName, getHashCodeDesc(), null, null);
|
||||
|
||||
if (!isInErasedInlineClass && classDescriptor.isInline()) {
|
||||
if (fieldOwnerContext.getContextKind() != OwnerKind.ERASED_INLINE_CLASS && classDescriptor.isInline()) {
|
||||
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
||||
return;
|
||||
}
|
||||
@@ -215,8 +198,6 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
mv.visitInsn(IRETURN);
|
||||
|
||||
FunctionCodegen.endVisit(mv, hashCodeMethodName, getDeclaration());
|
||||
|
||||
recordMethodForFunctionIfRequired(function, hashCodeMethodName, hashCodeMethodDesc);
|
||||
}
|
||||
|
||||
private String mapFunctionName(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
@@ -230,17 +211,17 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
MethodContext context = fieldOwnerContext.intoFunction(function);
|
||||
JvmDeclarationOrigin methodOrigin = JvmDeclarationOriginKt.OtherOrigin(function);
|
||||
String equalsMethodName = mapFunctionName(function);
|
||||
String equalsMethodDesc = getEqualsDesc();
|
||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), equalsMethodName, equalsMethodDesc, null, null);
|
||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), equalsMethodName, getEqualsDesc(), null, null);
|
||||
|
||||
if (!isInErasedInlineClass && classDescriptor.isInline()) {
|
||||
boolean isErasedInlineClassKind = fieldOwnerContext.getContextKind() == OwnerKind.ERASED_INLINE_CLASS;
|
||||
if (!isErasedInlineClassKind && classDescriptor.isInline()) {
|
||||
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isInErasedInlineClass) {
|
||||
visitEndForAnnotationVisitor(mv.visitParameterAnnotation(0, Type.getDescriptor(Nullable.class), false));
|
||||
}
|
||||
visitEndForAnnotationVisitor(
|
||||
mv.visitParameterAnnotation(isErasedInlineClassKind ? 1 : 0, Type.getDescriptor(Nullable.class), false)
|
||||
);
|
||||
|
||||
if (!generationState.getClassBuilderMode().generateBodies) {
|
||||
FunctionCodegen.endVisit(mv, equalsMethodName, getDeclaration());
|
||||
@@ -282,8 +263,6 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
iv.areturn(Type.INT_TYPE);
|
||||
|
||||
FunctionCodegen.endVisit(mv, equalsMethodName, getDeclaration());
|
||||
|
||||
recordMethodForFunctionIfRequired(function, equalsMethodName, equalsMethodDesc);
|
||||
}
|
||||
|
||||
private static void visitEndForAnnotationVisitor(@Nullable AnnotationVisitor annotation) {
|
||||
|
||||
@@ -62,18 +62,13 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.StandardNames.ENUM_VALUES;
|
||||
import static org.jetbrains.kotlin.builtins.StandardNames.ENUM_VALUE_OF;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isGenericToArray;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isNonGenericToArray;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.getDelegatedLocalVariableMetadata;
|
||||
import static org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil.*;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAbi.HIDDEN_INSTANCE_FIELD;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAbi.INSTANCE_FIELD;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAbi.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_SET;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull;
|
||||
@@ -125,8 +120,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
descriptor, extension,
|
||||
parentCodegen instanceof ImplementationBodyCodegen
|
||||
? ((ImplementationBodyCodegen) parentCodegen).serializer
|
||||
: DescriptorSerializer.createTopLevel(extension),
|
||||
state.getProject()
|
||||
: DescriptorSerializer.createTopLevel(extension)
|
||||
);
|
||||
|
||||
this.constructorCodegen = new ConstructorCodegen(
|
||||
@@ -777,12 +771,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.Field field = StackValue.createSingletonViaInstance(descriptor, typeMapper, INSTANCE_FIELD);
|
||||
FieldVisitor fv = v.newField(
|
||||
JvmDeclarationOriginKt.OtherOriginFromPure(myClass),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
|
||||
field.name, field.type.getDescriptor(), null, null
|
||||
);
|
||||
AnnotationCodegen.forField(fv, this, state).visitAnnotation(Type.getDescriptor(NotNull.class), false).visitEnd();
|
||||
v.newField(JvmDeclarationOriginKt.OtherOriginFromPure(myClass),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
|
||||
field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -820,17 +812,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
if (properVisibilityForCompanionObjectInstanceField &&
|
||||
JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic(companionObjectDescriptor) &&
|
||||
DescriptorVisibilities.isPrivate(companionObjectDescriptor.getVisibility())) {
|
||||
Visibilities.isPrivate(companionObjectDescriptor.getVisibility())) {
|
||||
fieldAccessFlags |= ACC_SYNTHETIC;
|
||||
}
|
||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||
FieldVisitor fv = v.newField(
|
||||
JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
|
||||
fieldAccessFlags, field.name, field.type.getDescriptor(), null, null
|
||||
);
|
||||
AnnotationCodegen.forField(fv, this, state).visitAnnotation(Type.getDescriptor(NotNull.class), false).visitEnd();
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
|
||||
fieldAccessFlags, field.name, field.type.getDescriptor(), null, null);
|
||||
if (fieldShouldBeDeprecated) {
|
||||
AnnotationCodegen.forField(fv, this, state).visitAnnotation(Type.getDescriptor(Deprecated.class), true).visitEnd();
|
||||
AnnotationCodegen.forField(fv, this, state).visitAnnotation("Ljava/lang/Deprecated;", true).visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.util.findImplementationFromInterface
|
||||
import org.jetbrains.kotlin.backend.common.bridges.findImplementationFromInterface
|
||||
import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.JvmMethodExceptionTypes
|
||||
@@ -28,7 +29,6 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.util.firstSuperMethodFromKotlin
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
|
||||
@@ -65,7 +65,7 @@ class InterfaceImplBodyCodegen(
|
||||
if (memberDescriptor !is CallableMemberDescriptor) continue
|
||||
|
||||
if (memberDescriptor.kind.isReal) continue
|
||||
if (memberDescriptor.visibility == DescriptorVisibilities.INVISIBLE_FAKE) continue
|
||||
if (memberDescriptor.visibility == Visibilities.INVISIBLE_FAKE) continue
|
||||
if (memberDescriptor.modality == Modality.ABSTRACT) continue
|
||||
|
||||
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMapper
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
@@ -42,7 +42,7 @@ class JvmBackendClassResolverForModuleWithDependencies(
|
||||
|
||||
val platformClass = moduleDescriptor.findClassAcrossModuleDependencies(type.classId) ?: return emptyList()
|
||||
|
||||
return JavaToKotlinClassMapper.mapPlatformClass(platformClass) + platformClass
|
||||
return JavaToKotlinClassMap.mapPlatformClass(platformClass) + platformClass
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,4 +54,4 @@ val Type.classId: ClassId
|
||||
val classRelativeNameWithDollars = if (lastDotIndex >= 0) className.substring(lastDotIndex + 1) else className
|
||||
val classFQN = FqName(classRelativeNameWithDollars.replace('$', '.'))
|
||||
return ClassId(packageFQN, classFQN, false)
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyD
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation
|
||||
import org.jetbrains.kotlin.util.findImplementationFromInterface
|
||||
import org.jetbrains.kotlin.util.findInterfaceImplementation
|
||||
|
||||
class DescriptorBasedFunctionHandleForJvm(
|
||||
descriptor: FunctionDescriptor,
|
||||
|
||||
@@ -12,8 +12,6 @@ import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.builtins.StandardNames;
|
||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity;
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
@@ -29,7 +27,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
|
||||
@@ -108,7 +106,7 @@ public class JvmCodegenUtil {
|
||||
boolean isDelegate = descriptor.getKind() == CallableMemberDescriptor.Kind.DELEGATION;
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration().getOriginal();
|
||||
if (DescriptorsJvmAbiUtil.isPropertyWithBackingFieldInOuterClass(descriptor)) {
|
||||
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(descriptor)) {
|
||||
// For property with backed field, check if the access is done in the same class containing the backed field and
|
||||
// not the class that declared the field.
|
||||
containingDeclaration = containingDeclaration.getContainingDeclaration();
|
||||
@@ -221,7 +219,7 @@ public class JvmCodegenUtil {
|
||||
if (DescriptorPsiUtilsKt.hasBody(accessor)) return false;
|
||||
|
||||
// If the accessor is private or final, it can't be overridden in the subclass and thus we can use direct access
|
||||
return DescriptorVisibilities.isPrivate(accessor.getVisibility()) || accessor.getModality() == FINAL;
|
||||
return Visibilities.isPrivate(accessor.getVisibility()) || accessor.getModality() == FINAL;
|
||||
}
|
||||
|
||||
public static boolean isDebuggerContext(@NotNull CodegenContext context) {
|
||||
@@ -340,12 +338,12 @@ public class JvmCodegenUtil {
|
||||
public static boolean isCompanionObjectInInterfaceNotIntrinsic(@NotNull DeclarationDescriptor companionObject) {
|
||||
return isCompanionObject(companionObject) &&
|
||||
isJvmInterface(companionObject.getContainingDeclaration()) &&
|
||||
!DescriptorsJvmAbiUtil.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||
!JvmAbi.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||
}
|
||||
|
||||
public static boolean isNonIntrinsicPrivateCompanionObjectInInterface(@NotNull DeclarationDescriptorWithVisibility companionObject) {
|
||||
return isCompanionObjectInInterfaceNotIntrinsic(companionObject) &&
|
||||
DescriptorVisibilities.isPrivate(companionObject.getVisibility());
|
||||
Visibilities.isPrivate(companionObject.getVisibility());
|
||||
}
|
||||
|
||||
public static boolean isDeclarationOfBigArityFunctionInvoke(@Nullable DeclarationDescriptor descriptor) {
|
||||
@@ -354,7 +352,7 @@ public class JvmCodegenUtil {
|
||||
|
||||
public static boolean isDeclarationOfBigArityCreateCoroutineMethod(@Nullable DeclarationDescriptor descriptor) {
|
||||
return descriptor instanceof SimpleFunctionDescriptor && descriptor.getName().asString().equals(SUSPEND_FUNCTION_CREATE_METHOD_NAME) &&
|
||||
((SimpleFunctionDescriptor) descriptor).getValueParameters().size() >= BuiltInFunctionArity.BIG_ARITY - 1 &&
|
||||
((SimpleFunctionDescriptor) descriptor).getValueParameters().size() >= FunctionInvokeDescriptor.BIG_ARITY - 1 &&
|
||||
descriptor.getContainingDeclaration() instanceof AnonymousFunctionDescriptor && ((AnonymousFunctionDescriptor) descriptor.getContainingDeclaration()).isSuspend();
|
||||
}
|
||||
|
||||
@@ -406,7 +404,7 @@ public class JvmCodegenUtil {
|
||||
// The Result class is the only inline class in the standard library without special rules for equality.
|
||||
// We only call Result.equals-impl0 if we are compiling for Kotlin 1.4 or later. Otherwise, the code
|
||||
// might well be running against an older version of the standard library.
|
||||
if (DescriptorUtils.getFqNameSafe(classDescriptor).equals(StandardNames.RESULT_FQ_NAME)) {
|
||||
if (DescriptorUtils.getFqNameSafe(classDescriptor).equals(DescriptorUtils.RESULT_FQ_NAME)) {
|
||||
return state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_4) >= 0;
|
||||
} else {
|
||||
return ((DeserializedClassDescriptor) descriptor).getMetadataVersion().isAtLeast(1, 1, 16);
|
||||
|
||||
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.resolve.calls.checkers.isRestrictsSuspensionReceiver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
|
||||
|
||||
class JvmRuntimeTypes(
|
||||
module: ModuleDescriptor,
|
||||
@@ -86,7 +84,7 @@ class JvmRuntimeTypes(
|
||||
packageFragment, classKind, false, false, Name.identifier(name), SourceElement.NO_SOURCE, LockBasedStorageManager.NO_LOCKS
|
||||
).apply {
|
||||
modality = Modality.FINAL
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
visibility = Visibilities.PUBLIC
|
||||
setTypeParameterDescriptors(emptyList())
|
||||
createTypeConstructor()
|
||||
}
|
||||
@@ -98,14 +96,6 @@ class JvmRuntimeTypes(
|
||||
else
|
||||
descriptor
|
||||
|
||||
if (actualFunctionDescriptor.returnType == null)
|
||||
throw KotlinExceptionWithAttachments(
|
||||
"Return type for function description is null. Super type cannot be calculated." +
|
||||
"initDesc=${descriptor}, actDesc=${actualFunctionDescriptor}, isReleaseCoroutines=${
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
}"
|
||||
)
|
||||
|
||||
val functionType = createFunctionType(
|
||||
descriptor.builtIns,
|
||||
Annotations.EMPTY,
|
||||
@@ -162,7 +152,7 @@ class JvmRuntimeTypes(
|
||||
referencedFunction.isSuspend || isSuspendConversion
|
||||
)
|
||||
|
||||
val suspendFunctionType = if (referencedFunction.isSuspend || isSuspendConversion) suspendFunctionInterface?.defaultType else null
|
||||
val suspendFunctionType = if (referencedFunction.isSuspend) suspendFunctionInterface?.defaultType else null
|
||||
val superClass = when {
|
||||
generateOptimizedCallableReferenceSuperClasses -> when {
|
||||
isAdaptedCallableReference || isSuspendConversion -> adaptedFunctionReference
|
||||
|
||||
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotatedImpl;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.name.SpecialNames;
|
||||
@@ -57,8 +56,8 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlags;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.calculateInnerClassAccessFlags;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getInlineName;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
@@ -258,7 +257,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
@NotNull Method syntheticMethod,
|
||||
@NotNull Annotations annotations
|
||||
) {
|
||||
int flags = ACC_DEPRECATED | ACC_STATIC | ACC_SYNTHETIC | DescriptorAsmUtil.getVisibilityAccessFlag(descriptor);
|
||||
int flags = ACC_DEPRECATED | ACC_STATIC | ACC_SYNTHETIC | AsmUtil.getVisibilityAccessFlag(descriptor);
|
||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), flags, syntheticMethod.getName(),
|
||||
syntheticMethod.getDescriptor(), null, null);
|
||||
AnnotationCodegen.forMethod(mv, this, state).genAnnotations(new AnnotatedImpl(annotations), Type.VOID_TYPE, null);
|
||||
@@ -469,7 +468,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
Name.special("<clinit>"), SYNTHESIZED, KotlinSourceElementKt.toSourceElement(element));
|
||||
clInit.initialize(null, null, Collections.emptyList(), Collections.emptyList(),
|
||||
DescriptorUtilsKt.getModule(descriptor).getBuiltIns().getUnitType(),
|
||||
Modality.FINAL, DescriptorVisibilities.PRIVATE);
|
||||
Modality.FINAL, Visibilities.PRIVATE);
|
||||
return clInit;
|
||||
}
|
||||
|
||||
@@ -727,7 +726,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public SourceMapper getOrCreateSourceMapper() {
|
||||
if (sourceMapper == null) {
|
||||
// note: this is used in InlineCodegen and the element is always physical (KtElement) there
|
||||
sourceMapper = new SourceMapper(SourceInfo.Companion.createFromPsi((KtElement)element, getClassName()));
|
||||
sourceMapper = new SourceMapper(SourceInfo.Companion.createInfo((KtElement)element, getClassName()));
|
||||
}
|
||||
return sourceMapper;
|
||||
}
|
||||
@@ -878,11 +877,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
AccessorKind fieldAccessorKind = accessor instanceof AccessorForPropertyBackingField
|
||||
? accessor.getAccessorKind() : null;
|
||||
boolean syntheticBackingField = fieldAccessorKind == AccessorKind.FIELD_FROM_LOCAL;
|
||||
boolean forceFieldForCompanionProperty = DescriptorsJvmAbiUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
boolean forceFieldForCompanionProperty = JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
!isCompanionObject(accessor.getContainingDeclaration());
|
||||
boolean forceField = forceFieldForCompanionProperty ||
|
||||
syntheticBackingField ||
|
||||
original.getVisibility() == JavaDescriptorVisibilities.PROTECTED_STATIC_VISIBILITY;
|
||||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
|
||||
StackValue property = codegen.intermediateValueForProperty(
|
||||
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(),
|
||||
forceFieldForCompanionProperty, StackValue.none(), null,
|
||||
@@ -925,8 +924,6 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
}
|
||||
|
||||
if (accessor.isVar() && accessor.isWithSyntheticSetterAccessor()) {
|
||||
if (isProhibitedAccessorToPrivatePropertySetter(original)) return;
|
||||
|
||||
PropertySetterDescriptor setter = accessor.getSetter();
|
||||
assert setter != null;
|
||||
|
||||
@@ -939,20 +936,6 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isProhibitedAccessorToPrivatePropertySetter(PropertyDescriptor original) {
|
||||
// Property setter might be less visible than the property itself.
|
||||
// We can generate accessor for a private setter only if we are in the same class
|
||||
// or in a class for the containing companion object (see KT-22465).
|
||||
// NB we don't allow private or protected interface members in Kotlin (so far),
|
||||
// so a property that might require an accessor can't be declared in an interface.
|
||||
PropertyDescriptor overriddenProperty = DescriptorUtils.unwrapFakeOverride(original);
|
||||
PropertySetterDescriptor overriddenSetter = overriddenProperty.getSetter();
|
||||
if (overriddenSetter == null || !DescriptorVisibilities.isPrivate(overriddenSetter.getVisibility())) return false;
|
||||
DeclarationDescriptor contextDescriptor = context.getContextDescriptor();
|
||||
return contextDescriptor != overriddenProperty.getContainingDeclaration() &&
|
||||
contextDescriptor != DescriptorUtils.getContainingClass(overriddenProperty);
|
||||
}
|
||||
|
||||
protected StackValue generateMethodCallTo(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@Nullable FunctionDescriptor accessorDescriptor,
|
||||
|
||||
@@ -224,8 +224,8 @@ class MultifileClassCodegenImpl(
|
||||
}
|
||||
|
||||
private fun shouldGenerateInFacade(descriptor: MemberDescriptor): Boolean {
|
||||
if (DescriptorVisibilities.isPrivate(descriptor.visibility)) return false
|
||||
if (DescriptorAsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false
|
||||
if (Visibilities.isPrivate(descriptor.visibility)) return false
|
||||
if (AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false
|
||||
|
||||
if (!state.classBuilderMode.generateBodies) return true
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class MultifileClassPartCodegen(
|
||||
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
||||
|
||||
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART, extraFlags) { av ->
|
||||
DescriptorAsmUtil.writeAnnotationData(av, serializer, packageProto)
|
||||
AsmUtil.writeAnnotationData(av, serializer, packageProto)
|
||||
av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, facadeClassType.internalName)
|
||||
|
||||
val kotlinPackageFqName = element.packageFqName
|
||||
|
||||
@@ -43,7 +43,7 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.writeAnnotationData;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -44,8 +43,8 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getDeprecatedAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getVisibilityForBackingField;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
|
||||
import static org.jetbrains.kotlin.codegen.FunctionCodegen.processInterfaceMethod;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
@@ -160,7 +159,7 @@ public class PropertyCodegen {
|
||||
|
||||
private void genBackingFieldAndAnnotations(@NotNull PropertyDescriptor descriptor) {
|
||||
// Fields and '$annotations' methods for non-private const properties are generated in the multi-file facade
|
||||
boolean isBackingFieldOwner = descriptor.isConst() && !DescriptorVisibilities.isPrivate(descriptor.getVisibility())
|
||||
boolean isBackingFieldOwner = descriptor.isConst() && !Visibilities.isPrivate(descriptor.getVisibility())
|
||||
? !(context instanceof MultifileClassPartContext)
|
||||
: CodegenContextUtil.isImplementationOwner(context, descriptor);
|
||||
|
||||
@@ -211,6 +210,7 @@ public class PropertyCodegen {
|
||||
if (kind == OwnerKind.DEFAULT_IMPLS && isDefaultAccessor) return false;
|
||||
|
||||
// Delegated or extension properties can only be referenced via accessors
|
||||
//noinspection deprecation
|
||||
if (descriptor.isDelegated() || descriptor.getExtensionReceiverParameter() != null) return true;
|
||||
|
||||
// Companion object properties should have accessors for non-private properties because these properties can be referenced
|
||||
@@ -218,7 +218,7 @@ public class PropertyCodegen {
|
||||
// and setter, in this case, the property can always be accessed through the accessor 'access<property name>$cp' and avoid some
|
||||
// useless indirection by using others accessors.
|
||||
if (isCompanionObject(descriptor.getContainingDeclaration())) {
|
||||
if (DescriptorVisibilities.isPrivate(descriptor.getVisibility()) && isDefaultGetterAndSetter) {
|
||||
if (Visibilities.isPrivate(descriptor.getVisibility()) && isDefaultGetterAndSetter) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -228,14 +228,14 @@ public class PropertyCodegen {
|
||||
if (isTopLevelInJvmMultifileClass(descriptor)) return true;
|
||||
|
||||
// Private class properties have accessors only in cases when those accessors are non-trivial
|
||||
if (DescriptorVisibilities.isPrivate(descriptor.getVisibility())) {
|
||||
if (Visibilities.isPrivate(descriptor.getVisibility())) {
|
||||
return !isDefaultAccessor;
|
||||
}
|
||||
|
||||
// Non-private properties with private setter should not be generated for trivial properties
|
||||
// as the class will use direct field access instead
|
||||
//noinspection ConstantConditions
|
||||
if (accessor != null && accessor.isSetter() && DescriptorVisibilities.isPrivate(descriptor.getSetter().getVisibility())) {
|
||||
if (accessor != null && accessor.isSetter() && Visibilities.isPrivate(descriptor.getSetter().getVisibility())) {
|
||||
return !isDefaultAccessor;
|
||||
}
|
||||
|
||||
@@ -254,12 +254,12 @@ public class PropertyCodegen {
|
||||
if (hasJvmFieldAnnotation(descriptor)) return false;
|
||||
if (kind == OwnerKind.ERASED_INLINE_CLASS) return false;
|
||||
|
||||
DescriptorVisibility visibility = descriptor.getVisibility();
|
||||
Visibility visibility = descriptor.getVisibility();
|
||||
if (InlineClassesUtilsKt.isInlineClass(descriptor.getContainingDeclaration())) {
|
||||
return visibility.isPublicAPI();
|
||||
}
|
||||
else {
|
||||
return !DescriptorVisibilities.isPrivate(visibility);
|
||||
return !Visibilities.isPrivate(visibility);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,8 +337,11 @@ public class PropertyCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
boolean isDelegate = descriptor.isDelegated();
|
||||
|
||||
Object defaultValue;
|
||||
if (descriptor.isDelegated()) {
|
||||
if (isDelegate) {
|
||||
defaultValue = null;
|
||||
}
|
||||
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
||||
@@ -354,7 +357,7 @@ public class PropertyCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
generateBackingField(descriptor, descriptor.isDelegated(), defaultValue, isBackingFieldOwner);
|
||||
generateBackingField(descriptor, isDelegate, defaultValue, isBackingFieldOwner);
|
||||
}
|
||||
|
||||
// Annotations on properties are stored in bytecode on an empty synthetic method. This way they're still
|
||||
@@ -408,10 +411,10 @@ public class PropertyCodegen {
|
||||
ClassBuilder builder = v;
|
||||
|
||||
FieldOwnerContext backingFieldContext = context;
|
||||
if (DescriptorAsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
modifiers |= ACC_STATIC;
|
||||
|
||||
if (DescriptorsJvmAbiUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
builder = codegen.v;
|
||||
backingFieldContext = codegen.context;
|
||||
@@ -419,7 +422,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
||||
|
||||
if (DescriptorAsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
|
||||
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
parentBodyCodegen.addCompanionObjectPropertyToCopy(propertyDescriptor, defaultValue);
|
||||
}
|
||||
@@ -435,13 +438,7 @@ public class PropertyCodegen {
|
||||
);
|
||||
|
||||
if (annotatedField != null) {
|
||||
// Don't emit nullability annotations for backing field if:
|
||||
// - backing field is synthetic;
|
||||
// - property is lateinit (since corresponding field is actually nullable).
|
||||
boolean skipNullabilityAnnotations =
|
||||
(modifiers & ACC_SYNTHETIC) != 0 ||
|
||||
propertyDescriptor.isLateInit();
|
||||
AnnotationCodegen.forField(fv, memberCodegen, state, skipNullabilityAnnotations)
|
||||
AnnotationCodegen.forField(fv, memberCodegen, state)
|
||||
.genAnnotations(annotatedField, type, propertyDescriptor.getType());
|
||||
}
|
||||
}
|
||||
@@ -512,14 +509,16 @@ public class PropertyCodegen {
|
||||
|
||||
private void generateAccessor(@Nullable KtPropertyAccessor accessor, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||
if (context instanceof MultifileClassFacadeContext &&
|
||||
(DescriptorVisibilities.isPrivate(descriptor.getVisibility()) ||
|
||||
DescriptorAsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE)) {
|
||||
(Visibilities.isPrivate(descriptor.getVisibility()) ||
|
||||
AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionGenerationStrategy strategy;
|
||||
if (accessor == null || !accessor.hasBody()) {
|
||||
if (descriptor.getCorrespondingProperty().isDelegated()) {
|
||||
@SuppressWarnings("deprecation")
|
||||
boolean isDelegated = descriptor.getCorrespondingProperty().isDelegated();
|
||||
if (isDelegated) {
|
||||
strategy = new DelegatedPropertyAccessorStrategy(state, descriptor);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -92,8 +92,8 @@ class PropertyReferenceCodegen(
|
||||
element,
|
||||
state.classFileVersion,
|
||||
ACC_FINAL or ACC_SUPER or
|
||||
DescriptorAsmUtil.getVisibilityAccessFlagForClass(classDescriptor) or
|
||||
DescriptorAsmUtil.getSyntheticAccessFlagForLambdaClass(classDescriptor),
|
||||
AsmUtil.getVisibilityAccessFlagForClass(classDescriptor) or
|
||||
AsmUtil.getSyntheticAccessFlagForLambdaClass(classDescriptor),
|
||||
asmType.internalName,
|
||||
null,
|
||||
superAsmType.internalName,
|
||||
@@ -108,7 +108,7 @@ class PropertyReferenceCodegen(
|
||||
if (JvmCodegenUtil.isConst(closure)) {
|
||||
generateConstInstance(asmType, wrapperMethod.returnType)
|
||||
} else {
|
||||
DescriptorAsmUtil.genClosureFields(closure, v, typeMapper, state.languageVersionSettings)
|
||||
AsmUtil.genClosureFields(closure, v, typeMapper, state.languageVersionSettings)
|
||||
}
|
||||
|
||||
generateConstructor()
|
||||
|
||||
@@ -46,9 +46,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.asmTypeByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.genAreEqualCall;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
@@ -108,7 +106,7 @@ public class SamWrapperCodegen {
|
||||
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getOriginalAbstractMethod().copy(
|
||||
classDescriptor,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.PUBLIC,
|
||||
Visibilities.PUBLIC,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
/*copyOverrides=*/ false
|
||||
);
|
||||
@@ -270,12 +268,12 @@ public class SamWrapperCodegen {
|
||||
if (!(descriptor instanceof CallableMemberDescriptor)) continue;
|
||||
CallableMemberDescriptor member = (CallableMemberDescriptor) descriptor;
|
||||
if (member.getModality() == Modality.ABSTRACT ||
|
||||
DescriptorVisibilities.isPrivate(member.getVisibility()) ||
|
||||
member.getVisibility() == DescriptorVisibilities.INVISIBLE_FAKE ||
|
||||
Visibilities.isPrivate(member.getVisibility()) ||
|
||||
member.getVisibility() == Visibilities.INVISIBLE_FAKE ||
|
||||
DescriptorUtils.isMethodOfAny(member)) continue;
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.INSTANCE.copyFunctions(
|
||||
member, member, classDescriptor, Modality.OPEN, DescriptorVisibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, false
|
||||
member, member, classDescriptor, Modality.OPEN, Visibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, false
|
||||
).entrySet()) {
|
||||
ClassBodyCodegen.generateDelegationToDefaultImpl(entry.getKey(), entry.getValue(), receiverType, functionCodegen, state, false);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||
import org.jetbrains.kotlin.codegen.context.ScriptContext
|
||||
@@ -70,7 +71,7 @@ class ScriptCodegen private constructor(
|
||||
val serializer = DescriptorSerializer.create(scriptDescriptor, JvmSerializerExtension(v.serializationBindings, state), null)
|
||||
val classProto = serializer.classProto(scriptDescriptor).build()
|
||||
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.CLASS, JvmAnnotationNames.METADATA_SCRIPT_FLAG) { av ->
|
||||
DescriptorAsmUtil.writeAnnotationData(av, serializer, classProto)
|
||||
writeAnnotationData(av, serializer, classProto)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,26 +21,28 @@ import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
|
||||
data class SourceInfo(
|
||||
val sourceFileName: String?,
|
||||
val pathOrCleanFQN: String,
|
||||
val linesInFile: Int
|
||||
) {
|
||||
data class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
|
||||
|
||||
companion object {
|
||||
fun createFromPsi(element: KtElement?, internalClassName: String): SourceInfo {
|
||||
fun createInfo(element: KtElement?, internalClassName: String): SourceInfo {
|
||||
assert(element != null) { "Couldn't create source mapper for null element $internalClassName" }
|
||||
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.containingFile, true)
|
||||
?: error("Couldn't extract line count in ${element.containingFile}")
|
||||
?: error("Couldn't extract line count in ${element.containingFile}")
|
||||
|
||||
//TODO hack condition for package parts cleaning
|
||||
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
|
||||
val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
|
||||
|
||||
val fileName = element.containingKtFile.name
|
||||
return SourceInfo(fileName, cleanedClassFqName, lineNumbers)
|
||||
return SourceInfo(element.containingKtFile.name, cleanedClassFqName, lineNumbers)
|
||||
}
|
||||
|
||||
fun createInfoForIr(lineNumbers: Int, internalClassName: String, containingFileName: String): SourceInfo {
|
||||
//TODO cut topLevel names
|
||||
// val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
|
||||
// val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
|
||||
|
||||
return SourceInfo(containingFileName, internalClassName, lineNumbers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
@@ -1544,7 +1543,7 @@ public abstract class StackValue {
|
||||
|
||||
//TODO: try to don't generate defaults at all in CollectionElementReceiver
|
||||
|
||||
List<ResolvedValueArgument> getterArguments = new ArrayList<>(collectionElementReceiver.valueArguments);
|
||||
List<ResolvedValueArgument> getterArguments = new ArrayList(collectionElementReceiver.valueArguments);
|
||||
List<ResolvedValueArgument> getterDefaults = CollectionsKt.takeLastWhile(getterArguments,
|
||||
argument -> argument instanceof DefaultValueArgument);
|
||||
|
||||
@@ -1762,7 +1761,7 @@ public abstract class StackValue {
|
||||
// is from a different context), the assertion will be generated on each access, see KT-28331.
|
||||
if (descriptor instanceof AccessorForPropertyBackingField) {
|
||||
PropertyDescriptor property = ((AccessorForPropertyBackingField) descriptor).getCalleeDescriptor();
|
||||
if (!skipLateinitAssertion && property.isLateInit() && DescriptorsJvmAbiUtil.isPropertyWithBackingFieldInOuterClass(property) &&
|
||||
if (!skipLateinitAssertion && property.isLateInit() && JvmAbi.isPropertyWithBackingFieldInOuterClass(property) &&
|
||||
!JvmCodegenUtil.couldUseDirectAccessToProperty(property, true, false, codegen.context, false)) {
|
||||
genNonNullAssertForLateinit(v, property.getName().asString());
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user