mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-12 15:51:07 +00:00
Compare commits
2 Commits
jspecify
...
rr/perf/no
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9704a56344 | ||
|
|
081b9d6d13 |
12
.bunch
12
.bunch
@@ -1,7 +1,7 @@
|
||||
201
|
||||
202
|
||||
203_202
|
||||
193
|
||||
as40_193
|
||||
as41
|
||||
as42_202
|
||||
201
|
||||
192
|
||||
191_192
|
||||
as35_191_192
|
||||
as36_192
|
||||
as40
|
||||
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
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -58,7 +58,5 @@ kotlin-ultimate/
|
||||
node_modules/
|
||||
.rpt2_cache/
|
||||
libraries/tools/kotlin-test-js-runner/lib/
|
||||
libraries/tools/kotlin-source-map-loader/lib/
|
||||
local.properties
|
||||
buildSrcTmp/
|
||||
distTmp/
|
||||
outTmp/
|
||||
|
||||
1
.idea/dictionaries/4u7.xml
generated
1
.idea/dictionaries/4u7.xml
generated
@@ -11,7 +11,6 @@
|
||||
<w>protobuf</w>
|
||||
<w>redirector</w>
|
||||
<w>remapper</w>
|
||||
<w>sonatype</w>
|
||||
<w>unpresent</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
||||
7
.idea/dictionaries/dmitriy_dolovov.xml
generated
7
.idea/dictionaries/dmitriy_dolovov.xml
generated
@@ -1,19 +1,12 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="dmitriy.dolovov">
|
||||
<words>
|
||||
<w>cinterop</w>
|
||||
<w>commonizable</w>
|
||||
<w>commonization</w>
|
||||
<w>commonize</w>
|
||||
<w>commonized</w>
|
||||
<w>commonizer</w>
|
||||
<w>commonizers</w>
|
||||
<w>commonizes</w>
|
||||
<w>commonizing</w>
|
||||
<w>jetbrains</w>
|
||||
<w>konan</w>
|
||||
<w>kotlinx</w>
|
||||
<w>macos</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
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>
|
||||
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -66,7 +66,7 @@
|
||||
<component name="ProjectResources">
|
||||
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="PsiViewerSettings">
|
||||
|
||||
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>
|
||||
@@ -1,22 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test: stdlib-js public kotlin api test, overwrite results" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<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="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value=":js:js.tests:cleanTest" />
|
||||
<option value=":js:js.tests:test" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<GradleScriptDebugEnabled>false</GradleScriptDebugEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
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" />
|
||||
</component>
|
||||
1734
ChangeLog.md
1734
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.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
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
|
||||
@@ -58,10 +66,10 @@ private val JDK_PATH = File("${System.getProperty("java.home")!!}/lib/rt.jar")
|
||||
private val RUNTIME_JAR = File(System.getProperty("kotlin.runtime.path") ?: "dist/kotlinc/lib/kotlin-runtime.jar")
|
||||
|
||||
private val LANGUAGE_FEATURE_SETTINGS =
|
||||
LanguageVersionSettingsImpl(
|
||||
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
|
||||
specificFeatures = mapOf(LanguageFeature.NewInference to LanguageFeature.State.ENABLED)
|
||||
)
|
||||
LanguageVersionSettingsImpl(
|
||||
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
|
||||
specificFeatures = mapOf(LanguageFeature.NewInference to LanguageFeature.State.ENABLED)
|
||||
)
|
||||
|
||||
private fun newConfiguration(useNewInference: Boolean): CompilerConfiguration {
|
||||
val configuration = CompilerConfiguration()
|
||||
@@ -73,10 +81,10 @@ private fun newConfiguration(useNewInference: Boolean): CompilerConfiguration {
|
||||
|
||||
val newInferenceState = if (useNewInference) LanguageFeature.State.ENABLED else LanguageFeature.State.DISABLED
|
||||
configuration.languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
|
||||
specificFeatures = mapOf(
|
||||
LanguageFeature.NewInference to newInferenceState
|
||||
)
|
||||
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
|
||||
specificFeatures = mapOf(
|
||||
LanguageFeature.NewInference to newInferenceState
|
||||
)
|
||||
)
|
||||
return configuration
|
||||
}
|
||||
@@ -97,19 +105,21 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
fun setUp() {
|
||||
if (isIR && !useNewInference) error("Invalid configuration")
|
||||
env = KotlinCoreEnvironment.createForTests(
|
||||
myDisposable,
|
||||
newConfiguration(useNewInference),
|
||||
EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
myDisposable,
|
||||
newConfiguration(useNewInference),
|
||||
EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
)
|
||||
|
||||
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(
|
||||
"test.kt",
|
||||
buildText(),
|
||||
env.project
|
||||
"test.kt",
|
||||
buildText(),
|
||||
env.project
|
||||
)
|
||||
}
|
||||
|
||||
@@ -124,22 +134,22 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
private fun analyzeGreenFileFrontend(bh: Blackhole) {
|
||||
val tracker = ExceptionTracker()
|
||||
val storageManager: StorageManager =
|
||||
LockBasedStorageManager.createWithExceptionHandling("benchmarks", tracker)
|
||||
LockBasedStorageManager.createWithExceptionHandling("benchmarks", tracker)
|
||||
|
||||
val context = SimpleGlobalContext(storageManager, tracker)
|
||||
val module =
|
||||
ModuleDescriptorImpl(
|
||||
Name.special("<benchmark>"), storageManager,
|
||||
JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
|
||||
)
|
||||
ModuleDescriptorImpl(
|
||||
Name.special("<benchmark>"), storageManager,
|
||||
JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
|
||||
)
|
||||
val moduleContext = context.withProject(env.project).withModule(module)
|
||||
|
||||
val result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
moduleContext.project,
|
||||
listOf(file),
|
||||
NoScopeRecordCliBindingTrace(),
|
||||
env.configuration,
|
||||
{ scope -> JvmPackagePartProvider(LANGUAGE_FEATURE_SETTINGS, scope) }
|
||||
moduleContext.project,
|
||||
listOf(file),
|
||||
NoScopeRecordCliBindingTrace(),
|
||||
env.configuration,
|
||||
{ scope -> JvmPackagePartProvider(LANGUAGE_FEATURE_SETTINGS, scope) }
|
||||
)
|
||||
|
||||
assert(result.bindingContext.diagnostics.none { it.severity == Severity.ERROR })
|
||||
@@ -149,21 +159,56 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
|
||||
private fun analyzeGreenFileIr(bh: Blackhole) {
|
||||
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
|
||||
val session = createSession(env, scope)
|
||||
val firProvider = session.firProvider as FirProviderImpl
|
||||
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
|
||||
|
||||
val totalTransformer = FirTotalResolveProcessor(session)
|
||||
val totalTransformer = FirTotalResolveTransformer()
|
||||
val firFile = builder.buildFirFile(file).also(firProvider::recordFile)
|
||||
|
||||
totalTransformer.process(listOf(firFile))
|
||||
for (transformer in totalTransformer.transformers) {
|
||||
transformer.transformFile(firFile, null)
|
||||
}
|
||||
|
||||
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(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("}")
|
||||
}
|
||||
}
|
||||
@@ -23,28 +23,28 @@ open class ManyImplicitReceiversBenchmark : AbstractSimpleFileBenchmark() {
|
||||
|
||||
override fun buildText(): String {
|
||||
return buildString {
|
||||
appendLine("inline fun <T, R> with(receiver: T, block: T.() -> R): R = block()")
|
||||
appendln("inline fun <T, R> with(receiver: T, block: T.() -> R): R = block()")
|
||||
|
||||
for (i in 1..size) {
|
||||
appendLine("interface A$i {")
|
||||
appendLine(" fun foo$i()")
|
||||
appendLine("}")
|
||||
appendLine()
|
||||
appendln("interface A$i {")
|
||||
appendln(" fun foo$i()")
|
||||
appendln("}")
|
||||
appendln()
|
||||
}
|
||||
appendLine()
|
||||
appendln()
|
||||
append("fun test(")
|
||||
append((1..size).joinToString(", ") { "a$it: A$it" })
|
||||
appendLine(" {")
|
||||
appendln(" {")
|
||||
for (i in 1..size) {
|
||||
appendLine("with(a$i) {")
|
||||
appendln("with(a$i) {")
|
||||
}
|
||||
for (i in 1..size) {
|
||||
appendLine("foo$i()")
|
||||
appendln("foo$i()")
|
||||
}
|
||||
for (i in 1..size) {
|
||||
appendLine("}")
|
||||
appendln("}")
|
||||
}
|
||||
appendLine("}")
|
||||
appendln("}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ open class PlusAssignOperatorDesugaringBenchmark : AbstractInferenceBenchmark()
|
||||
}
|
||||
|
||||
override fun buildText(): String = buildString {
|
||||
appendLine(
|
||||
appendln(
|
||||
"""
|
||||
class A {
|
||||
operator fun <T : Number> plus(other: (Int) -> T): A = this
|
||||
@@ -30,20 +30,19 @@ open class PlusAssignOperatorDesugaringBenchmark : AbstractInferenceBenchmark()
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
appendLine("fun test() {")
|
||||
appendLine("var a = A()")
|
||||
appendln("fun test() {")
|
||||
appendln("var a = A()")
|
||||
for (i in 1..size) {
|
||||
appendLine("a += {")
|
||||
appendln("a += {")
|
||||
}
|
||||
for (i in 1..size) {
|
||||
appendLine(
|
||||
appendln(
|
||||
"""
|
||||
it.inc()
|
||||
1
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
""".trimIndent())
|
||||
}
|
||||
appendLine()
|
||||
appendln()
|
||||
}
|
||||
}
|
||||
@@ -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"))
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
@@ -25,7 +25,7 @@ class MessageCollectorToOutputItemsCollectorAdapter(
|
||||
private val delegate: MessageCollector,
|
||||
private val outputCollector: OutputItemsCollector
|
||||
) : MessageCollector by delegate {
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
|
||||
// TODO: consider adding some other way of passing input -> output mapping from compiler, e.g. dedicated service
|
||||
OutputMessageUtil.parseOutputMessage(message)?.let {
|
||||
outputCollector.add(it.sourceFiles, it.outputFile)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.EnumeratorStringDescriptor
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
abstract class BasicMap<K : Comparable<K>, V>(
|
||||
internal val storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<K>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) {
|
||||
protected val storage = LazyStorage(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
fun clean() {
|
||||
storage.clean()
|
||||
}
|
||||
|
||||
fun flush(memoryCachesOnly: Boolean) {
|
||||
storage.flush(memoryCachesOnly)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
storage.close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun dump(): String {
|
||||
return with(StringBuilder()) {
|
||||
with(Printer(this)) {
|
||||
println(this@BasicMap::class.java.simpleName)
|
||||
pushIndent()
|
||||
|
||||
for (key in storage.keys.sorted()) {
|
||||
println("${dumpKey(key)} -> ${dumpValue(storage[key]!!)}")
|
||||
}
|
||||
|
||||
popIndent()
|
||||
}
|
||||
|
||||
this
|
||||
}.toString()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpKey(key: K): String
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpValue(value: V): String
|
||||
}
|
||||
|
||||
abstract class BasicStringMap<V>(
|
||||
storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<String>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : BasicMap<String, V>(storageFile, keyDescriptor, valueExternalizer) {
|
||||
constructor(
|
||||
storageFile: File,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : this(storageFile, EnumeratorStringDescriptor.INSTANCE, valueExternalizer)
|
||||
|
||||
override fun dumpKey(key: String): String = key
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
|
||||
internal open class ClassOneToManyMap(
|
||||
storageFile: File
|
||||
) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
|
||||
fun add(key: FqName, value: FqName) {
|
||||
storage.append(key.asString(), value.asString())
|
||||
}
|
||||
|
||||
operator fun get(key: FqName): Collection<FqName> =
|
||||
storage[key.asString()]?.map(::FqName) ?: setOf()
|
||||
|
||||
operator fun set(key: FqName, values: Collection<FqName>) {
|
||||
if (values.isEmpty()) {
|
||||
remove(key)
|
||||
return
|
||||
}
|
||||
|
||||
storage[key.asString()] = values.map(FqName::asString)
|
||||
}
|
||||
|
||||
fun remove(key: FqName) {
|
||||
storage.remove(key.asString())
|
||||
}
|
||||
|
||||
fun removeValues(key: FqName, removed: Set<FqName>) {
|
||||
val notRemoved = this[key].filter { it !in removed }
|
||||
this[key] = notRemoved
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubtypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
internal class SupertypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.IOUtil
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.DataOutput
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
/**
|
||||
* It's lazy in a sense that PersistentHashMap is created only on write
|
||||
*/
|
||||
class LazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<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!!
|
||||
}
|
||||
|
||||
val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
fun append(key: K, value: String) {
|
||||
append(key) { out -> IOUtil.writeUTF(out, value) }
|
||||
}
|
||||
|
||||
fun append(key: K, value: Int) {
|
||||
append(key) { out -> out.writeInt(value) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
}
|
||||
catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
}
|
||||
else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
private fun append(key: K, append: (DataOutput)->Unit) {
|
||||
getStorageOrCreateNew().appendData(key, append)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 java.io.File
|
||||
|
||||
internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(storage, LookupSymbolKeyDescriptor, IntCollectionExternalizer) {
|
||||
override fun dumpKey(key: LookupSymbolKey): String = key.toString()
|
||||
|
||||
override fun dumpValue(value: Collection<Int>): String = value.toString()
|
||||
|
||||
fun add(name: String, scope: String, fileId: Int) {
|
||||
storage.append(LookupSymbolKey(name, scope), fileId)
|
||||
}
|
||||
|
||||
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
|
||||
|
||||
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {
|
||||
storage[key] = fileIds
|
||||
}
|
||||
|
||||
fun remove(key: LookupSymbolKey) {
|
||||
storage.remove(key)
|
||||
}
|
||||
|
||||
val keys: Collection<LookupSymbolKey>
|
||||
get() = storage.keys
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
internal class SourceToJvmNameMap(
|
||||
storageFile: File,
|
||||
pathConverter: FileToPathConverter
|
||||
) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile, pathConverter)
|
||||
|
||||
internal class SourceToFqNameMap(
|
||||
storageFile: File,
|
||||
pathConverter: FileToPathConverter
|
||||
) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile, pathConverter)
|
||||
|
||||
internal abstract class AbstractSourceToOutputMap<Name>(
|
||||
private val nameTransformer: NameTransformer<Name>,
|
||||
storageFile: File,
|
||||
private val pathConverter: FileToPathConverter
|
||||
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(pathConverter.toPath(sourceFile))
|
||||
}
|
||||
|
||||
fun add(sourceFile: File, className: Name) {
|
||||
storage.append(pathConverter.toPath(sourceFile), nameTransformer.asString(className))
|
||||
}
|
||||
|
||||
fun contains(sourceFile: File): Boolean =
|
||||
pathConverter.toPath(sourceFile) in storage
|
||||
|
||||
operator fun get(sourceFile: File): Collection<Name> =
|
||||
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asName)
|
||||
|
||||
fun getFqNames(sourceFile: File): Collection<FqName> =
|
||||
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asFqName)
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
329
build.gradle.kts
329
build.gradle.kts
@@ -1,5 +1,4 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.crypto.checksum.Checksum
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import proguard.gradle.ProGuardTask
|
||||
@@ -7,7 +6,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 +26,10 @@ 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("com.gradle.publish:plugin-publish-plugin:0.11.0")
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,8 +42,6 @@ plugins {
|
||||
idea
|
||||
id("jps-compatible")
|
||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||
id("org.gradle.crypto.checksum") version "1.2.0"
|
||||
signing
|
||||
}
|
||||
|
||||
pill {
|
||||
@@ -153,7 +150,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)
|
||||
@@ -167,7 +163,7 @@ extra["versions.junit"] = "4.12"
|
||||
extra["versions.javaslang"] = "2.0.6"
|
||||
extra["versions.ant"] = "1.8.2"
|
||||
extra["versions.android"] = "2.3.1"
|
||||
val coroutinesVersion = if (Platform[192].orHigher()) "1.3.7" else "1.1.1"
|
||||
val coroutinesVersion = if (Platform[192].orHigher()) "1.2.1" else "1.1.1"
|
||||
extra["versions.kotlinx-coroutines-core"] = coroutinesVersion
|
||||
extra["versions.kotlinx-coroutines-jdk8"] = coroutinesVersion
|
||||
extra["versions.json"] = "20160807"
|
||||
@@ -178,8 +174,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 +184,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.20-dev-16314"
|
||||
extra["versions.kotlin-native"] = "1.4-M3-dev-15453"
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -202,10 +197,7 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
|
||||
|
||||
extra["IntellijCoreDependencies"] =
|
||||
listOf(
|
||||
when {
|
||||
Platform[202].orHigher() -> "asm-all-8.0.1"
|
||||
else -> "asm-all-7.0.1"
|
||||
},
|
||||
if (Platform[191].orHigher()) "asm-all-7.0.1" else "asm-all",
|
||||
"guava",
|
||||
"jdom",
|
||||
"jna",
|
||||
@@ -222,8 +214,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 +222,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 +230,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 +255,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,37 +273,14 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:fir:java",
|
||||
":compiler:fir:jvm",
|
||||
":compiler:fir:checkers",
|
||||
":compiler:fir:entrypoint",
|
||||
":compiler:fir:analysis-tests"
|
||||
)
|
||||
|
||||
extra["compilerModulesForJps"] = listOf(
|
||||
":kotlin-build-common",
|
||||
":kotlin-util-io",
|
||||
":kotlin-util-klib",
|
||||
":kotlin-util-klib-metadata",
|
||||
":compiler:cli-common",
|
||||
":kotlin-compiler-runner",
|
||||
":daemon-common",
|
||||
":daemon-common-new",
|
||||
":core:compiler.common",
|
||||
":core:compiler.common.jvm",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":idea:idea-jps-common",
|
||||
":kotlin-preloader",
|
||||
":compiler:util",
|
||||
":compiler:config",
|
||||
":compiler:config.jvm",
|
||||
":js:js.config",
|
||||
":core:util.runtime",
|
||||
":compiler:compiler.version"
|
||||
)
|
||||
|
||||
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,18 +290,22 @@ 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"
|
||||
)
|
||||
|
||||
val gradlePluginProjects = listOf(
|
||||
":kotlin-gradle-plugin",
|
||||
":kotlin-gradle-plugin:plugin-marker",
|
||||
":kotlin-gradle-plugin-api",
|
||||
// ":kotlin-gradle-plugin-integration-tests", // TODO: build fails
|
||||
":kotlin-allopen",
|
||||
":kotlin-allopen:plugin-marker",
|
||||
":kotlin-annotation-processing-gradle",
|
||||
":kotlin-noarg",
|
||||
":kotlin-sam-with-receiver",
|
||||
":kotlin-parcelize-compiler"
|
||||
":kotlin-noarg:plugin-marker",
|
||||
":kotlin-sam-with-receiver"
|
||||
)
|
||||
|
||||
apply {
|
||||
@@ -366,28 +329,12 @@ 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 {
|
||||
|
||||
configurations.maybeCreate("embedded").apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = true
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
|
||||
}
|
||||
}
|
||||
|
||||
configurations.maybeCreate("embeddedElements").apply {
|
||||
extendsFrom(configurations["embedded"])
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named("embedded-java-runtime"))
|
||||
}
|
||||
}
|
||||
configurations.maybeCreate("embedded")
|
||||
|
||||
jvmTarget = defaultJvmTarget
|
||||
javaHome = defaultJavaHome
|
||||
@@ -419,6 +366,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,20 +380,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 = commonCompilerArgs + listOf("-Xnormalize-constructor-calls=enable")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +412,6 @@ allprojects {
|
||||
ignore("META-INF/MANIFEST.MF")
|
||||
ignore("META-INF/compiler.version")
|
||||
ignore("META-INF/plugin.xml")
|
||||
ignore("kotlin/KotlinVersionCurrentValue.class")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,23 +461,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,12 +468,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)
|
||||
@@ -566,10 +484,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)
|
||||
@@ -595,7 +509,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") }
|
||||
}
|
||||
@@ -604,8 +518,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"
|
||||
@@ -671,6 +583,7 @@ tasks {
|
||||
":compiler:fir:raw-fir:light-tree2fir:test",
|
||||
":compiler:fir:analysis-tests:test",
|
||||
":compiler:fir:fir2ir:test",
|
||||
":idea:idea-fir:test",
|
||||
":plugins:fir:fir-plugin-prototype:test"
|
||||
)
|
||||
}
|
||||
@@ -682,7 +595,7 @@ tasks {
|
||||
register("scriptingTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":kotlin-script-util:test")
|
||||
dependsOn(":kotlin-scripting-compiler-embeddable:test")
|
||||
dependsOn(":kotlin-scripting-compiler:test")
|
||||
dependsOn(":kotlin-scripting-common:test")
|
||||
dependsOn(":kotlin-scripting-jvm:test")
|
||||
dependsOn(":kotlin-scripting-jvm-host-test:test")
|
||||
@@ -694,17 +607,12 @@ 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")
|
||||
}
|
||||
|
||||
register("compilerTest") {
|
||||
dependsOn("jvmCompilerTest")
|
||||
dependsOn("jsCompilerTest")
|
||||
dependsOn("miscCompilerTest")
|
||||
}
|
||||
|
||||
register("miscCompilerTest") {
|
||||
dependsOn("wasmCompilerTest")
|
||||
dependsOn("nativeCompilerTest")
|
||||
dependsOn("firCompilerTest")
|
||||
@@ -713,12 +621,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") {
|
||||
@@ -754,9 +659,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",
|
||||
@@ -764,7 +676,8 @@ tasks {
|
||||
":idea:jvm-debugger:jvm-debugger-evaluation:test",
|
||||
":idea:jvm-debugger:jvm-debugger-sequence:test",
|
||||
":idea:jvm-debugger:eval4j:test",
|
||||
":idea:scripting-support:test"
|
||||
":idea:scripting-support:test",
|
||||
":idea:idea-fir:test"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -779,6 +692,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(
|
||||
@@ -786,38 +710,19 @@ tasks {
|
||||
)
|
||||
}
|
||||
|
||||
register("idea-fir-plugin-performance-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":idea:idea-fir-performance-tests:ideaFirPerformanceTest"
|
||||
)
|
||||
}
|
||||
|
||||
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",
|
||||
@@ -825,41 +730,21 @@ 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 {
|
||||
@@ -878,41 +763,6 @@ tasks {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register("publishIdeArtifacts") {
|
||||
idePluginDependency {
|
||||
dependsOn(
|
||||
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-dist-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide:publish",
|
||||
":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",
|
||||
":kotlin-scripting-jvm:publish",
|
||||
":kotlin-scripting-compiler:publish",
|
||||
":kotlin-scripting-compiler-impl:publish",
|
||||
":kotlin-android-extensions-runtime:publish",
|
||||
":kotlin-stdlib-common:publish",
|
||||
":kotlin-stdlib:publish",
|
||||
":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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun CopySpec.setExecutablePermissions() {
|
||||
@@ -922,15 +772,15 @@ fun CopySpec.setExecutablePermissions() {
|
||||
|
||||
val zipCompiler by task<Zip> {
|
||||
dependsOn(dist)
|
||||
destinationDirectory.set(file(distDir))
|
||||
archiveFileName.set("kotlin-compiler-$kotlinVersion.zip")
|
||||
destinationDir = file(distDir)
|
||||
archiveName = "kotlin-compiler-$kotlinVersion.zip"
|
||||
|
||||
from(distKotlinHomeDir)
|
||||
into("kotlinc")
|
||||
setExecutablePermissions()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("Compiler artifacts packed to ${archiveFile.get().asFile.absolutePath}")
|
||||
logger.lifecycle("Compiler artifacts packed to $archivePath")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,37 +826,10 @@ val zipPlugin by task<Zip> {
|
||||
setExecutablePermissions()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("Plugin artifacts packed to ${archiveFile.get()}")
|
||||
logger.lifecycle("Plugin artifacts packed to $archiveFile")
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.secureZipTask(zipTask: TaskProvider<Zip>): RegisteringDomainObjectDelegateProviderWithAction<out TaskContainer, Task> {
|
||||
val checkSumTask = tasks.register("${zipTask.name}Checksum", Checksum::class) {
|
||||
dependsOn(zipTask)
|
||||
val compilerFile = zipTask.get().outputs.files.singleFile
|
||||
files = files(compilerFile)
|
||||
outputDir = compilerFile.parentFile
|
||||
algorithm = Checksum.Algorithm.SHA256
|
||||
}
|
||||
|
||||
val signTask = tasks.register("${zipTask.name}Sign", Sign::class) {
|
||||
description = "Signs the archive produced by the '" + zipTask.name + "' task."
|
||||
sign(zipTask.get())
|
||||
}
|
||||
|
||||
return tasks.registering {
|
||||
dependsOn(checkSumTask)
|
||||
dependsOn(signTask)
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
}
|
||||
|
||||
val zipCompilerWithSignature by secureZipTask(zipCompiler)
|
||||
val zipPluginWithSignature by secureZipTask(zipPlugin)
|
||||
|
||||
configure<IdeaModel> {
|
||||
module {
|
||||
excludeDirs = files(
|
||||
@@ -1134,15 +957,3 @@ val Jar.outputFile: File
|
||||
|
||||
val Project.sourceSetsOrNull: SourceSetContainer?
|
||||
get() = convention.findPlugin(JavaPluginConvention::class.java)?.sourceSets
|
||||
|
||||
val disableVerificationTasks = System.getProperty("disable.verification.tasks") == "true"
|
||||
if (disableVerificationTasks) {
|
||||
gradle.taskGraph.whenReady {
|
||||
allTasks.forEach {
|
||||
if (it is VerificationTask) {
|
||||
logger.info("DISABLED: '$it'")
|
||||
it.enabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ buildscript {
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
extra["defaultSnapshotVersion"] = kotlinBuildProperties.defaultSnapshotVersion
|
||||
kotlinBootstrapFrom(BootstrapOption.SpaceBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
|
||||
BootstrapOption.BintrayBootstrap("1.4.0-dev-1818", cacheRedirectorEnabled).applyToProject(project)
|
||||
// kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
|
||||
|
||||
repositories {
|
||||
if (cacheRedirectorEnabled) {
|
||||
@@ -22,7 +23,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}")
|
||||
}
|
||||
@@ -72,6 +73,7 @@ rootProject.apply {
|
||||
val isTeamcityBuild = kotlinBuildProperties.isTeamcityBuild
|
||||
val intellijUltimateEnabled by extra(kotlinBuildProperties.intellijUltimateEnabled)
|
||||
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
|
||||
val verifyDependencyOutput by extra( getBooleanProperty("kotlin.build.dependency.output.verification") ?: isTeamcityBuild)
|
||||
|
||||
extra["intellijReleaseType"] = when {
|
||||
extra["versions.intellijSdk"]?.toString()?.contains("-EAP-") == true -> "snapshots"
|
||||
@@ -96,9 +98,7 @@ 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.11.0")
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.17")
|
||||
|
||||
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
|
||||
implementation("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
|
||||
@@ -107,11 +107,9 @@ dependencies {
|
||||
|
||||
implementation("com.github.jengelman.gradle.plugins:shadow:${rootProject.extra["versions.shadow"]}")
|
||||
implementation("net.sf.proguard:proguard-gradle:6.2.2")
|
||||
implementation("org.jetbrains.intellij.deps:asm-all:8.0.1")
|
||||
implementation("org.jetbrains.intellij.deps:asm-all:7.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 {
|
||||
|
||||
8
buildSrc/gradle.properties.as35
Normal file
8
buildSrc/gradle.properties.as35
Normal file
@@ -0,0 +1,8 @@
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
intellijUltimateEnabled=false
|
||||
8
buildSrc/gradle.properties.as36
Normal file
8
buildSrc/gradle.properties.as36
Normal file
@@ -0,0 +1,8 @@
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
intellijUltimateEnabled=false
|
||||
8
buildSrc/gradle.properties.as40
Normal file
8
buildSrc/gradle.properties.as40
Normal file
@@ -0,0 +1,8 @@
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
intellijUltimateEnabled=false
|
||||
@@ -1,20 +1,22 @@
|
||||
@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.FileWriter
|
||||
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 org.jetbrains.kotlin.gradle.tasks.CleanDataTask
|
||||
|
||||
plugins {
|
||||
base
|
||||
}
|
||||
|
||||
val verifyDependencyOutput: Boolean by rootProject.extra
|
||||
val intellijUltimateEnabled: Boolean by rootProject.extra
|
||||
val intellijReleaseType: String by rootProject.extra
|
||||
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
|
||||
@@ -23,7 +25,7 @@ val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelea
|
||||
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
|
||||
val intellijSeparateSdks: Boolean by rootProject.extra
|
||||
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
|
||||
val installIntellijUltimate = intellijUltimateEnabled && androidStudioRelease == null
|
||||
val installIntellijUltimate = intellijUltimateEnabled
|
||||
|
||||
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
|
||||
if (intellijVersionDelimiterIndex == -1) {
|
||||
@@ -32,6 +34,7 @@ if (intellijVersionDelimiterIndex == -1) {
|
||||
|
||||
val platformBaseVersion = intellijVersion.substring(0, intellijVersionDelimiterIndex)
|
||||
|
||||
logger.info("verifyDependencyOutput: $verifyDependencyOutput")
|
||||
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
|
||||
logger.info("intellijVersion: $intellijVersion")
|
||||
logger.info("androidStudioRelease: $androidStudioRelease")
|
||||
@@ -142,7 +145,21 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
val makeIntellijCore = buildIvyRepositoryTask(intellijCore, customDepsOrg, customDepsRepoDir)
|
||||
|
||||
val cleanupIntellijCore = tasks.register<CleanDataTask>("cleanupIntellijCore") {
|
||||
cleanableStoreProvider = provider { CleanableStore[repoDir.resolve("intellij-core").absolutePath] }
|
||||
}
|
||||
|
||||
val cleanupIntellijAnnotation = tasks.register<CleanDataTask>("cleanupIntellijAnnotation") {
|
||||
cleanableStoreProvider = provider { CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath] }
|
||||
}
|
||||
|
||||
val cleanupDependencies = tasks.register("cleanupDependencies") {
|
||||
dependsOn(cleanupIntellijCore)
|
||||
dependsOn(cleanupIntellijAnnotation)
|
||||
}
|
||||
|
||||
val makeIntellijCore = buildIvyRepositoryTaskAndRegisterCleanupTask(intellijCore, customDepsOrg, customDepsRepoDir)
|
||||
|
||||
val makeIntellijAnnotations by tasks.registering(Copy::class) {
|
||||
dependsOn(makeIntellijCore)
|
||||
@@ -150,17 +167,12 @@ val makeIntellijAnnotations by tasks.registering(Copy::class) {
|
||||
val intellijCoreRepo = CleanableStore[repoDir.resolve("intellij-core").absolutePath][intellijVersion].use()
|
||||
from(intellijCoreRepo.resolve("artifacts/annotations.jar"))
|
||||
|
||||
val annotationsStore = CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath]
|
||||
val targetDir = annotationsStore[intellijVersion].use()
|
||||
val targetDir = CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath][intellijVersion].use()
|
||||
into(targetDir)
|
||||
|
||||
val ivyFile = File(targetDir, "$intellijRuntimeAnnotations.ivy.xml")
|
||||
outputs.files(ivyFile)
|
||||
|
||||
doFirst {
|
||||
annotationsStore.cleanStore()
|
||||
}
|
||||
|
||||
doLast {
|
||||
writeIvyXml(
|
||||
customDepsOrg,
|
||||
@@ -179,10 +191,7 @@ val mergeSources by tasks.creating(Jar::class.java) {
|
||||
dependsOn(sources)
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
isZip64 = true
|
||||
if (!kotlinBuildProperties.isTeamcityBuild) {
|
||||
from(provider { sources.map(::zipTree) })
|
||||
}
|
||||
from(provider { sources.map(::zipTree) })
|
||||
destinationDirectory.set(File(repoDir, sources.name))
|
||||
archiveBaseName.set("intellij")
|
||||
archiveClassifier.set("sources")
|
||||
@@ -192,7 +201,7 @@ val mergeSources by tasks.creating(Jar::class.java) {
|
||||
val sourcesFile = mergeSources.outputs.files.singleFile
|
||||
|
||||
val makeIde = if (androidStudioBuild != null) {
|
||||
buildIvyRepositoryTask(
|
||||
buildIvyRepositoryTaskAndRegisterCleanupTask(
|
||||
androidStudio,
|
||||
customDepsOrg,
|
||||
customDepsRepoDir,
|
||||
@@ -203,9 +212,9 @@ val makeIde = if (androidStudioBuild != null) {
|
||||
)
|
||||
} else {
|
||||
val task = if (installIntellijUltimate) {
|
||||
buildIvyRepositoryTask(intellijUltimate, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
buildIvyRepositoryTaskAndRegisterCleanupTask(intellijUltimate, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
} else {
|
||||
buildIvyRepositoryTask(intellij, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
buildIvyRepositoryTaskAndRegisterCleanupTask(intellij, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
}
|
||||
|
||||
task.configure {
|
||||
@@ -215,7 +224,7 @@ val makeIde = if (androidStudioBuild != null) {
|
||||
task
|
||||
}
|
||||
|
||||
val buildJpsStandalone = buildIvyRepositoryTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
val buildJpsStandalone = buildIvyRepositoryTaskAndRegisterCleanupTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
|
||||
tasks.named("build") {
|
||||
dependsOn(
|
||||
@@ -229,15 +238,24 @@ tasks.named("build") {
|
||||
|
||||
if (installIntellijUltimate) {
|
||||
val buildNodeJsPlugin =
|
||||
buildIvyRepositoryTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
|
||||
buildIvyRepositoryTaskAndRegisterCleanupTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
|
||||
tasks.named("build") { dependsOn(buildNodeJsPlugin) }
|
||||
}
|
||||
|
||||
tasks.named("build") { dependsOn(cleanupDependencies) }
|
||||
|
||||
// Task to delete legacy repo locations
|
||||
tasks.register<Delete>("cleanLegacy") {
|
||||
delete("$projectDir/android-dx")
|
||||
delete("$projectDir/intellij-sdk")
|
||||
}
|
||||
|
||||
tasks.named<Delete>("clean") {
|
||||
//TODO specify repos to clean? Use CleanDataTask
|
||||
delete(customDepsRepoDir)
|
||||
}
|
||||
|
||||
fun buildIvyRepositoryTask(
|
||||
fun buildIvyRepositoryTaskAndRegisterCleanupTask(
|
||||
configuration: Configuration,
|
||||
organization: String,
|
||||
repoDirectory: File,
|
||||
@@ -250,29 +268,29 @@ fun buildIvyRepositoryTask(
|
||||
fun ResolvedArtifact.moduleDirectory(): File =
|
||||
storeDirectory()[moduleVersion.id.version].use()
|
||||
|
||||
return tasks.register("buildIvyRepositoryFor${configuration.name.capitalize()}") {
|
||||
val buildIvyRepositoryTask = tasks.register("buildIvyRepositoryFor${configuration.name.capitalize()}") {
|
||||
dependsOn(configuration)
|
||||
inputs.files(configuration)
|
||||
|
||||
outputs.upToDateWhen {
|
||||
val repoMarker = configuration.resolvedConfiguration.resolvedArtifacts.single().moduleDirectory().resolve(".marker")
|
||||
repoMarker.exists()
|
||||
if (verifyDependencyOutput) {
|
||||
outputs.dir(
|
||||
provider {
|
||||
configuration.resolvedConfiguration.resolvedArtifacts.single().moduleDirectory()
|
||||
}
|
||||
)
|
||||
} else {
|
||||
outputs.upToDateWhen {
|
||||
configuration.resolvedConfiguration.resolvedArtifacts.single()
|
||||
.moduleDirectory()
|
||||
.exists()
|
||||
}
|
||||
}
|
||||
|
||||
doFirst {
|
||||
val artifact = configuration.resolvedConfiguration.resolvedArtifacts.single()
|
||||
val moduleDirectory = artifact.moduleDirectory()
|
||||
configuration.resolvedConfiguration.resolvedArtifacts.single().run {
|
||||
val moduleDirectory = moduleDirectory()
|
||||
val artifactsDirectory = File(moduleDirectory(), "artifacts")
|
||||
|
||||
artifact.storeDirectory().cleanStore()
|
||||
|
||||
val repoMarker = File(moduleDirectory, ".marker")
|
||||
if (repoMarker.exists()) {
|
||||
logger.info("Path ${repoMarker.absolutePath} already exists, skipping unpacking.")
|
||||
return@doFirst
|
||||
}
|
||||
|
||||
with(artifact) {
|
||||
val artifactsDirectory = File(moduleDirectory, "artifacts")
|
||||
logger.info("Unpacking ${file.name} into ${artifactsDirectory.absolutePath}")
|
||||
copy {
|
||||
val fileTree = when (extension) {
|
||||
@@ -326,14 +344,22 @@ fun buildIvyRepositoryTask(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
repoMarker.createNewFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun CleanableStore.cleanStore() = cleanDir(Instant.now().minus(Duration.ofDays(30)))
|
||||
val cleanupIvyRepositoryTask = tasks.register<CleanDataTask>("cleanupIvyRepositoryFor${configuration.name.capitalize()}") {
|
||||
cleanableStoreProvider = provider {
|
||||
configuration.resolvedConfiguration.resolvedArtifacts.single().storeDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
cleanupDependencies {
|
||||
dependsOn(cleanupIvyRepositoryTask)
|
||||
}
|
||||
|
||||
return buildIvyRepositoryTask
|
||||
}
|
||||
|
||||
fun writeIvyXml(
|
||||
organization: String,
|
||||
|
||||
@@ -20,13 +20,15 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.17")
|
||||
}
|
||||
}
|
||||
|
||||
def buildProperties = BuildPropertiesKt.getKotlinBuildPropertiesForSettings(settings)
|
||||
def projectVersions = file("../gradle/versions.properties").text
|
||||
|
||||
BuildCacheKt.setupBuildCache(settings)
|
||||
|
||||
include "prepare-deps"
|
||||
|
||||
def target_AppCode_Clion = buildProperties.includeCidrPlugins && !projectVersions.contains("versions.androidStudioRelease")
|
||||
@@ -46,12 +48,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 +71,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;
|
||||
|
||||
val version: Int = name.drop(1).toInt()
|
||||
|
||||
@@ -47,14 +47,10 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
|
||||
IJ192(Platform.P192),
|
||||
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);
|
||||
AS40(Platform.P193);
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,29 +6,14 @@ import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.ConfigurablePublishArtifact
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.artifacts.PublishArtifact
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.attributes.Bundling
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.file.DuplicatesStrategy
|
||||
import org.gradle.api.plugins.BasePluginConvention
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.plugins.JavaPlugin.*
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.tasks.GenerateModuleMetadata
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.Upload
|
||||
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
|
||||
|
||||
|
||||
private const val MAGIC_DO_NOT_CHANGE_TEST_JAR_TASK_NAME = "testJar"
|
||||
@@ -41,7 +26,7 @@ fun Project.testsJar(body: Jar.() -> Unit = {}): Jar {
|
||||
pluginManager.withPlugin("java") {
|
||||
from(testSourceSet.output)
|
||||
}
|
||||
archiveClassifier.set("tests")
|
||||
classifier = "tests"
|
||||
body()
|
||||
project.addArtifact(testsJarCfg, this, this)
|
||||
}
|
||||
@@ -71,26 +56,20 @@ fun Project.noDefaultJar() {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Task> Project.runtimeJarArtifactBy(
|
||||
task: TaskProvider<T>,
|
||||
artifactRef: Any,
|
||||
body: ConfigurablePublishArtifact.() -> Unit = {}
|
||||
) {
|
||||
fun Project.runtimeJarArtifactBy(task: Task, 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)
|
||||
addArtifact(it, task, artifactRef, body)
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.runtimeJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> = runtimeJar(getOrCreateTask("jar", 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> {
|
||||
|
||||
tasks.named<Jar>("jar").configure {
|
||||
removeArtifacts(configurations.getOrCreate("archives"), this)
|
||||
}
|
||||
|
||||
task.configure {
|
||||
configurations.findByName("embedded")?.let { embedded ->
|
||||
dependsOn(embedded)
|
||||
@@ -99,47 +78,19 @@ fun <T : Jar> Project.runtimeJar(task: TaskProvider<T>, body: T.() -> Unit = {})
|
||||
}
|
||||
}
|
||||
setupPublicJar(project.the<BasePluginConvention>().archivesBaseName)
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||
body()
|
||||
project.runtimeJarArtifactBy(this, this)
|
||||
}
|
||||
|
||||
project.runtimeJarArtifactBy(task, task)
|
||||
|
||||
val runtimeJar = configurations.maybeCreate("runtimeJar").apply {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
|
||||
}
|
||||
}
|
||||
|
||||
configurePublishedComponent {
|
||||
withVariantsFromConfiguration(configurations[RUNTIME_ELEMENTS_CONFIGURATION_NAME]) { skip() }
|
||||
addVariantsFromConfiguration(runtimeJar) { }
|
||||
}
|
||||
|
||||
return task
|
||||
}
|
||||
|
||||
fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
|
||||
configure<JavaPluginExtension> {
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
val task = tasks.register<Jar>("sourcesJar") {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
archiveClassifier.set("sources")
|
||||
|
||||
from(project.sources())
|
||||
from(project.mainSourceSet.allSource)
|
||||
|
||||
project.configurations.findByName("embedded")?.let { embedded ->
|
||||
from(provider {
|
||||
@@ -148,7 +99,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
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -156,21 +110,13 @@ fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
|
||||
body()
|
||||
}
|
||||
|
||||
addArtifact("archives", sourcesJar)
|
||||
addArtifact("sources", sourcesJar)
|
||||
addArtifact("archives", task)
|
||||
addArtifact("sources", task)
|
||||
|
||||
configurePublishedComponent {
|
||||
addVariantsFromConfiguration(configurations[SOURCES_ELEMENTS_CONFIGURATION_NAME]) { }
|
||||
}
|
||||
|
||||
return sourcesJar
|
||||
return task
|
||||
}
|
||||
|
||||
fun Project.javadocJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
|
||||
configure<JavaPluginExtension> {
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
val javadocTask = getOrCreateTask<Jar>("javadocJar") {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
archiveClassifier.set("javadoc")
|
||||
@@ -182,40 +128,9 @@ fun Project.javadocJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
|
||||
}
|
||||
|
||||
addArtifact("archives", javadocTask)
|
||||
|
||||
configurePublishedComponent {
|
||||
addVariantsFromConfiguration(configurations[JAVADOC_ELEMENTS_CONFIGURATION_NAME]) { }
|
||||
}
|
||||
|
||||
return javadocTask
|
||||
}
|
||||
|
||||
fun Project.modularJar(body: Jar.() -> Unit): TaskProvider<Jar> {
|
||||
val modularJar = configurations.maybeCreate("modularJar").apply {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named("modular-jar"))
|
||||
}
|
||||
}
|
||||
|
||||
val modularJarTask = getOrCreateTask<Jar>("modularJar") {
|
||||
archiveClassifier.set("modular")
|
||||
|
||||
body()
|
||||
}
|
||||
|
||||
addArtifact("modularJar", modularJarTask)
|
||||
addArtifact("archives", modularJarTask)
|
||||
|
||||
configurePublishedComponent {
|
||||
addVariantsFromConfiguration(modularJar) { mapToMavenScope("runtime") }
|
||||
}
|
||||
|
||||
return modularJarTask
|
||||
}
|
||||
|
||||
|
||||
fun Project.standardPublicJars() {
|
||||
runtimeJar()
|
||||
@@ -223,22 +138,7 @@ fun Project.standardPublicJars() {
|
||||
javadocJar()
|
||||
}
|
||||
|
||||
fun Project.publish(moduleMetadata: Boolean = false, configure: MavenPublication.() -> Unit = { }) {
|
||||
apply<KotlinBuildPublishingPlugin>()
|
||||
|
||||
if (!moduleMetadata) {
|
||||
tasks.withType<GenerateModuleMetadata> {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
val publication = extensions.findByType<PublishingExtension>()
|
||||
?.publications
|
||||
?.findByName(KotlinBuildPublishingPlugin.PUBLICATION_NAME) as MavenPublication
|
||||
publication.configure()
|
||||
}
|
||||
|
||||
fun Project.publishWithLegacyMavenPlugin(body: Upload.() -> Unit = {}): Upload {
|
||||
fun Project.publish(body: Upload.() -> Unit = {}): Upload {
|
||||
apply<plugins.PublishedKotlinModule>()
|
||||
|
||||
if (artifactsRemovedDiagnosticFlag) {
|
||||
@@ -255,87 +155,12 @@ fun Project.publishWithLegacyMavenPlugin(body: Upload.() -> Unit = {}): Upload {
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.idePluginDependency(block: () -> Unit) {
|
||||
val shouldActivate = rootProject.findProperty("publish.ide.plugin.dependencies")?.toString()?.toBoolean() == true
|
||||
if (shouldActivate) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.publishProjectJars(projects: List<String>, libraryDependencies: List<String> = emptyList()) {
|
||||
apply<JavaPlugin>()
|
||||
|
||||
val fatJarContents by configurations.creating
|
||||
|
||||
dependencies {
|
||||
for (projectName in projects) {
|
||||
fatJarContents(project(projectName)) { isTransitive = false }
|
||||
}
|
||||
|
||||
for (libraryDependency in libraryDependencies) {
|
||||
fatJarContents(libraryDependency)
|
||||
}
|
||||
}
|
||||
|
||||
publish()
|
||||
|
||||
val jar: Jar by tasks
|
||||
|
||||
jar.apply {
|
||||
dependsOn(fatJarContents)
|
||||
|
||||
from {
|
||||
fatJarContents.map(::zipTree)
|
||||
}
|
||||
}
|
||||
|
||||
sourcesJar {
|
||||
from {
|
||||
projects.map {
|
||||
project(it).mainSourceSet.allSource
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
javadocJar()
|
||||
}
|
||||
|
||||
fun Project.publishTestJar(projectName: String) {
|
||||
apply<JavaPlugin>()
|
||||
|
||||
val fatJarContents by configurations.creating
|
||||
|
||||
dependencies {
|
||||
fatJarContents(project(projectName, configuration = "tests-jar")) { isTransitive = false }
|
||||
}
|
||||
|
||||
publish()
|
||||
|
||||
val jar: Jar by tasks
|
||||
|
||||
jar.apply {
|
||||
dependsOn(fatJarContents)
|
||||
|
||||
from {
|
||||
fatJarContents.map(::zipTree)
|
||||
}
|
||||
}
|
||||
|
||||
sourcesJar {
|
||||
from {
|
||||
project(projectName).testSourceSet.allSource
|
||||
}
|
||||
}
|
||||
|
||||
javadocJar()
|
||||
}
|
||||
|
||||
fun ConfigurationContainer.getOrCreate(name: String): Configuration = findByName(name) ?: create(name)
|
||||
|
||||
fun Jar.setupPublicJar(baseName: String, classifier: String = "") {
|
||||
val buildNumber = project.rootProject.extra["buildNumber"] as String
|
||||
this.archiveBaseName.set(baseName)
|
||||
this.archiveClassifier.set(classifier)
|
||||
this.baseName = baseName
|
||||
this.classifier = classifier
|
||||
manifest.attributes.apply {
|
||||
put("Implementation-Vendor", "JetBrains")
|
||||
put("Implementation-Title", baseName)
|
||||
@@ -354,26 +179,9 @@ fun Project.addArtifact(configuration: Configuration, task: Task, artifactRef: A
|
||||
fun Project.addArtifact(configurationName: String, task: Task, artifactRef: Any, body: ConfigurablePublishArtifact.() -> Unit = {}) =
|
||||
addArtifact(configurations.getOrCreate(configurationName), task, artifactRef, body)
|
||||
|
||||
fun <T : Task> Project.addArtifact(
|
||||
configurationName: String,
|
||||
task: TaskProvider<T>,
|
||||
body: ConfigurablePublishArtifact.() -> Unit = {}
|
||||
): PublishArtifact {
|
||||
fun <T : Task> Project.addArtifact(configurationName: String, task: TaskProvider<T>, body: ConfigurablePublishArtifact.() -> Unit = {}) {
|
||||
configurations.maybeCreate(configurationName)
|
||||
return artifacts.add(configurationName, task, body)
|
||||
}
|
||||
|
||||
fun <T : Task> Project.addArtifact(
|
||||
configurationName: String,
|
||||
task: TaskProvider<T>,
|
||||
artifactRef: Any,
|
||||
body: ConfigurablePublishArtifact.() -> Unit = {}
|
||||
): PublishArtifact {
|
||||
configurations.maybeCreate(configurationName)
|
||||
return artifacts.add(configurationName, artifactRef) {
|
||||
builtBy(task)
|
||||
body()
|
||||
}
|
||||
artifacts.add(configurationName, task, body)
|
||||
}
|
||||
|
||||
fun Project.cleanArtifacts() {
|
||||
@@ -383,6 +191,3 @@ fun Project.cleanArtifacts() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configurePublishedComponent(configure: AdhocComponentWithVariants.() -> Unit) =
|
||||
(components.findByName(KotlinBuildPublishingPlugin.ADHOC_COMPONENT_NAME) as AdhocComponentWithVariants?)?.apply(configure)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -20,6 +20,7 @@ val packagesToRelocate =
|
||||
"org.picocontainer",
|
||||
"org.jline",
|
||||
"org.fusesource",
|
||||
"kotlinx.coroutines",
|
||||
"net.jpountz",
|
||||
"one.util.streamex",
|
||||
"kotlinx.collections.immutable"
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,76 +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 com.gradle.publish.PluginBundleExtension
|
||||
import com.gradle.publish.PluginConfig
|
||||
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>()
|
||||
val mainPublication = publishingExtension.publications[KotlinBuildPublishingPlugin.PUBLICATION_NAME] as MavenPublication
|
||||
|
||||
pluginDevelopment.plugins.forEach { declaration ->
|
||||
val markerPublication = createMavenMarkerPublication(declaration, mainPublication, publishingExtension.publications)
|
||||
if (withEmptyJars) {
|
||||
addEmptyJarArtifacts(markerPublication)
|
||||
}
|
||||
|
||||
tasks.named<PublishToMavenRepository>(
|
||||
"publish${markerPublication.name.capitalize(Locale.ROOT)}PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository"
|
||||
).configureRepository()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.addEmptyJarArtifacts(publication: MavenPublication) {
|
||||
val emptyJar = getOrCreateTask<Jar>("emptyJar") {
|
||||
archiveBaseName.set("empty")
|
||||
}
|
||||
|
||||
publication.artifact(emptyJar.get()) { }
|
||||
publication.artifact(emptyJar.get()) { classifier = "sources" }
|
||||
publication.artifact(emptyJar.get()) { classifier = "javadoc" }
|
||||
}
|
||||
|
||||
// Based on code from `java-gradle-plugin`
|
||||
// https://github.com/gradle/gradle/blob/v6.4.0/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/MavenPluginPublishPlugin.java#L84
|
||||
private fun createMavenMarkerPublication(
|
||||
declaration: PluginConfig,
|
||||
coordinates: MavenPublication,
|
||||
publications: PublicationContainer
|
||||
): MavenPublication {
|
||||
return publications.create<MavenPublication>(declaration.name.toString() + "PluginMarkerMaven") {
|
||||
val pluginId: String = declaration.id
|
||||
artifactId = pluginId + PLUGIN_MARKER_SUFFIX
|
||||
groupId = pluginId
|
||||
pom.withXml {
|
||||
val root = asElement()
|
||||
val document = root.ownerDocument
|
||||
val dependencies = root.appendChild(document.createElement("dependencies"))
|
||||
val dependency = dependencies.appendChild(document.createElement("dependency"))
|
||||
val groupId = dependency.appendChild(document.createElement("groupId"))
|
||||
groupId.textContent = coordinates.groupId
|
||||
val artifactId = dependency.appendChild(document.createElement("artifactId"))
|
||||
artifactId.textContent = coordinates.artifactId
|
||||
val version = dependency.appendChild(document.createElement("version"))
|
||||
version.textContent = coordinates.version
|
||||
}
|
||||
|
||||
pom.name.set(declaration.displayName)
|
||||
pom.description.set(declaration.description)
|
||||
}
|
||||
}
|
||||
@@ -1,160 +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 plugins
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.component.SoftwareComponentFactory
|
||||
import org.gradle.api.plugins.JavaBasePlugin
|
||||
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.SigningExtension
|
||||
import org.gradle.plugins.signing.SigningPlugin
|
||||
import java.net.URI
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class KotlinBuildPublishingPlugin @Inject constructor(
|
||||
private val componentFactory: SoftwareComponentFactory
|
||||
) : Plugin<Project> {
|
||||
override fun apply(target: Project): Unit = with(target) {
|
||||
apply<MavenPublishPlugin>()
|
||||
apply<SigningPlugin>()
|
||||
|
||||
val publishedRuntime = configurations.maybeCreate(RUNTIME_CONFIGURATION).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
|
||||
}
|
||||
}
|
||||
|
||||
val publishedCompile = configurations.maybeCreate(COMPILE_CONFIGURATION).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_API))
|
||||
}
|
||||
}
|
||||
|
||||
val kotlinLibraryComponent = componentFactory.adhoc(ADHOC_COMPONENT_NAME) as AdhocComponentWithVariants
|
||||
components.add(kotlinLibraryComponent)
|
||||
kotlinLibraryComponent.addVariantsFromConfiguration(publishedCompile) { mapToMavenScope("compile") }
|
||||
kotlinLibraryComponent.addVariantsFromConfiguration(publishedRuntime) { mapToMavenScope("runtime") }
|
||||
|
||||
pluginManager.withPlugin("java-base") {
|
||||
val runtimeElements by configurations
|
||||
val apiElements by configurations
|
||||
|
||||
publishedRuntime.extendsFrom(runtimeElements)
|
||||
publishedCompile.extendsFrom(apiElements)
|
||||
|
||||
kotlinLibraryComponent.addVariantsFromConfiguration(runtimeElements) {
|
||||
mapToMavenScope("runtime")
|
||||
|
||||
if (configurationVariant.artifacts.any { JavaBasePlugin.UNPUBLISHABLE_VARIANT_ARTIFACTS.contains(it.type) }) {
|
||||
skip()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configure<PublishingExtension> {
|
||||
publications {
|
||||
create<MavenPublication>(PUBLICATION_NAME) {
|
||||
from(kotlinLibraryComponent)
|
||||
|
||||
pom {
|
||||
packaging = "jar"
|
||||
name.set(humanReadableName(project))
|
||||
description.set(project.description ?: humanReadableName(project))
|
||||
url.set("https://kotlinlang.org/")
|
||||
licenses {
|
||||
license {
|
||||
name.set("The Apache License, Version 2.0")
|
||||
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url.set("https://github.com/JetBrains/kotlin")
|
||||
connection.set("scm:git:https://github.com/JetBrains/kotlin.git")
|
||||
developerConnection.set("scm:git:https://github.com/JetBrains/kotlin.git")
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
name.set("Kotlin Team")
|
||||
organization.set("JetBrains")
|
||||
organizationUrl.set("https://www.jetbrains.com")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = REPOSITORY_NAME
|
||||
url = file("${project.rootDir}/build/repo").toURI()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configure<SigningExtension> {
|
||||
setRequired(provider {
|
||||
project.findProperty("signingRequired")?.toString()?.toBoolean()
|
||||
?: project.property("isSonatypeRelease") as Boolean
|
||||
})
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PUBLICATION_NAME = "Main"
|
||||
const val REPOSITORY_NAME = "Maven"
|
||||
const val ADHOC_COMPONENT_NAME = "kotlinLibrary"
|
||||
|
||||
const val COMPILE_CONFIGURATION = "publishedCompile"
|
||||
const val RUNTIME_CONFIGURATION = "publishedRuntime"
|
||||
|
||||
@UseExperimental(ExperimentalStdlibApi::class)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,18 +31,12 @@ open class PublishedKotlinModule : Plugin<Project> {
|
||||
|
||||
plugins.apply("maven")
|
||||
|
||||
configurations.maybeCreate("publishedRuntime").apply {
|
||||
val publishedRuntime by configurations.creating {
|
||||
the<MavenPluginConvention>()
|
||||
.conf2ScopeMappings
|
||||
.addMapping(0, this, Conf2ScopeMappingContainer.RUNTIME)
|
||||
}
|
||||
|
||||
configurations.maybeCreate("publishedCompile").apply {
|
||||
the<MavenPluginConvention>()
|
||||
.conf2ScopeMappings
|
||||
.addMapping(0, this, Conf2ScopeMappingContainer.COMPILE)
|
||||
}
|
||||
|
||||
if (!project.hasProperty("prebuiltJar")) {
|
||||
plugins.apply("signing")
|
||||
|
||||
@@ -52,7 +46,6 @@ open class PublishedKotlinModule : Plugin<Project> {
|
||||
configure<SigningExtension> {
|
||||
isRequired = signingRequired
|
||||
sign(configurations["archives"])
|
||||
useGpgCmd()
|
||||
}
|
||||
|
||||
tasks.named<Sign>("signArchives").configure {
|
||||
|
||||
@@ -23,15 +23,3 @@ fun DependencyHandler.publishedRuntime(
|
||||
): ExternalModuleDependency =
|
||||
addDependencyTo(this, "publishedRuntime", dependencyNotation, dependencyConfiguration)
|
||||
|
||||
|
||||
val NamedDomainObjectContainer<Configuration>.publishedCompile: NamedDomainObjectProvider<Configuration> get() = named("publishedCompile")
|
||||
|
||||
fun DependencyHandler.publishedCompile(dependencyNotation: Any): Dependency? =
|
||||
add("publishedCompile", dependencyNotation)
|
||||
|
||||
fun DependencyHandler.publishedCompile(
|
||||
dependencyNotation: String,
|
||||
dependencyConfiguration: Action<ExternalModuleDependency>
|
||||
): ExternalModuleDependency =
|
||||
addDependencyTo(this, "publishedCompile", dependencyNotation, dependencyConfiguration)
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -120,20 +79,21 @@ fun Project.projectTest(
|
||||
}
|
||||
}
|
||||
|
||||
if (project.findProperty("kotlin.test.instrumentation.disable")?.toString()?.toBoolean() != true) {
|
||||
doFirst {
|
||||
val agent = tasks.findByPath(":test-instrumenter:jar")!!.outputs.files.singleFile
|
||||
val args = project.findProperty("kotlin.test.instrumentation.args")?.let { "=$it" }.orEmpty()
|
||||
jvmArgs("-javaagent:$agent$args")
|
||||
}
|
||||
dependsOn(":test-instrumenter:jar")
|
||||
doFirst {
|
||||
val agent = tasks.findByPath(":test-instrumenter:jar")!!.outputs.files.singleFile
|
||||
|
||||
val args = project.findProperty("kotlin.test.instrumentation.args")?.let { "=$it" }.orEmpty()
|
||||
|
||||
jvmArgs("-javaagent:$agent$args")
|
||||
}
|
||||
|
||||
dependsOn(":test-instrumenter:jar")
|
||||
|
||||
jvmArgs(
|
||||
"-ea",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-XX:+UseCodeCacheFlushing",
|
||||
"-XX:ReservedCodeCacheSize=256m",
|
||||
"-XX:ReservedCodeCacheSize=128m",
|
||||
"-Djna.nosys=true"
|
||||
)
|
||||
|
||||
@@ -146,11 +106,6 @@ fun Project.projectTest(
|
||||
environment("PROJECT_BUILD_DIR", buildDir)
|
||||
systemProperty("jps.kotlin.home", rootProject.extra["distKotlinHomeDir"]!!)
|
||||
systemProperty("kotlin.ni", if (rootProject.hasProperty("newInferenceTests")) "true" else "false")
|
||||
systemProperty("org.jetbrains.kotlin.skip.muted.tests", if (rootProject.hasProperty("skipMutedTests")) "true" else "false")
|
||||
|
||||
if (Platform[202].orHigher()) {
|
||||
systemProperty("idea.ignore.disabled.plugins", "true")
|
||||
}
|
||||
|
||||
var subProjectTempRoot: Path? = null
|
||||
doFirst {
|
||||
|
||||
@@ -6,33 +6,32 @@ 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) }
|
||||
}
|
||||
|
||||
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", rootProject = rootProject) }
|
||||
Platform[202].orHigher {
|
||||
testCompile(intellijDep()) { includeJars("groovy", rootProject = rootProject) }
|
||||
}
|
||||
Platform[201].orLower {
|
||||
testCompile(intellijDep()) { includeJars("groovy-all", rootProject = rootProject) }
|
||||
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", "groovy-all", rootProject = rootProject) }
|
||||
Platform[191].orLower {
|
||||
testCompile(intellijDep()) { includeJars("jps-builders") }
|
||||
}
|
||||
Platform[192].orHigher {
|
||||
testCompile(intellijPluginDep("java")) { includeJars("jps-builders") }
|
||||
@@ -42,7 +41,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;
|
||||
|
||||
@@ -100,11 +100,9 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
File("./gradlew.bat").copyTo(File(projectRoot, "gradlew.bat"));
|
||||
val file = File(target, "gradle-wrapper.properties")
|
||||
file.readLines().map {
|
||||
when {
|
||||
it.startsWith("distributionUrl") -> "distributionUrl=https\\://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip"
|
||||
it.startsWith("distributionSha256Sum") -> "distributionSha256Sum=$GRADLE_SHA_256"
|
||||
else -> it
|
||||
}
|
||||
if (it.startsWith("distributionUrl"))
|
||||
"distributionUrl=https\\://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip"
|
||||
else it
|
||||
}.let { lines ->
|
||||
FileWriter(file).use { fw ->
|
||||
lines.forEach { line ->
|
||||
@@ -294,7 +292,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 +301,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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -317,8 +315,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
CodegenTestCase.createTestFilesFromFile(file, expectedText, "kotlin.coroutines", false, TargetBackend.JVM)
|
||||
|
||||
companion object {
|
||||
const val GRADLE_VERSION = "5.6.4" // update GRADLE_SHA_256 on change
|
||||
const val GRADLE_SHA_256 = "1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d"
|
||||
const val GRADLE_VERSION = "5.6.4"
|
||||
const val testClassPackage = "org.jetbrains.kotlin.android.tests"
|
||||
const val testClassName = "CodegenTestCaseOnAndroid"
|
||||
const val baseTestClassPackage = "org.jetbrains.kotlin.android.tests"
|
||||
|
||||
@@ -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,31 +80,33 @@ 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)
|
||||
|
||||
private fun mapMembers(
|
||||
inherited: CallableMemberDescriptor,
|
||||
traitMember: CallableMemberDescriptor
|
||||
): Map<FunctionDescriptor, FunctionDescriptor> = when (traitMember) {
|
||||
is SimpleFunctionDescriptor -> mapOf(traitMember to inherited as FunctionDescriptor)
|
||||
is PropertyDescriptor -> linkedMapOf<FunctionDescriptor, FunctionDescriptor>().also { result ->
|
||||
): LinkedHashMap<FunctionDescriptor, FunctionDescriptor> {
|
||||
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||
if (traitMember is SimpleFunctionDescriptor) {
|
||||
result[traitMember] = inherited as FunctionDescriptor
|
||||
} else if (traitMember is PropertyDescriptor) {
|
||||
for (traitAccessor in traitMember.accessors) {
|
||||
for (inheritedAccessor in (inherited as PropertyDescriptor).accessors) {
|
||||
if ((inheritedAccessor is PropertyGetterDescriptor) == (traitAccessor is PropertyGetterDescriptor)) {
|
||||
result[traitAccessor] = inheritedAccessor
|
||||
if (inheritedAccessor::class.java == traitAccessor::class.java) { // same accessor kind
|
||||
result.put(traitAccessor, inheritedAccessor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> error("Unexpected member: $inherited")
|
||||
return result
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -17,13 +17,11 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.mapToIndex
|
||||
|
||||
@@ -37,10 +35,10 @@ abstract class ArgumentGenerator {
|
||||
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
|
||||
*/
|
||||
open fun generate(
|
||||
valueArgumentsByIndex: List<ResolvedValueArgument>,
|
||||
actualArgs: List<ResolvedValueArgument>,
|
||||
// may be null for a constructor of an object literal
|
||||
calleeDescriptor: CallableDescriptor?
|
||||
valueArgumentsByIndex: List<ResolvedValueArgument>,
|
||||
actualArgs: List<ResolvedValueArgument>,
|
||||
// may be null for a constructor of an object literal
|
||||
calleeDescriptor: CallableDescriptor?
|
||||
): DefaultCallArgs {
|
||||
assert(valueArgumentsByIndex.size == actualArgs.size) {
|
||||
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
|
||||
@@ -52,9 +50,9 @@ abstract class ArgumentGenerator {
|
||||
ArgumentAndDeclIndex(it, arg2Index[it]!!)
|
||||
}.toMutableList()
|
||||
|
||||
for ((index, value) in valueArgumentsByIndex.withIndex()) {
|
||||
if (value is DefaultValueArgument) {
|
||||
actualArgsWithDeclIndex.add(index, ArgumentAndDeclIndex(value, index))
|
||||
valueArgumentsByIndex.withIndex().forEach {
|
||||
if (it.value is DefaultValueArgument) {
|
||||
actualArgsWithDeclIndex.add(it.index, ArgumentAndDeclIndex(it.value, it.index))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +70,8 @@ abstract class ArgumentGenerator {
|
||||
is DefaultValueArgument -> {
|
||||
if (calleeDescriptor?.defaultValueFromJava(declIndex) == true) {
|
||||
generateDefaultJava(declIndex, argument)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
defaultArgs.mark(declIndex)
|
||||
generateDefault(declIndex, argument)
|
||||
}
|
||||
@@ -117,42 +116,11 @@ abstract class ArgumentGenerator {
|
||||
}
|
||||
|
||||
private fun CallableDescriptor.defaultValueFromJava(index: Int): Boolean = DFS.ifAny(
|
||||
listOf(this),
|
||||
{ current -> current.original.overriddenDescriptors.map { it.original } },
|
||||
{ descriptor ->
|
||||
descriptor.original.overriddenDescriptors.isEmpty() &&
|
||||
descriptor is JavaCallableMemberDescriptor &&
|
||||
descriptor.valueParameters[index].declaresDefaultValue()
|
||||
}
|
||||
listOf(this),
|
||||
{ current -> current.original.overriddenDescriptors.map { it.original } },
|
||||
{ descriptor ->
|
||||
descriptor.original.overriddenDescriptors.isEmpty() &&
|
||||
descriptor is JavaCallableMemberDescriptor &&
|
||||
descriptor.valueParameters[index].declaresDefaultValue()
|
||||
}
|
||||
)
|
||||
|
||||
fun shouldInvokeDefaultArgumentsStub(resolvedCall: ResolvedCall<*>): Boolean {
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
val valueArgumentsByIndex = resolvedCall.valueArgumentsByIndex ?: return false
|
||||
for (index in valueArgumentsByIndex.indices) {
|
||||
val resolvedValueArgument = valueArgumentsByIndex[index]
|
||||
if (resolvedValueArgument is DefaultValueArgument && !descriptor.defaultValueFromJava(index)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun getFunctionWithDefaultArguments(functionDescriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
if (functionDescriptor.containingDeclaration !is ClassDescriptor) return functionDescriptor
|
||||
if (functionDescriptor.overriddenDescriptors.isEmpty()) return functionDescriptor
|
||||
|
||||
// We are calling a function with some arguments mapped as defaults.
|
||||
// Multiple override-equivalent functions from different supertypes with (potentially different) default values
|
||||
// can't be overridden by any function in a subtype.
|
||||
// Also, a function overriding some other function can't introduce default parameter values.
|
||||
// Thus, among all overridden functions should be one (and only one) function
|
||||
// that doesn't override anything and has parameters with default values.
|
||||
return functionDescriptor.overriddenTreeUniqueAsSequence(true)
|
||||
.firstOrNull { function ->
|
||||
function.kind == CallableMemberDescriptor.Kind.DECLARATION &&
|
||||
function.overriddenDescriptors.isEmpty() &&
|
||||
function.valueParameters.any { valueParameter -> valueParameter.hasDefaultValue() }
|
||||
}
|
||||
?: functionDescriptor
|
||||
}
|
||||
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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
@@ -19,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.util.Printer
|
||||
class CallableMethod(
|
||||
override val owner: Type,
|
||||
private val defaultImplOwner: Type?,
|
||||
computeDefaultMethod: () -> Method,
|
||||
computeDefaultMethodDesc: () -> String,
|
||||
private val signature: JvmMethodSignature,
|
||||
val invokeOpcode: Int,
|
||||
override val dispatchReceiverType: Type?,
|
||||
@@ -31,10 +32,7 @@ class CallableMethod(
|
||||
val isInterfaceMethod: Boolean,
|
||||
private val isDefaultMethodInInterface: Boolean
|
||||
) : Callable {
|
||||
private val defaultImplMethod: Method by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethod)
|
||||
|
||||
private val defaultImplMethodName: String get() = defaultImplMethod.name
|
||||
private val defaultMethodDesc: String get() = defaultImplMethod.descriptor
|
||||
private val defaultMethodDesc: String by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethodDesc)
|
||||
|
||||
fun getValueParameters(): List<JvmMethodParameterSignature> =
|
||||
signature.valueParameters
|
||||
@@ -70,14 +68,10 @@ class CallableMethod(
|
||||
} else {
|
||||
v.visitMethodInsn(
|
||||
INVOKESTATIC, defaultImplOwner.internalName,
|
||||
defaultImplMethodName, defaultMethodDesc, isDefaultMethodInInterface
|
||||
method.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, isDefaultMethodInInterface
|
||||
)
|
||||
|
||||
StackValue.coerce(
|
||||
Type.getReturnType(defaultMethodDesc),
|
||||
Type.getReturnType(signature.asmMethod.descriptor),
|
||||
v
|
||||
)
|
||||
StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ 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;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
@@ -38,8 +38,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 +124,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);
|
||||
}
|
||||
@@ -221,32 +219,21 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
protected void generateDelegatesToDefaultImpl() {
|
||||
if (isJvmInterface(descriptor)) return;
|
||||
|
||||
boolean isErasedInlineClass = InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
|
||||
JvmKotlinType receiverType = new JvmKotlinType(typeMapper.mapType(descriptor), descriptor.getDefaultType());
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
generateDelegationToDefaultImpl(entry.getKey(), entry.getValue(), receiverType, functionCodegen, state, isErasedInlineClass);
|
||||
FunctionDescriptor interfaceFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) &&
|
||||
!JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(
|
||||
DescriptorUtils.unwrapFakeOverrideToAnyDeclaration(interfaceFun), state.getJvmDefaultMode()
|
||||
)
|
||||
) {
|
||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateDelegationToDefaultImpl(
|
||||
@NotNull FunctionDescriptor interfaceFun,
|
||||
@NotNull FunctionDescriptor inheritedFun,
|
||||
@NotNull JvmKotlinType receiverType,
|
||||
@NotNull FunctionCodegen functionCodegen,
|
||||
@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())) {
|
||||
return;
|
||||
}
|
||||
private void generateDelegationToDefaultImpl(@NotNull FunctionDescriptor interfaceFun, @NotNull FunctionDescriptor inheritedFun) {
|
||||
|
||||
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||
functionCodegen.generateMethod(
|
||||
new JvmDeclarationOrigin(
|
||||
CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun, null
|
||||
@@ -261,7 +248,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
|
||||
PsiElement classForInheritedFun = descriptorToDeclaration(declarationInheritedFun);
|
||||
if (classForInheritedFun instanceof KtDeclaration) {
|
||||
codegen.markLineNumber(classForInheritedFun, false);
|
||||
codegen.markLineNumber((KtElement) classForInheritedFun, false);
|
||||
}
|
||||
|
||||
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
||||
@@ -295,15 +282,18 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
InstructionAdapter iv = codegen.v;
|
||||
Type[] myArgTypes = signature.getAsmMethod().getArgumentTypes();
|
||||
Type[] toArgTypes = defaultImplsMethod.getArgumentTypes();
|
||||
boolean isErasedInlineClass =
|
||||
InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
|
||||
|
||||
int myArgI = 0;
|
||||
int argVar = 0;
|
||||
|
||||
Type receiverType = typeMapper.mapType(descriptor);
|
||||
KotlinType interfaceKotlinType = ((ClassDescriptor) inheritedFun.getContainingDeclaration()).getDefaultType();
|
||||
StackValue.local(argVar, receiverType.getType(), receiverType.getKotlinType())
|
||||
StackValue.local(argVar, receiverType, descriptor.getDefaultType())
|
||||
.put(OBJECT_TYPE, interfaceKotlinType, iv);
|
||||
if (isErasedInlineClass) myArgI++;
|
||||
argVar += receiverType.getType().getSize();
|
||||
argVar += receiverType.getSize();
|
||||
|
||||
int toArgI = 1;
|
||||
|
||||
|
||||
@@ -50,11 +50,11 @@ 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.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
@@ -140,7 +140,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
|
||||
this.asmType = typeMapper.mapClass(classDescriptor);
|
||||
|
||||
visibilityFlag = DescriptorAsmUtil.getVisibilityAccessFlagForClass(classDescriptor);
|
||||
visibilityFlag = AsmUtil.getVisibilityAccessFlagForClass(classDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +170,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
superInterfaceAsmTypes
|
||||
);
|
||||
|
||||
initDefaultSourceMappingIfNeeded();
|
||||
initDefaultSourceMappingIfNeeded(context, this, state);
|
||||
|
||||
v.visitSource(element.getContainingFile().getName(), null);
|
||||
}
|
||||
@@ -186,12 +186,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
generateBridges();
|
||||
generateClosureBody();
|
||||
|
||||
if (samType != null) {
|
||||
SamWrapperCodegen.generateDelegatesToDefaultImpl(
|
||||
asmType, classDescriptor, samType.getClassDescriptor(), functionCodegen, state
|
||||
);
|
||||
}
|
||||
|
||||
this.constructor = generateConstructor();
|
||||
|
||||
if (isConst(closure)) {
|
||||
@@ -266,9 +260,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
|
||||
assert method != null : "No method for " + frontendFunDescriptor;
|
||||
|
||||
FunctionDescriptor freeLambdaDescriptor = FakeDescriptorsForReferencesKt.createFreeFakeLambdaDescriptor(
|
||||
frontendFunDescriptor, state.getTypeApproximator()
|
||||
);
|
||||
FunctionDescriptor freeLambdaDescriptor = FakeDescriptorsForReferencesKt.createFreeFakeLambdaDescriptor(frontendFunDescriptor);
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
@@ -415,7 +407,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
if (generateBody) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
CallableReferenceUtilKt.generateFunctionReferenceSignature(iv, descriptor, state);
|
||||
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, descriptor, state);
|
||||
iv.areturn(JAVA_STRING_TYPE);
|
||||
FunctionCodegen.endVisit(iv, "function reference getSignature", element);
|
||||
}
|
||||
@@ -473,7 +465,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
assert functionReferenceTarget != null : "No function reference target: " + funDescriptor;
|
||||
generateCallableReferenceDeclarationContainerClass(iv, functionReferenceTarget, state);
|
||||
iv.aconst(functionReferenceTarget.getName().asString());
|
||||
CallableReferenceUtilKt.generateFunctionReferenceSignature(iv, functionReferenceTarget, state);
|
||||
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, functionReferenceTarget, state);
|
||||
int flags =
|
||||
getCallableReferenceTopLevelFlag(functionReferenceTarget) +
|
||||
(calculateFunctionReferenceFlags(functionReferenceCall, funDescriptor) << 1);
|
||||
@@ -590,8 +582,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;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user