Compare commits

..

3 Commits

Author SHA1 Message Date
Dmitry Petrov
ef461d4a3a JVM_IR KT-36646 fuze primitive equality with safe call 2021-04-27 16:22:53 +03:00
Dmitry Petrov
eaf870bfd4 JVM_IR update test for KT-36637 2021-04-27 16:22:52 +03:00
Dmitry Petrov
e8982765c8 JVM_IR use static 'hashCode' for boxed primitives on JVM 1.8+ 2021-04-27 16:22:52 +03:00
58776 changed files with 1210396 additions and 302716 deletions

4
.bunch
View File

@@ -1,2 +1,2 @@
203
202
202
as42

3
.gitignore vendored
View File

@@ -12,7 +12,6 @@
/android-studio/sdk
out/
/tmp
kotlin-ide/
workspace.xml
*.versionsBackup
/idea/testData/debugger/tinyApp/classes*
@@ -58,7 +57,7 @@ build/
.idea/artifacts/kotlin_stdlib_wasm_*
.idea/jarRepositories.xml
.idea/csv-plugin.xml
.idea/libraries-with-intellij-classes.xml
kotlin-ultimate/
node_modules/
.rpt2_cache/
libraries/tools/kotlin-test-js-runner/lib/

View File

@@ -1,8 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="igor">
<words>
<w>descr</w>
<w>exprs</w>
</words>
</dictionary>
</component>

View File

@@ -2,7 +2,6 @@
<dictionary name="skuzmich">
<words>
<w>anyref</w>
<w>dataref</w>
<w>ushr</w>
<w>wasm</w>
</words>

2
.idea/kotlinc.xml generated
View File

@@ -13,6 +13,6 @@
</option>
</component>
<component name="KotlinCompilerSettings">
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check" />
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check -Xread-deserialized-contracts" />
</component>
</project>

View File

@@ -11,7 +11,7 @@
<option name="taskNames">
<list>
<option value=":compiler:fir:checkers:generateCheckersComponents" />
<option value=":idea-frontend-fir:generateCode" />
<option value=":idea:idea-frontend-fir:generateCode" />
</list>
</option>
<option name="vmOptions" value="" />

20
.idea/runConfigurations/IDEA.xml generated Normal file
View File

@@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA" type="GradleRunConfiguration" factoryName="Gradle" singleton="true" folderName="IDEA">
<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="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA Ultimate" type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-P intellijUltimateEnabled" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runUltimate" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA Ultimate (No ProcessCanceledException) " type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-PnoPCE" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runUltimate" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -0,0 +1,20 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA (No ProcessCanceledException)" type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-PnoPCE" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA (Not Internal)" type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-Pidea.is.internal=false" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
</configuration>
</component>

View File

@@ -1,23 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: Commonizer / Light" type="GradleRunConfiguration" factoryName="Gradle" folderName="Tests">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":native:kotlin-klib-commonizer-api:test" />
<option value=":native:kotlin-klib-commonizer:test" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>

12
.idea/vcs.xml generated
View File

@@ -8,18 +8,6 @@
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
<component name="GithubSharedProjectSettings">
<option name="branchProtectionPatterns">
<list>
<option value="master" />
<option value="1\.5\.0-M2" />
<option value="1\.5\.0" />
<option value="1\.5\.20" />
<option value="1\.5\.20-M1-release" />
<option value="1\.5\.20-RC-release" />
</list>
</option>
</component>
<component name="IssueNavigationConfiguration">
<option name="links">
<list>

File diff suppressed because it is too large Load Diff

View File

@@ -35,30 +35,26 @@ Support for multiplatform programming is one of Kotlins key benefits. It redu
## Editing Kotlin
* [Kotlin IntelliJ IDEA Plugin](https://kotlinlang.org/docs/tutorials/getting-started.html) ([source code](https://github.com/JetBrains/intellij-community/tree/master/plugins/kotlin))
* [Kotlin IntelliJ IDEA Plugin](https://kotlinlang.org/docs/tutorials/getting-started.html)
* [Kotlin Eclipse Plugin](https://kotlinlang.org/docs/tutorials/getting-started-eclipse.html)
* [Kotlin Sublime Text Package](https://github.com/vkostyukov/kotlin-sublime-package)
## Build environment requirements
This repository is using [Gradle toolchains](https://docs.gradle.org/current/userguide/toolchains.html) feature
to select and auto-provision required JDKs from [AdoptOpenJdk](https://adoptopenjdk.net) project.
In order to build Kotlin distribution you need to have:
Unfortunately [AdoptOpenJdk](https://adoptopenjdk.net) project does not provide required JDK 1.6 and 1.7 images,
so you could either download them manually and provide path to installation via `JDK_16` and `JDK_17` environment variables or
use following SDK managers:
- [Asdf-vm](https://asdf-vm.com/)
- [Jabba](https://github.com/shyiko/jabba)
- [SDKMAN!](https://sdkman.io/)
- JDK 1.6, 1.7, 1.8 and 9
- Setup environment variables as following:
Alternatively, it is still possible to only provide required JDKs via environment variables
(see [gradle.properties](./gradle.properties#L5) for supported variable names). To ensure Gradle uses only JDKs
from environmental variables - disable Gradle toolchain auto-detection by passing `-Porg.gradle.java.installations.auto-detect=false` option
(or put it into `$GRADLE_USER_HOME/gradle.properties`).
JAVA_HOME="path to JDK 1.8"
JDK_16="path to JDK 1.6"
JDK_17="path to JDK 1.7"
JDK_18="path to JDK 1.8"
JDK_9="path to JDK 9"
For local development, if you're not working on the standard library, it's OK to avoid installing JDK 1.6 and JDK 1.7.
Add `kotlin.build.isObsoleteJdkOverrideEnabled=true` to the `local.properties` file, so build will only use JDK 1.8+. Note, that in this
case, build will have Gradle remote build cache misses for some tasks.
For local development, if you're not working on bytecode generation or the standard library, it's OK to have only JDK 1.8 and JDK 9 installed, and to point `JDK_16` and `JDK_17` environment variables to your JDK 1.8 installation.
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
@@ -97,10 +93,13 @@ command line parameters on the first run:
- `clean` - clean build results
- `dist` - assembles the compiler distribution into `dist/kotlinc/` folder
- `ideaPlugin` - assembles the Kotlin IDEA plugin distribution into `dist/artifacts/ideaPlugin/Kotlin/` folder
- `install` - build and install all public artifacts into local maven repository
- `runIde` - build IDEA plugin and run IDEA with it
- `coreLibsTest` - build and run stdlib, reflect and kotlin-test tests
- `gradlePluginTest` - build and run gradle plugin tests
- `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.
@@ -140,6 +139,14 @@ To be able to run tests from IntelliJ easily, check `Delegate IDE build/run acti
At this time, you can use the latest released `1.3.x` version of the Kotlin plugin for working with the code. To make sure you have the latest version installed, use `Tools` -> `Kotlin` -> `Configure Kotlin Plugin Updates`.
### Compiling and running
From this root project there are Run/Debug Configurations for running `IDEA` or the `Generate Compiler Tests` for example; so if you want to try out the latest and greatest IDEA plugin
* `VCS` -> `Git` -> `Pull`
* Run the `IDEA` run configuration in the project
* A child IntelliJ IDEA with the Kotlin plugin will then startup
### Dependency verification
We have a [dependencies verification](https://docs.gradle.org/current/userguide/dependency_verification.html) feature enabled in the

View File

@@ -1,11 +1,11 @@
import kotlinx.benchmark.gradle.benchmark
val benchmarks_version = "0.3.1"
val benchmarks_version = "0.3.0"
plugins {
java
kotlin("jvm")
id("org.jetbrains.kotlinx.benchmark") version "0.3.1"
id("org.jetbrains.kotlinx.benchmark") version "0.3.0"
}
dependencies {

View File

@@ -12,7 +12,6 @@ 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.ObsoleteTestInfrastructure
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
@@ -25,7 +24,6 @@ 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.builder.PsiHandlingMode
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.createSessionForTests
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
@@ -149,13 +147,12 @@ abstract class AbstractSimpleFileBenchmark {
bh.consume(result.shouldGenerateCode)
}
@OptIn(ObsoleteTestInfrastructure::class)
private fun analyzeGreenFileIr(bh: Blackhole) {
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
val session = createSessionForTests(env, scope)
val firProvider = session.firProvider as FirProviderImpl
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, PsiHandlingMode.COMPILER)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider)
val totalTransformer = FirTotalResolveProcessor(session)
val firFile = builder.buildFirFile(file).also(firProvider::recordFile)

View File

@@ -1,65 +0,0 @@
group = "org.jetbrains"
version = "1.0-SNAPSHOT"
plugins {
java
application
}
buildscript {
val kotlinVersion = System.getenv("KOTLIN_VERSION") ?: "1.5.255-SNAPSHOT"
val kotlinRepo = "https://buildserver.labs.intellij.net/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinDev_CompilerDistAndMavenArtifacts),number:$kotlinVersion,branch:default:any/artifacts/content/maven"
extra["kotlinRepo"] = kotlinRepo
repositories {
mavenLocal()
maven {
url = uri(kotlinRepo)
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
apply {
plugin("kotlin")
}
val kotlinRepo: String by extra
repositories {
maven { url = uri("https://repo.gradle.org/gradle/libs-releases") }
mavenLocal()
maven {
url = uri(kotlinRepo)
}
}
dependencies {
implementation("org.jetbrains:kotlin-build-benchmarks:1.0-SNAPSHOT")
implementation(kotlin("stdlib"))
}
application {
mainClassName = "RunBenchmarksKt"
}
tasks.register("runGavra0", JavaExec::class) {
classpath = sourceSets.main.get().runtimeClasspath
main = "RunGavra0BenchmarksKt"
}
tasks.register("runAbiSnapshot", JavaExec::class) {
classpath = sourceSets.main.get().runtimeClasspath
main = "RunAbiSnapshotsBenchmarksKt"
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
kotlinOptions {
freeCompilerArgs += listOf(
"-Xuse-experimental=kotlin.ExperimentalUnsignedTypes"
)
}
}

View File

@@ -1,205 +0,0 @@
import org.jetbrains.kotlin.build.benchmarks.dsl.*
fun abiSnapshotBenchmarks() = kotlinBenchmarks(arrayOf("-Dkotlin.incremental.classpath.snapshot.enabled=true"))
fun artifactTransformBenchmarks() = kotlinBenchmarks(arrayOf("-Dkotlin.incremental.useClasspathSnapshot=true"))
fun kotlinBenchmarks(additionalDefaultProperties: Array<String> = emptyArray()) =
suite {
val coreUtilStrings = changeableFile("coreUtil/StringsKt")
val coreUtilCoreLib = changeableFile("coreUtil/CoreLibKt")
val compilerCommonBackendContext = changeableFile("compiler/CommonBackendContext")
val kotlinGradlePluginConfigurationPhaseAware = changeableFile("kotlinGradlePlugin/ConfigurationPhaseAware")
val buildSrc = changeableFile("buildSrc/BuildPropertiesExtKt")
defaultTasks(Tasks.DIST, Tasks.COMPILER_TEST_CLASSES, Tasks.KOTLIN_GRADLE_PLUGIN_COMPILE_JAVA)
defaultJdk = System.getenv("JDK_8")
val noArgs = arrayOf<String>()
val defaultArguments = arrayOf(
"--info",
"--no-build-cache",
"--watch-fs",
*additionalDefaultProperties
)
val parallelBuild = arrayOf(
*defaultArguments,
"--parallel",
)
val nonParallelBuild = arrayOf(
*defaultArguments,
"--no-parallel",
)
defaultArguments(*defaultArguments)
scenario("clean build") {
arguments(*nonParallelBuild)
expectSlowBuild("clean build")
step {
doNotMeasure()
runTasks(Tasks.CLEAN)
}
step {}
}
scenario("(buildSrc, Kotlin) add public fun") {
step {
changeFile(buildSrc, TypeOfChange.ADD_PUBLIC_FUNCTION)
runTasks(*noArgs)
}
}
scenario("(buildSrc, Kotlin) add private fun") {
step {
changeFile(buildSrc, TypeOfChange.ADD_PRIVATE_FUNCTION)
runTasks(*noArgs)
}
}
scenario("clean build parallel") {
arguments(*parallelBuild)
expectSlowBuild("clean build")
step {
doNotMeasure()
runTasks(Tasks.CLEAN)
}
step {}
}
scenario("Run gradle plugin tests") {
arguments(*nonParallelBuild)
step {
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_TEST)
}
step {
doNotMeasure()
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_TEST_CLEAN)
}
repeat = 5U
}
scenario("Run gradle plugin tests after changes") {
arguments(*nonParallelBuild)
step {
changeFile(kotlinGradlePluginConfigurationPhaseAware, TypeOfChange.ADD_PRIVATE_FUNCTION)
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_TEST)
}
step {
doNotMeasure()
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_TEST_CLEAN)
}
repeat = 5U
}
scenario("(non-leaf, core) add private function") {
arguments(*nonParallelBuild)
step {
changeFile(coreUtilStrings, TypeOfChange.ADD_PRIVATE_FUNCTION)
}
}
scenario("(non-leaf, core) add public function") {
arguments(*nonParallelBuild)
step {
changeFile(coreUtilStrings, TypeOfChange.ADD_PUBLIC_FUNCTION)
}
}
scenario("(non-leaf, core) add private class") {
arguments(*nonParallelBuild)
step {
changeFile(coreUtilStrings, TypeOfChange.ADD_PRIVATE_CLASS)
}
}
scenario("(non-leaf, core) add public class") {
arguments(*nonParallelBuild)
step {
changeFile(coreUtilStrings, TypeOfChange.ADD_PUBLIC_CLASS)
}
}
scenario("(non-leaf, core) build after error") {
arguments(*nonParallelBuild)
step {
doNotMeasure()
expectBuildToFail()
changeFile(coreUtilStrings, TypeOfChange.INTRODUCE_COMPILE_ERROR)
}
step {
changeFile(coreUtilStrings, TypeOfChange.FIX_COMPILE_ERROR)
}
}
scenario("(non-leaf, core) change popular inline function") {
arguments(*nonParallelBuild)
step {
changeFile(coreUtilCoreLib, TypeOfChange.CHANGE_INLINE_FUNCTION)
}
}
scenario("(non-leaf, compiler) add public function") {
arguments(*nonParallelBuild)
step {
changeFile(compilerCommonBackendContext, TypeOfChange.ADD_PUBLIC_FUNCTION)
}
}
scenario("(non-leaf, compiler) add private function") {
arguments(*nonParallelBuild)
step {
changeFile(compilerCommonBackendContext, TypeOfChange.ADD_PRIVATE_FUNCTION)
}
}
scenario("(leaf, kotlin gradle plugin) add private function") {
arguments(*nonParallelBuild)
step {
changeFile(kotlinGradlePluginConfigurationPhaseAware, TypeOfChange.ADD_PRIVATE_FUNCTION)
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_COMPILE_JAVA)
}
}
scenario("(leaf, kotlin gradle plugin) add public function") {
arguments(*nonParallelBuild)
step {
changeFile(kotlinGradlePluginConfigurationPhaseAware, TypeOfChange.ADD_PUBLIC_FUNCTION)
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_COMPILE_JAVA)
}
}
}
fun gavra0Benchmarks() =
suite {
defaultArguments("-Dorg.gradle.workers.max=8", "--parallel", "--watch-fs")
defaultJdk = System.getenv("JDK_8")
val stdlibFileTreeWalk = changeableFile("gavra0/stdlib/FileTreeWalkKt")
val coreDescriptorsClassDescriptorsBase = changeableFile("gavra0/coreDescriptors/ClassDescriptorBaseJava")
scenario("build") {
step {
doNotMeasure()
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_COMPILE_JAVA)
}
}
scenario("abi change to stdlib") {
step {
changeFile(stdlibFileTreeWalk, TypeOfChange.ADD_PUBLIC_FUNCTION)
runTasks(Tasks.KOTLIN_GRADLE_PLUGIN_COMPILE_JAVA)
}
repeat = 10U
}
scenario("abi change to core.descriptors") {
step {
changeFile(coreDescriptorsClassDescriptorsBase, TypeOfChange.ADD_PUBLIC_FUNCTION)
runTasks(Tasks.DIST)
}
repeat = 10U
}
}

View File

@@ -1,5 +0,0 @@
import org.jetbrains.kotlin.build.benchmarks.*
fun main() {
mainImpl(kotlinBenchmarks(arrayOf("-Dkotlin.incremental.classpath.snapshot.enabled=true")), "../.") // expected working dir is %KOTLIN_PROJECT_PATH%/build-benchmarks/
}

View File

@@ -1,5 +0,0 @@
import org.jetbrains.kotlin.build.benchmarks.*
fun main() {
mainImpl(kotlinBenchmarks(arrayOf("-Dkotlin.incremental.useClasspathSnapshot=true")), "../.") // expected working dir is %KOTLIN_PROJECT_PATH%/build-benchmarks/
}

View File

@@ -1,7 +0,0 @@
import org.jetbrains.kotlin.build.benchmarks.*
fun main() {
mainImpl(kotlinBenchmarks(), "../.") // expected working dir is %KOTLIN_PROJECT_PATH%/build-benchmarks/
mainImpl(abiSnapshotBenchmarks(), "../.")
mainImpl(artifactTransformBenchmarks(), "../.")
}

View File

@@ -1,5 +0,0 @@
import org.jetbrains.kotlin.build.benchmarks.*
fun main() {
mainImpl(gavra0Benchmarks(), "../.") // expected working dir is %KOTLIN_PROJECT_PATH%/build-benchmarks/
}

View File

@@ -1,26 +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.
*/
val KotlinBuildProperties.includeJava9: Boolean
get() = !isInJpsBuildIdeaSync && getBoolean("kotlin.build.java9", true)
val KotlinBuildProperties.useBootstrapStdlib: Boolean
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
val KotlinBuildProperties.postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
val KotlinBuildProperties.relocation: Boolean get() = postProcessing
val KotlinBuildProperties.proguard: Boolean get() = postProcessing && getBoolean("kotlin.build.proguard", isTeamcityBuild)
val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.build.jar.compression", isTeamcityBuild)
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
val KotlinBuildProperties.disableWerror: Boolean
get() = getBoolean("kotlin.build.disable.werror") || useFir || isInJpsBuildIdeaSync || getBoolean("test.progressive.mode")
val KotlinBuildProperties.isObsoleteJdkOverrideEnabled: Boolean
get() = getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)

View File

@@ -1 +0,0 @@
buildSrc/src/main/kotlin/BuildPropertiesExt.kt

View File

@@ -1,28 +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.
*/
val KotlinBuildProperties.includeJava9: Boolean
get() = !isInJpsBuildIdeaSync && getBoolean("kotlin.build.java9", true)
val KotlinBuildProperties.useBootstrapStdlib: Boolean
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
val KotlinBuildProperties.postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
val KotlinBuildProperties.relocation: Boolean get() = postProcessing
val KotlinBuildProperties.proguard: Boolean get() = postProcessing && getBoolean("kotlin.build.proguard", isTeamcityBuild)
val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.build.jar.compression", isTeamcityBuild)
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
val KotlinBuildProperties.disableWerror: Boolean
get() = getBoolean("kotlin.build.disable.werror") || useFir || isInJpsBuildIdeaSync || getBoolean("test.progressive.mode")
val KotlinBuildProperties.isObsoleteJdkOverrideEnabled: Boolean
get() = getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)
private fun foo() {}

View File

@@ -1,28 +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.
*/
val KotlinBuildProperties.includeJava9: Boolean
get() = !isInJpsBuildIdeaSync && getBoolean("kotlin.build.java9", true)
val KotlinBuildProperties.useBootstrapStdlib: Boolean
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
val KotlinBuildProperties.postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
val KotlinBuildProperties.relocation: Boolean get() = postProcessing
val KotlinBuildProperties.proguard: Boolean get() = postProcessing && getBoolean("kotlin.build.proguard", isTeamcityBuild)
val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.build.jar.compression", isTeamcityBuild)
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
val KotlinBuildProperties.disableWerror: Boolean
get() = getBoolean("kotlin.build.disable.werror") || useFir || isInJpsBuildIdeaSync || getBoolean("test.progressive.mode")
val KotlinBuildProperties.isObsoleteJdkOverrideEnabled: Boolean
get() = getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)
fun foo() {}

View File

@@ -1,56 +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.backend.common
import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irString
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
interface LoggingContext {
var inVerbosePhase: Boolean
fun log(message: () -> String)
}
interface CommonBackendContext : BackendContext, LoggingContext {
override val ir: Ir<CommonBackendContext>
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
val configuration: CompilerConfiguration
val scriptMode: Boolean
fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression {
val throwErrorFunction = ir.symbols.throwUninitializedPropertyAccessException.owner
return builder.irCall(throwErrorFunction).apply {
putValueArgument(0, builder.irString(name))
}
}
val mapping: Mapping
// Adjust internal structures after a deep copy of some declarations.
fun handleDeepCopy(
fileSymbolMap: MutableMap<IrFileSymbol, IrFileSymbol>,
classSymbolMap: MutableMap<IrClassSymbol, IrClassSymbol>,
functionSymbolMap: MutableMap<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>
) {}
fun isSideEffectFree(call: IrCall): Boolean {
return false
}
val preferJavaLikeCounterLoop: Boolean
get() = false
}

View File

@@ -1 +0,0 @@
compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt

View File

@@ -1,58 +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.backend.common
import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irString
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
interface LoggingContext {
var inVerbosePhase: Boolean
fun log(message: () -> String)
}
interface CommonBackendContext : BackendContext, LoggingContext {
override val ir: Ir<CommonBackendContext>
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
val configuration: CompilerConfiguration
val scriptMode: Boolean
fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression {
val throwErrorFunction = ir.symbols.throwUninitializedPropertyAccessException.owner
return builder.irCall(throwErrorFunction).apply {
putValueArgument(0, builder.irString(name))
}
}
val mapping: Mapping
// Adjust internal structures after a deep copy of some declarations.
fun handleDeepCopy(
fileSymbolMap: MutableMap<IrFileSymbol, IrFileSymbol>,
classSymbolMap: MutableMap<IrClassSymbol, IrClassSymbol>,
functionSymbolMap: MutableMap<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>
) {}
fun isSideEffectFree(call: IrCall): Boolean {
return false
}
val preferJavaLikeCounterLoop: Boolean
get() = false
}
private fun foo() {}

View File

@@ -1,58 +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.backend.common
import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irString
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
interface LoggingContext {
var inVerbosePhase: Boolean
fun log(message: () -> String)
}
interface CommonBackendContext : BackendContext, LoggingContext {
override val ir: Ir<CommonBackendContext>
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
val configuration: CompilerConfiguration
val scriptMode: Boolean
fun throwUninitializedPropertyAccessException(builder: IrBuilderWithScope, name: String): IrExpression {
val throwErrorFunction = ir.symbols.throwUninitializedPropertyAccessException.owner
return builder.irCall(throwErrorFunction).apply {
putValueArgument(0, builder.irString(name))
}
}
val mapping: Mapping
// Adjust internal structures after a deep copy of some declarations.
fun handleDeepCopy(
fileSymbolMap: MutableMap<IrFileSymbol, IrFileSymbol>,
classSymbolMap: MutableMap<IrClassSymbol, IrClassSymbol>,
functionSymbolMap: MutableMap<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>
) {}
fun isSideEffectFree(call: IrCall): Boolean {
return false
}
val preferJavaLikeCounterLoop: Boolean
get() = false
}
fun foo() {}

View File

@@ -1,19 +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.utils
inline fun <T : Any> T?.sure(message: () -> String): T = this ?: throw AssertionError(message())

View File

@@ -1 +0,0 @@
core/util.runtime/src/org/jetbrains/kotlin/utils/coreLib.kt

View File

@@ -1,19 +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.utils
fun <T : Any> T?.sure(message: () -> String): T = this ?: throw AssertionError(message())

View File

@@ -1,20 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) = collection.joinToString(separator)

View File

@@ -1 +0,0 @@
core/util.runtime/src/org/jetbrains/kotlin/utils/strings.kt

View File

@@ -1,22 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) = collection.joinToString(separator)
private class Foo()

View File

@@ -1,22 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) = collection.joinToString(separator)
private fun foo() {}

View File

@@ -1,22 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) = collection.joinToString(separator)
class Foo()

View File

@@ -1,22 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) = collection.joinToString(separator)
fun foo() {}

View File

@@ -1,20 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) = collection.joinToString(separator)

View File

@@ -1,20 +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.utils
// Needed for Java interop: otherwise you need to specify all the optional parameters to join, i.e. prefix, postfix, limit, truncated
fun join(collection: Iterable<Any>, separator: String) =

View File

@@ -1,60 +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.descriptors.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.storage.StorageManager;
public abstract class ClassDescriptorBase extends AbstractClassDescriptor {
private final DeclarationDescriptor containingDeclaration;
private final SourceElement source;
private final boolean isExternal;
protected ClassDescriptorBase(
@NotNull StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull SourceElement source,
boolean isExternal
) {
super(storageManager, name);
this.containingDeclaration = containingDeclaration;
this.source = source;
this.isExternal = isExternal;
}
@Override
public boolean isExternal() {
return isExternal;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration;
}
@NotNull
@Override
public SourceElement getSource() {
return source;
}
}

View File

@@ -1 +0,0 @@
core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ClassDescriptorBase.java

View File

@@ -1,64 +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.descriptors.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.storage.StorageManager;
public abstract class ClassDescriptorBase extends AbstractClassDescriptor {
private final DeclarationDescriptor containingDeclaration;
private final SourceElement source;
private final boolean isExternal;
protected ClassDescriptorBase(
@NotNull StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull SourceElement source,
boolean isExternal
) {
super(storageManager, name);
this.containingDeclaration = containingDeclaration;
this.source = source;
this.isExternal = isExternal;
}
@Override
public boolean isExternal() {
return isExternal;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration;
}
@NotNull
@Override
public SourceElement getSource() {
return source;
}
public static String foo() {
return "bar";
}
}

View File

@@ -1,272 +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.
*/
@file:JvmMultifileClass
@file:JvmName("FilesKt")
package kotlin.io
import java.io.File
import java.io.IOException
import java.util.ArrayDeque
/**
* An enumeration to describe possible walk directions.
* There are two of them: beginning from parents, ending with children,
* and beginning from children, ending with parents. Both use depth-first search.
*/
public enum class FileWalkDirection {
/** Depth-first search, directory is visited BEFORE its files */
TOP_DOWN,
/** Depth-first search, directory is visited AFTER its files */
BOTTOM_UP
// Do we want also breadth-first search?
}
/**
* This class is intended to implement different file traversal methods.
* It allows to iterate through all files inside a given directory.
*
* Use [File.walk], [File.walkTopDown] or [File.walkBottomUp] extension functions to instantiate a `FileTreeWalk` instance.
* If the file path given is just a file, walker iterates only it.
* If the file path given does not exist, walker iterates nothing, i.e. it's equivalent to an empty sequence.
*/
public class FileTreeWalk private constructor(
private val start: File,
private val direction: FileWalkDirection = FileWalkDirection.TOP_DOWN,
private val onEnter: ((File) -> Boolean)?,
private val onLeave: ((File) -> Unit)?,
private val onFail: ((f: File, e: IOException) -> Unit)?,
private val maxDepth: Int = Int.MAX_VALUE
) : Sequence<File> {
internal constructor(start: File, direction: FileWalkDirection = FileWalkDirection.TOP_DOWN) : this(start, direction, null, null, null)
/** Returns an iterator walking through files. */
override fun iterator(): Iterator<File> = FileTreeWalkIterator()
/** Abstract class that encapsulates file visiting in some order, beginning from a given [root] */
private abstract class WalkState(val root: File) {
/** Call of this function proceeds to a next file for visiting and returns it */
public abstract fun step(): File?
}
/** Abstract class that encapsulates directory visiting in some order, beginning from a given [rootDir] */
private abstract class DirectoryState(rootDir: File) : WalkState(rootDir) {
init {
if (_Assertions.ENABLED)
assert(rootDir.isDirectory) { "rootDir must be verified to be directory beforehand." }
}
}
private inner class FileTreeWalkIterator : AbstractIterator<File>() {
// Stack of directory states, beginning from the start directory
private val state = ArrayDeque<WalkState>()
init {
when {
start.isDirectory -> state.push(directoryState(start))
start.isFile -> state.push(SingleFileState(start))
else -> done()
}
}
override fun computeNext() {
val nextFile = gotoNext()
if (nextFile != null)
setNext(nextFile)
else
done()
}
private fun directoryState(root: File): DirectoryState {
return when (direction) {
FileWalkDirection.TOP_DOWN -> TopDownDirectoryState(root)
FileWalkDirection.BOTTOM_UP -> BottomUpDirectoryState(root)
}
}
private tailrec fun gotoNext(): File? {
// Take next file from the top of the stack or return if there's nothing left
val topState = state.peek() ?: return null
val file = topState.step()
if (file == null) {
// There is nothing more on the top of the stack, go back
state.pop()
return gotoNext()
} else {
// Check that file/directory matches the filter
if (file == topState.root || !file.isDirectory || state.size >= maxDepth) {
// Proceed to a root directory or a simple file
return file
} else {
// Proceed to a sub-directory
state.push(directoryState(file))
return gotoNext()
}
}
}
/** Visiting in bottom-up order */
private inner class BottomUpDirectoryState(rootDir: File) : DirectoryState(rootDir) {
private var rootVisited = false
private var fileList: Array<File>? = null
private var fileIndex = 0
private var failed = false
/** First all children, then root directory */
override fun step(): File? {
if (!failed && fileList == null) {
if (onEnter?.invoke(root) == false) {
return null
}
fileList = root.listFiles()
if (fileList == null) {
onFail?.invoke(root, AccessDeniedException(file = root, reason = "Cannot list files in a directory"))
failed = true
}
}
if (fileList != null && fileIndex < fileList!!.size) {
// First visit all files
return fileList!![fileIndex++]
} else if (!rootVisited) {
// Then visit root
rootVisited = true
return root
} else {
// That's all
onLeave?.invoke(root)
return null
}
}
}
/** Visiting in top-down order */
private inner class TopDownDirectoryState(rootDir: File) : DirectoryState(rootDir) {
private var rootVisited = false
private var fileList: Array<File>? = null
private var fileIndex = 0
/** First root directory, then all children */
override fun step(): File? {
if (!rootVisited) {
// First visit root
if (onEnter?.invoke(root) == false) {
return null
}
rootVisited = true
return root
} else if (fileList == null || fileIndex < fileList!!.size) {
if (fileList == null) {
// Then read an array of files, if any
fileList = root.listFiles()
if (fileList == null) {
onFail?.invoke(root, AccessDeniedException(file = root, reason = "Cannot list files in a directory"))
}
if (fileList == null || fileList!!.size == 0) {
onLeave?.invoke(root)
return null
}
}
// Then visit all files
return fileList!![fileIndex++]
} else {
// That's all
onLeave?.invoke(root)
return null
}
}
}
private inner class SingleFileState(rootFile: File) : WalkState(rootFile) {
private var visited: Boolean = false
init {
if (_Assertions.ENABLED)
assert(rootFile.isFile) { "rootFile must be verified to be file beforehand." }
}
override fun step(): File? {
if (visited) return null
visited = true
return root
}
}
}
/**
* Sets a predicate [function], that is called on any entered directory before its files are visited
* and before it is visited itself.
*
* If the [function] returns `false` the directory is not entered and neither it nor its files are visited.
*/
public fun onEnter(function: (File) -> Boolean): FileTreeWalk {
return FileTreeWalk(start, direction, onEnter = function, onLeave = onLeave, onFail = onFail, maxDepth = maxDepth)
}
/**
* Sets a callback [function], that is called on any left directory after its files are visited and after it is visited itself.
*/
public fun onLeave(function: (File) -> Unit): FileTreeWalk {
return FileTreeWalk(start, direction, onEnter = onEnter, onLeave = function, onFail = onFail, maxDepth = maxDepth)
}
/**
* Set a callback [function], that is called on a directory when it's impossible to get its file list.
*
* [onEnter] and [onLeave] callback functions are called even in this case.
*/
public fun onFail(function: (File, IOException) -> Unit): FileTreeWalk {
return FileTreeWalk(start, direction, onEnter = onEnter, onLeave = onLeave, onFail = function, maxDepth = maxDepth)
}
/**
* Sets the maximum [depth] of a directory tree to traverse. By default there is no limit.
*
* The value must be positive and [Int.MAX_VALUE] is used to specify an unlimited depth.
*
* With a value of 1, walker visits only the origin directory and all its immediate children,
* with a value of 2 also grandchildren, etc.
*/
public fun maxDepth(depth: Int): FileTreeWalk {
if (depth <= 0)
throw IllegalArgumentException("depth must be positive, but was $depth.")
return FileTreeWalk(start, direction, onEnter, onLeave, onFail, depth)
}
}
/**
* Gets a sequence for visiting this directory and all its content.
*
* @param direction walk direction, top-down (by default) or bottom-up.
*/
public fun File.walk(direction: FileWalkDirection = FileWalkDirection.TOP_DOWN): FileTreeWalk =
FileTreeWalk(this, direction)
/**
* Gets a sequence for visiting this directory and all its content in top-down order.
* Depth-first search is used and directories are visited before all their files.
*/
public fun File.walkTopDown(): FileTreeWalk = walk(FileWalkDirection.TOP_DOWN)
/**
* Gets a sequence for visiting this directory and all its content in bottom-up order.
* Depth-first search is used and directories are visited after all their files.
*/
public fun File.walkBottomUp(): FileTreeWalk = walk(FileWalkDirection.BOTTOM_UP)

View File

@@ -1 +0,0 @@
libraries/stdlib/jvm/src/kotlin/io/files/FileTreeWalk.kt

View File

@@ -1,276 +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.
*/
@file:JvmMultifileClass
@file:JvmName("FilesKt")
package kotlin.io
import java.io.File
import java.io.IOException
import java.util.ArrayDeque
/**
* An enumeration to describe possible walk directions.
* There are two of them: beginning from parents, ending with children,
* and beginning from children, ending with parents. Both use depth-first search.
*/
public enum class FileWalkDirection {
/** Depth-first search, directory is visited BEFORE its files */
TOP_DOWN,
/** Depth-first search, directory is visited AFTER its files */
BOTTOM_UP
// Do we want also breadth-first search?
}
/**
* This class is intended to implement different file traversal methods.
* It allows to iterate through all files inside a given directory.
*
* Use [File.walk], [File.walkTopDown] or [File.walkBottomUp] extension functions to instantiate a `FileTreeWalk` instance.
* If the file path given is just a file, walker iterates only it.
* If the file path given does not exist, walker iterates nothing, i.e. it's equivalent to an empty sequence.
*/
public class FileTreeWalk private constructor(
private val start: File,
private val direction: FileWalkDirection = FileWalkDirection.TOP_DOWN,
private val onEnter: ((File) -> Boolean)?,
private val onLeave: ((File) -> Unit)?,
private val onFail: ((f: File, e: IOException) -> Unit)?,
private val maxDepth: Int = Int.MAX_VALUE
) : Sequence<File> {
internal constructor(start: File, direction: FileWalkDirection = FileWalkDirection.TOP_DOWN) : this(start, direction, null, null, null)
/** Returns an iterator walking through files. */
override fun iterator(): Iterator<File> = FileTreeWalkIterator()
/** Abstract class that encapsulates file visiting in some order, beginning from a given [root] */
private abstract class WalkState(val root: File) {
/** Call of this function proceeds to a next file for visiting and returns it */
public abstract fun step(): File?
}
/** Abstract class that encapsulates directory visiting in some order, beginning from a given [rootDir] */
private abstract class DirectoryState(rootDir: File) : WalkState(rootDir) {
init {
if (_Assertions.ENABLED)
assert(rootDir.isDirectory) { "rootDir must be verified to be directory beforehand." }
}
}
private inner class FileTreeWalkIterator : AbstractIterator<File>() {
// Stack of directory states, beginning from the start directory
private val state = ArrayDeque<WalkState>()
init {
when {
start.isDirectory -> state.push(directoryState(start))
start.isFile -> state.push(SingleFileState(start))
else -> done()
}
}
override fun computeNext() {
val nextFile = gotoNext()
if (nextFile != null)
setNext(nextFile)
else
done()
}
private fun directoryState(root: File): DirectoryState {
return when (direction) {
FileWalkDirection.TOP_DOWN -> TopDownDirectoryState(root)
FileWalkDirection.BOTTOM_UP -> BottomUpDirectoryState(root)
}
}
private tailrec fun gotoNext(): File? {
// Take next file from the top of the stack or return if there's nothing left
val topState = state.peek() ?: return null
val file = topState.step()
if (file == null) {
// There is nothing more on the top of the stack, go back
state.pop()
return gotoNext()
} else {
// Check that file/directory matches the filter
if (file == topState.root || !file.isDirectory || state.size >= maxDepth) {
// Proceed to a root directory or a simple file
return file
} else {
// Proceed to a sub-directory
state.push(directoryState(file))
return gotoNext()
}
}
}
/** Visiting in bottom-up order */
private inner class BottomUpDirectoryState(rootDir: File) : DirectoryState(rootDir) {
private var rootVisited = false
private var fileList: Array<File>? = null
private var fileIndex = 0
private var failed = false
/** First all children, then root directory */
override fun step(): File? {
if (!failed && fileList == null) {
if (onEnter?.invoke(root) == false) {
return null
}
fileList = root.listFiles()
if (fileList == null) {
onFail?.invoke(root, AccessDeniedException(file = root, reason = "Cannot list files in a directory"))
failed = true
}
}
if (fileList != null && fileIndex < fileList!!.size) {
// First visit all files
return fileList!![fileIndex++]
} else if (!rootVisited) {
// Then visit root
rootVisited = true
return root
} else {
// That's all
onLeave?.invoke(root)
return null
}
}
}
/** Visiting in top-down order */
private inner class TopDownDirectoryState(rootDir: File) : DirectoryState(rootDir) {
private var rootVisited = false
private var fileList: Array<File>? = null
private var fileIndex = 0
/** First root directory, then all children */
override fun step(): File? {
if (!rootVisited) {
// First visit root
if (onEnter?.invoke(root) == false) {
return null
}
rootVisited = true
return root
} else if (fileList == null || fileIndex < fileList!!.size) {
if (fileList == null) {
// Then read an array of files, if any
fileList = root.listFiles()
if (fileList == null) {
onFail?.invoke(root, AccessDeniedException(file = root, reason = "Cannot list files in a directory"))
}
if (fileList == null || fileList!!.size == 0) {
onLeave?.invoke(root)
return null
}
}
// Then visit all files
return fileList!![fileIndex++]
} else {
// That's all
onLeave?.invoke(root)
return null
}
}
}
private inner class SingleFileState(rootFile: File) : WalkState(rootFile) {
private var visited: Boolean = false
init {
if (_Assertions.ENABLED)
assert(rootFile.isFile) { "rootFile must be verified to be file beforehand." }
}
override fun step(): File? {
if (visited) return null
visited = true
return root
}
}
}
/**
* Sets a predicate [function], that is called on any entered directory before its files are visited
* and before it is visited itself.
*
* If the [function] returns `false` the directory is not entered and neither it nor its files are visited.
*/
public fun onEnter(function: (File) -> Boolean): FileTreeWalk {
return FileTreeWalk(start, direction, onEnter = function, onLeave = onLeave, onFail = onFail, maxDepth = maxDepth)
}
/**
* Sets a callback [function], that is called on any left directory after its files are visited and after it is visited itself.
*/
public fun onLeave(function: (File) -> Unit): FileTreeWalk {
return FileTreeWalk(start, direction, onEnter = onEnter, onLeave = function, onFail = onFail, maxDepth = maxDepth)
}
/**
* Set a callback [function], that is called on a directory when it's impossible to get its file list.
*
* [onEnter] and [onLeave] callback functions are called even in this case.
*/
public fun onFail(function: (File, IOException) -> Unit): FileTreeWalk {
return FileTreeWalk(start, direction, onEnter = onEnter, onLeave = onLeave, onFail = function, maxDepth = maxDepth)
}
/**
* Sets the maximum [depth] of a directory tree to traverse. By default there is no limit.
*
* The value must be positive and [Int.MAX_VALUE] is used to specify an unlimited depth.
*
* With a value of 1, walker visits only the origin directory and all its immediate children,
* with a value of 2 also grandchildren, etc.
*/
public fun maxDepth(depth: Int): FileTreeWalk {
if (depth <= 0)
throw IllegalArgumentException("depth must be positive, but was $depth.")
return FileTreeWalk(start, direction, onEnter, onLeave, onFail, depth)
}
public fun foo(): Int {
return 0;
}
}
/**
* Gets a sequence for visiting this directory and all its content.
*
* @param direction walk direction, top-down (by default) or bottom-up.
*/
public fun File.walk(direction: FileWalkDirection = FileWalkDirection.TOP_DOWN): FileTreeWalk =
FileTreeWalk(this, direction)
/**
* Gets a sequence for visiting this directory and all its content in top-down order.
* Depth-first search is used and directories are visited before all their files.
*/
public fun File.walkTopDown(): FileTreeWalk = walk(FileWalkDirection.TOP_DOWN)
/**
* Gets a sequence for visiting this directory and all its content in bottom-up order.
* Depth-first search is used and directories are visited after all their files.
*/
public fun File.walkBottomUp(): FileTreeWalk = walk(FileWalkDirection.BOTTOM_UP)

View File

@@ -1,37 +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.gradle.internal
import kotlin.reflect.KProperty
abstract class ConfigurationPhaseAware<C : Any> {
private var configured: C? = null
@Synchronized
fun requireConfigured(): C {
if (configured == null) {
configured = finalizeConfiguration()
}
return configured!!
}
protected fun requireNotConfigured() {
check(configured == null) { "Configuration already finalized for previous property values" }
}
inner class Property<T>(var value: T) {
operator fun getValue(receiver: Any, property: KProperty<*>): T = value
operator fun setValue(receiver: Any, property: KProperty<*>, value: T) {
requireNotConfigured()
this.value = value
}
}
protected abstract fun finalizeConfiguration(): C
}

View File

@@ -1 +0,0 @@
libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/ConfigurationPhaseAware.kt

View File

@@ -1,39 +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.gradle.internal
import kotlin.reflect.KProperty
abstract class ConfigurationPhaseAware<C : Any> {
private var configured: C? = null
@Synchronized
fun requireConfigured(): C {
if (configured == null) {
configured = finalizeConfiguration()
}
return configured!!
}
protected fun requireNotConfigured() {
check(configured == null) { "Configuration already finalized for previous property values" }
}
inner class Property<T>(var value: T) {
operator fun getValue(receiver: Any, property: KProperty<*>): T = value
operator fun setValue(receiver: Any, property: KProperty<*>, value: T) {
requireNotConfigured()
this.value = value
}
}
protected abstract fun finalizeConfiguration(): C
}
private fun foo() {}

View File

@@ -1,39 +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.gradle.internal
import kotlin.reflect.KProperty
abstract class ConfigurationPhaseAware<C : Any> {
private var configured: C? = null
@Synchronized
fun requireConfigured(): C {
if (configured == null) {
configured = finalizeConfiguration()
}
return configured!!
}
protected fun requireNotConfigured() {
check(configured == null) { "Configuration already finalized for previous property values" }
}
inner class Property<T>(var value: T) {
operator fun getValue(receiver: Any, property: KProperty<*>): T = value
operator fun setValue(receiver: Any, property: KProperty<*>, value: T) {
requireNotConfigured()
this.value = value
}
}
protected abstract fun finalizeConfiguration(): C
}
fun foo() {}

View File

@@ -23,6 +23,9 @@ dependencies {
testCompile(commonDep("junit:junit"))
testCompile(protobufFull())
testCompile(kotlinStdlib())
Platform[193].orLower {
testCompileOnly(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
}
testRuntime(project(":kotlin-reflect"))
}

View File

@@ -40,7 +40,7 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
): T
fun create(args: CommonCompilerArguments): T {
val languageVersion = args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE
val languageVersion = args.languageVersion?.let((LanguageVersion)::fromVersionString) ?: LanguageVersion.LATEST_STABLE
return create(
isEAP = languageVersion.isPreRelease(),
@@ -51,7 +51,7 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
ownVersion = OWN_VERSION,
coroutinesVersion = COROUTINES_VERSION,
multiplatformVersion = MULTIPLATFORM_VERSION,
metadataVersionArray = args.metadataVersion?.let { BinaryVersion.parseVersionArray(it) }
metadataVersionArray = args.metadataVersion?.let((BinaryVersion)::parseVersionArray)
)
}

View File

@@ -39,4 +39,4 @@ class GeneratedJvmClass(
}
}
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"

View File

@@ -17,7 +17,6 @@ enum class BuildAttributeKind : Serializable {
enum class BuildAttribute(val kind: BuildAttributeKind) : Serializable {
NO_BUILD_HISTORY(BuildAttributeKind.REBUILD_REASON),
NO_ABI_SNAPSHOT(BuildAttributeKind.REBUILD_REASON),
CACHE_CORRUPTION(BuildAttributeKind.REBUILD_REASON),
UNKNOWN_CHANGES_IN_GRADLE_INPUTS(BuildAttributeKind.REBUILD_REASON),
JAVA_CHANGE_UNTRACKED_FILE_IS_REMOVED(BuildAttributeKind.REBUILD_REASON),

View File

@@ -9,7 +9,6 @@ import java.io.Serializable
@Suppress("Reformat")
enum class BuildTime(val parent: BuildTime? = null) : Serializable {
GRADLE_TASK_ACTION,
GRADLE_TASK,
CLEAR_OUTPUT(GRADLE_TASK),
BACKUP_OUTPUT(GRADLE_TASK),
@@ -21,10 +20,6 @@ enum class BuildTime(val parent: BuildTime? = null) : Serializable {
NON_INCREMENTAL_COMPILATION_OUT_OF_PROCESS(RUN_COMPILER),
NON_INCREMENTAL_COMPILATION_DAEMON(RUN_COMPILER),
INCREMENTAL_COMPILATION(RUN_COMPILER),
STORE_BUILD_INFO(INCREMENTAL_COMPILATION),
JAR_SNAPSHOT(INCREMENTAL_COMPILATION),
SET_UP_ABI_SNAPSHOTS(JAR_SNAPSHOT),
IC_ANALYZE_JAR_FILES(JAR_SNAPSHOT),
IC_CALCULATE_INITIAL_DIRTY_SET(INCREMENTAL_COMPILATION),
IC_ANALYZE_CHANGES_IN_DEPENDENCIES(IC_CALCULATE_INITIAL_DIRTY_SET),
IC_FIND_HISTORY_FILES(IC_ANALYZE_CHANGES_IN_DEPENDENCIES),

View File

@@ -30,28 +30,6 @@ class ChangesCollector {
private val changedMembers = hashMapOf<FqName, MutableSet<String>>()
private val areSubclassesAffected = hashMapOf<FqName, Boolean>()
//TODO for test only: ProtoData or ProtoBuf
private val storage = hashMapOf<FqName, ProtoData>()
private val removed = ArrayList<FqName>()
//TODO change to immutable map
fun protoDataChanges(): Map<FqName, ProtoData> = storage
fun protoDataRemoved(): List<FqName> = removed
companion object {
fun <T> T.getNonPrivateNames(nameResolver: NameResolver, vararg members: T.() -> List<MessageLite>) =
members.flatMap { this.it().filterNot { it.isPrivate }.names(nameResolver) }.toSet()
fun ClassProtoData.getNonPrivateMemberNames(): Set<String> {
return proto.getNonPrivateNames(
nameResolver,
ProtoBuf.Class::getConstructorList,
ProtoBuf.Class::getFunctionList,
ProtoBuf.Class::getPropertyList
) + proto.enumEntryList.map { nameResolver.getString(it.name) }
}
}
fun changes(): List<ChangeInfo> {
val changes = arrayListOf<ChangeInfo>()
@@ -79,7 +57,7 @@ class ChangesCollector {
}
private fun <T, R> MutableMap<T, MutableSet<R>>.getSet(key: T) =
getOrPut(key) { HashSet() }
getOrPut(key) { HashSet() }
private fun collectChangedMember(scope: FqName, name: String) {
changedMembers.getSet(scope).add(name)
@@ -101,35 +79,11 @@ class ChangesCollector {
}
}
fun collectProtoChanges(oldData: ProtoData?, newData: ProtoData?, collectAllMembersForNewClass: Boolean = false, packageProtoKey: String? = null) {
fun collectProtoChanges(oldData: ProtoData?, newData: ProtoData?, collectAllMembersForNewClass: Boolean = false) {
if (oldData == null && newData == null) {
throw IllegalStateException("Old and new value are null")
}
if (newData != null) {
when (newData) {
is ClassProtoData -> {
val fqName = newData.nameResolver.getClassId(newData.proto.fqName).asSingleFqName()
storage[fqName] = newData
}
is PackagePartProtoData -> {
//TODO fqName is not unique. It's package and can be present in both java and kotlin
val fqName = newData.packageFqName
storage[packageProtoKey?.let { FqName(it) } ?: fqName] = newData
}
}
} else if (oldData != null) {
when (oldData) {
is ClassProtoData -> {
removed.add(oldData.nameResolver.getClassId(oldData.proto.fqName).asSingleFqName())
}
is PackagePartProtoData -> {
//TODO fqName is not unique. It's package and can be present in both java and kotlin
removed.add(packageProtoKey?.let { FqName(it) } ?: oldData.packageFqName)
}
}
}
if (oldData == null) {
newData!!.collectAll(isRemoved = false, isAdded = true, collectAllMembersForNewClass = collectAllMembersForNewClass)
return
@@ -171,8 +125,8 @@ class ChangesCollector {
}
}
fun <T> T.getNonPrivateNames(nameResolver: NameResolver, vararg members: T.() -> List<MessageLite>) =
members.flatMap { this.it().filterNot { it.isPrivate }.names(nameResolver) }.toSet()
private fun <T> T.getNonPrivateNames(nameResolver: NameResolver, vararg members: T.() -> List<MessageLite>): Set<String> =
members.flatMap { this.it().filterNot { it.isPrivate }.names(nameResolver) }.toSet()
//TODO remember all sealed parent classes
private fun ProtoData.collectAll(isRemoved: Boolean, isAdded: Boolean, collectAllMembersForNewClass: Boolean = false) =
@@ -183,15 +137,16 @@ class ChangesCollector {
private fun PackagePartProtoData.collectAllFromPackage(isRemoved: Boolean) {
val memberNames =
proto.getNonPrivateNames(
nameResolver,
ProtoBuf.Package::getFunctionList,
ProtoBuf.Package::getPropertyList
)
proto.getNonPrivateNames(
nameResolver,
ProtoBuf.Package::getFunctionList,
ProtoBuf.Package::getPropertyList
)
if (isRemoved) {
collectRemovedMembers(packageFqName, memberNames)
} else {
}
else {
collectChangedMembers(packageFqName, memberNames)
}
}
@@ -206,7 +161,8 @@ class ChangesCollector {
val collectMember = if (isRemoved) this@ChangesCollector::collectRemovedMember else this@ChangesCollector::collectChangedMember
collectMember(classFqName.parent(), classFqName.shortName().asString())
memberNames.forEach { collectMember(classFqName, it) }
} else {
}
else {
if (!isRemoved && collectAllMembersForNewClass) {
val memberNames = getNonPrivateMemberNames()
memberNames.forEach { this@ChangesCollector.collectChangedMember(classFqName, it) }
@@ -233,6 +189,15 @@ class ChangesCollector {
addChangedParents(fqName, changedParentsFqNames)
}
private fun ClassProtoData.getNonPrivateMemberNames(): Set<String> {
return proto.getNonPrivateNames(
nameResolver,
ProtoBuf.Class::getConstructorList,
ProtoBuf.Class::getFunctionList,
ProtoBuf.Class::getPropertyList
) + proto.enumEntryList.map { nameResolver.getString(it.name) }
}
fun collectMemberIfValueWasChanged(scope: FqName, name: String, oldValue: Any?, newValue: Any?) {
if (oldValue == null && newValue == null) {
throw IllegalStateException("Old and new value are null for $scope#$name")
@@ -240,7 +205,8 @@ class ChangesCollector {
if (oldValue != null && newValue == null) {
collectRemovedMember(scope, name)
} else if (oldValue != newValue) {
}
else if (oldValue != newValue) {
collectChangedMember(scope, name)
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.name.FqName
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
/**
* Changes to the classpath of the `KotlinCompile` task, used to compute the source files that need to be recompiled during an incremental
* run.
*/
sealed class ClasspathChanges : Serializable {
class Available() : ClasspathChanges() {
lateinit var lookupSymbols: List<LookupSymbol>
private set
lateinit var fqNames: List<FqName>
private set
constructor(lookupSymbols: List<LookupSymbol>, fqNames: List<FqName>) : this() {
this.lookupSymbols = lookupSymbols
this.fqNames = fqNames
}
private fun writeObject(out: ObjectOutputStream) {
out.writeInt(lookupSymbols.size)
lookupSymbols.forEach {
out.writeUTF(it.name)
out.writeUTF(it.scope)
}
out.writeInt(fqNames.size)
fqNames.forEach {
out.writeUTF(it.asString())
}
}
private fun readObject(ois: ObjectInputStream) {
val lookupSymbolsSize = ois.readInt()
val lookupSymbols = ArrayList<LookupSymbol>(lookupSymbolsSize)
repeat(lookupSymbolsSize) {
val name = ois.readUTF()
val scope = ois.readUTF()
lookupSymbols.add(LookupSymbol(name, scope))
}
this.lookupSymbols = lookupSymbols
val fqNamesSize = ois.readInt()
val fqNames = ArrayList<FqName>(fqNamesSize)
repeat(fqNamesSize) {
val fqNameString = ois.readUTF()
fqNames.add(FqName(fqNameString))
}
this.fqNames = fqNames
}
companion object {
private const val serialVersionUID = 0L
}
}
sealed class NotAvailable : ClasspathChanges() {
object UnableToCompute : NotAvailable()
object ForNonIncrementalRun : NotAvailable()
object ClasspathSnapshotIsDisabled : NotAvailable()
object ReservedForTestsOnly : NotAvailable()
object ForJSCompiler : NotAvailable()
}
}

View File

@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.incremental
import com.intellij.util.io.DataExternalizer
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.incremental.js.IrTranslationResultValue
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
@@ -49,7 +48,6 @@ open class IncrementalJsCache(
private const val INLINE_FUNCTIONS = "inline-functions"
private const val HEADER_FILE_NAME = "header.meta"
private const val PACKAGE_META_FILE = "packages-meta"
private const val SOURCE_TO_JS_OUTPUT = "source-to-js-output"
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
}
@@ -62,7 +60,6 @@ open class IncrementalJsCache(
private val irTranslationResults = registerMap(IrTranslationResultMap(IR_TRANSLATION_RESULT_MAP.storageFile, pathConverter))
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter))
private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile))
private val sourceToJsOutputsMap = registerMap(SourceToJsOutputMap(SOURCE_TO_JS_OUTPUT.storageFile, pathConverter))
private val dirtySources = hashSetOf<File>()
@@ -78,7 +75,6 @@ open class IncrementalJsCache(
override fun markDirty(removedAndCompiledSources: Collection<File>) {
removedAndCompiledSources.forEach { sourceFile ->
sourceToJsOutputsMap.remove(sourceFile)
// The common prefix of all FQN parents has to be the file package
sourceToClassesMap[sourceFile].map { it.parentOrNull()?.asString() ?: "" }.minByOrNull { it.length }?.let {
packageMetadata.remove(it)
@@ -99,10 +95,6 @@ open class IncrementalJsCache(
}
}
fun getOutputsBySource(sourceFile: File): Collection<File> {
return sourceToJsOutputsMap.get(sourceFile)
}
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
val translatedFiles = incrementalResults.packageParts
@@ -137,8 +129,8 @@ open class IncrementalJsCache(
}
for ((srcFile, irData) in incrementalResults.irFileData) {
val (fileData, types, signatures, strings, declarations, bodies, fqn, debugInfos) = irData
irTranslationResults.put(srcFile, fileData, types, signatures, strings, declarations, bodies, fqn, debugInfos)
val (fileData, types, signatures, strings, declarations, bodies, fqn) = irData
irTranslationResults.put(srcFile, fileData, types, signatures, strings, declarations, bodies, fqn)
}
}
@@ -183,17 +175,6 @@ open class IncrementalJsCache(
}
}
}
fun updateSourceToOutputMap(
generatedFiles: Iterable<GeneratedFile>,
) {
for (generatedFile in generatedFiles) {
for (source in generatedFile.sourceFiles) {
if (dirtySources.contains(source))
sourceToJsOutputsMap.add(source, generatedFile.outputFile)
}
}
}
}
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
@@ -234,20 +215,17 @@ private class TranslationResultMap(
override fun dumpValue(value: TranslationResultValue): String =
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
@Synchronized
fun put(sourceFile: File, newMetadata: ByteArray, newBinaryAst: ByteArray, newInlineData: ByteArray) {
storage[pathConverter.toPath(sourceFile)] =
TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst, inlineData = newInlineData)
}
@Synchronized
operator fun get(sourceFile: File): TranslationResultValue? =
storage[pathConverter.toPath(sourceFile)]
fun keys(): Collection<File> =
storage.keys.map { pathConverter.toFile(it) }
@Synchronized
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
val path = pathConverter.toPath(sourceFile)
val protoBytes = storage[path]!!.metadata
@@ -269,7 +247,6 @@ private object IrTranslationResultValueExternalizer : DataExternalizer<IrTransla
output.writeArray(value.declarations)
output.writeArray(value.bodies)
output.writeArray(value.fqn)
value.debugInfo?.let { output.writeArray(it) }
}
private fun DataOutput.writeArray(array: ByteArray) {
@@ -284,17 +261,6 @@ private object IrTranslationResultValueExternalizer : DataExternalizer<IrTransla
return filedata
}
private fun DataInput.readArrayOrNull(): ByteArray? {
try {
val dataSize = readInt()
val filedata = ByteArray(dataSize)
readFully(filedata)
return filedata
} catch (e: Throwable) {
return null
}
}
override fun read(input: DataInput): IrTranslationResultValue {
val fileData = input.readArray()
val types = input.readArray()
@@ -303,9 +269,8 @@ private object IrTranslationResultValueExternalizer : DataExternalizer<IrTransla
val declarations = input.readArray()
val bodies = input.readArray()
val fqn = input.readArray()
val debugInfos = input.readArrayOrNull()
return IrTranslationResultValue(fileData, types, signatures, strings, declarations, bodies, fqn, debugInfos)
return IrTranslationResultValue(fileData, types, signatures, strings, declarations, bodies, fqn)
}
}
@@ -330,11 +295,10 @@ private class IrTranslationResultMap(
newStrings: ByteArray,
newDeclarations: ByteArray,
newBodies: ByteArray,
fqn: ByteArray,
debugInfos: ByteArray?
fqn: ByteArray
) {
storage[pathConverter.toPath(sourceFile)] =
IrTranslationResultValue(newFiledata, newTypes, newSignatures, newStrings, newDeclarations, newBodies, fqn, debugInfos)
IrTranslationResultValue(newFiledata, newTypes, newSignatures, newStrings, newDeclarations, newBodies, fqn)
}
operator fun get(sourceFile: File): IrTranslationResultValue? =
@@ -395,7 +359,6 @@ private class InlineFunctionsMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
@Synchronized
fun process(srcFile: File, newMap: Map<String, Long>, changesCollector: ChangesCollector) {
val key = pathConverter.toPath(srcFile)
val oldMap = storage[key] ?: emptyMap()
@@ -413,7 +376,6 @@ private class InlineFunctionsMap(
}
}
@Synchronized
fun remove(sourceFile: File) {
storage.remove(pathConverter.toPath(sourceFile))
}

View File

@@ -39,11 +39,12 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.*
import java.io.File
import java.security.MessageDigest
import java.util.*
val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
targetDataRoot: File,
private val targetDataRoot: File,
targetOutputDir: File?,
pathConverter: FileToPathConverter
) : AbstractIncrementalCache<JvmClassName>(
@@ -113,43 +114,32 @@ open class IncrementalJvmCache(
}
open fun saveFileToCache(generatedClass: GeneratedJvmClass, changesCollector: ChangesCollector) {
saveClassToCache(KotlinClassInfo(generatedClass.outputClass), generatedClass.sourceFiles, changesCollector)
}
/**
* Saves information about the given (kotlinc-generated) class to this cache, and stores changes between this class and its previous
* version into the given [ChangesCollector].
*
* @param kotlinClassInfo A kotlin-generated class
* @param sourceFiles The source files that the given class was generated from, or `null` if this information is not available
* @param changesCollector A [ChangesCollector]
*/
fun saveClassToCache(kotlinClassInfo: KotlinClassInfo, sourceFiles: List<File>?, changesCollector: ChangesCollector) {
val className = kotlinClassInfo.className
val sourceFiles: Collection<File> = generatedClass.sourceFiles
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
val className = kotlinClass.className
dirtyOutputClassesMap.notDirty(className)
sourceFiles?.forEach {
sourceFiles.forEach {
sourceToClassesMap.add(it, className)
}
sourceFiles?.let { internalNameToSource[className.internalName] = it }
internalNameToSource[className.internalName] = sourceFiles
if (kotlinClassInfo.classId.isLocal) return
if (kotlinClass.classId.isLocal) return
when (kotlinClassInfo.classKind) {
val header = kotlinClass.classHeader
when (header.kind) {
KotlinClassHeader.Kind.FILE_FACADE -> {
if (sourceFiles != null) {
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
}
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
packagePartMap.addPackagePart(className)
protoMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
protoMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
}
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
val partNames = kotlinClassInfo.classHeaderData?.toList()
?: throw AssertionError("Multifile class has no parts: $className")
val partNames = kotlinClass.classHeader.data?.toList()
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
multifileFacadeToParts[className] = partNames
// When a class is replaced with a facade with the same name,
// the class' proto wouldn't ever be deleted,
@@ -164,29 +154,25 @@ open class IncrementalJvmCache(
internalNameToSource.remove(className.internalName)
// TODO NO_CHANGES? (delegates only)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
}
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
if (sourceFiles != null) {
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
}
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
packagePartMap.addPackagePart(className)
partToMultifileFacade.set(className.internalName, kotlinClassInfo.multifileClassName!!)
partToMultifileFacade.set(className.internalName, header.multifileClassName!!)
protoMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
protoMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
}
KotlinClassHeader.Kind.CLASS -> {
if (sourceFiles != null) {
assert(sourceFiles.size == 1) { "Class is expected to have only one source file: $sourceFiles" }
addToClassStorage(kotlinClassInfo, sourceFiles.first())
}
assert(sourceFiles.size == 1) { "Class is expected to have only one source file: $sourceFiles" }
addToClassStorage(kotlinClass, sourceFiles.first())
protoMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
protoMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
}
KotlinClassHeader.Kind.UNKNOWN, KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
}
@@ -199,7 +185,7 @@ open class IncrementalJvmCache(
sourceToClassesMap.add(source, jvmClassName)
val (proto, nameResolver) = serializedJavaClass.toProtoData()
addToClassStorage(proto, nameResolver, source)
// collector.addJavaProto(ClassProtoData(proto, nameResolver))
dirtyOutputClassesMap.notDirty(jvmClassName)
}
@@ -292,8 +278,8 @@ open class IncrementalJvmCache(
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
@Synchronized
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
return put(kotlinClassInfo, changesCollector)
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
return put(kotlinClass, changesCollector)
}
// A module mapping (.kotlin_module file) is stored in a cache,
@@ -309,18 +295,20 @@ open class IncrementalJvmCache(
}
@Synchronized
private fun put(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
val key = kotlinClassInfo.className.internalName
private fun put(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val header = kotlinClass.classHeader
val key = kotlinClass.className.internalName
val oldData = storage[key]
val newData = ProtoMapValue(
kotlinClassInfo.classKind != KotlinClassHeader.Kind.CLASS,
BitEncoding.decodeBytes(kotlinClassInfo.classHeaderData!!),
kotlinClassInfo.classHeaderStrings!!
header.kind != KotlinClassHeader.Kind.CLASS,
BitEncoding.decodeBytes(header.data!!),
header.strings!!
)
storage[key] = newData
val packageFqName = kotlinClassInfo.className.packageFqName
changesCollector.collectProtoChanges(oldData?.toProtoData(packageFqName), newData.toProtoData(packageFqName), packageProtoKey = key)
val packageFqName = kotlinClass.className.packageFqName
changesCollector.collectProtoChanges(oldData?.toProtoData(packageFqName), newData.toProtoData(packageFqName))
}
operator fun contains(className: JvmClassName): Boolean =
@@ -380,16 +368,31 @@ open class IncrementalJvmCache(
// todo: reuse code with InlineFunctionsMap?
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
private fun getConstantsMap(bytes: ByteArray): Map<String, Any> {
val result = HashMap<String, Any>()
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
val staticFinal = Opcodes.ACC_STATIC or Opcodes.ACC_FINAL or Opcodes.ACC_PRIVATE
if (value != null && access and staticFinal == Opcodes.ACC_STATIC or Opcodes.ACC_FINAL) {
result[name] = value
}
return null
}
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return result
}
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
@Synchronized
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
val key = kotlinClassInfo.className.internalName
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
val oldMap = storage[key] ?: emptyMap()
val newMap = kotlinClassInfo.constantsMap
val newMap = getConstantsMap(kotlinClass.fileContents)
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
@@ -398,18 +401,8 @@ open class IncrementalJvmCache(
for (const in oldMap.keys + newMap.keys) {
//Constant can be declared via companion object or via const field declaration
changesCollector.collectMemberIfValueWasChanged(
kotlinClassInfo.scopeFqName(companion = true),
const,
oldMap[const],
newMap[const]
)
changesCollector.collectMemberIfValueWasChanged(
kotlinClassInfo.scopeFqName(companion = false),
const,
oldMap[const],
newMap[const]
)
changesCollector.collectMemberIfValueWasChanged(kotlinClass.scopeFqName(companion = true), const, oldMap[const], newMap[const])
changesCollector.collectMemberIfValueWasChanged(kotlinClass.scopeFqName(companion = false), const, oldMap[const], newMap[const])
}
}
@@ -497,20 +490,67 @@ open class IncrementalJvmCache(
value.dumpCollection()
}
private fun addToClassStorage(classInfo: KotlinClassInfo, srcFile: File) {
val (nameResolver, proto) = JvmProtoBufUtil.readClassDataFrom(classInfo.classHeaderData!!, classInfo.classHeaderStrings!!)
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) {
val (nameResolver, proto) = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!)
addToClassStorage(proto, nameResolver, srcFile)
}
private inner class InlineFunctionsMap(storageFile: File) :
BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)
if (inlineFunctions.isEmpty()) return emptyMap()
val result = HashMap<String, Long>()
var dummyVersion: Int = -1
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
dummyVersion = version
}
override fun visitMethod(
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor? {
val dummyClassWriter = ClassWriter(0)
dummyClassWriter.visit(dummyVersion, 0, "dummy", null, AsmTypes.OBJECT_TYPE.internalName, null)
return object : MethodVisitor(Opcodes.API_VERSION, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
override fun visitEnd() {
val jvmName = name + desc
if (jvmName !in inlineFunctions) return
val dummyBytes = dummyClassWriter.toByteArray()!!
val hash = dummyBytes.md5()
result[jvmName] = hash
}
}
}
}, 0)
return result
}
@Synchronized
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
val key = kotlinClassInfo.className.internalName
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
val oldMap = storage[key] ?: emptyMap()
val newMap = kotlinClassInfo.inlineFunctionsMap
val newMap = getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents)
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
@@ -519,7 +559,7 @@ open class IncrementalJvmCache(
for (fn in oldMap.keys + newMap.keys) {
changesCollector.collectMemberIfValueWasChanged(
kotlinClassInfo.scopeFqName(),
kotlinClass.scopeFqName(),
functionNameBySignature(fn),
oldMap[fn],
newMap[fn]
@@ -562,6 +602,13 @@ sealed class ChangeInfo(val fqName: FqName) {
}
}
private fun LocalFileKotlinClass.scopeFqName(companion: Boolean = false) = when (classHeader.kind) {
KotlinClassHeader.Kind.CLASS -> {
className.fqNameForClassNameWithoutDollars.let { if (companion) it.child(DEFAULT_NAME_FOR_COMPANION_OBJECT) else it }
}
else -> className.packageFqName
}
fun ByteArray.md5(): Long {
val d = MessageDigest.getInstance("MD5").digest(this)!!
return ((d[0].toLong() and 0xFFL)
@@ -593,105 +640,3 @@ fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V) -> String): String =
@TestOnly
fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
"[${sorted().joinToString(", ", transform = Any::toString)}]"
/**
* Minimal information about a kotlinc-generated class that will be used to compute recompilation-triggered changes to support incremental
* compilation (see [IncrementalJvmCache.saveClassToCache]).
*
* It's important that this class contain only the minimal required information, as it will be part of the classpath snapshot of the
* `KotlinCompile` task and the task needs to support compile avoidance. For example, this class should contain public method signatures,
* and should not contain private method signatures, or method implementations.
*/
class KotlinClassInfo private constructor(
val classId: ClassId,
val classKind: KotlinClassHeader.Kind,
val classHeaderData: Array<String>?,
val classHeaderStrings: Array<String>?,
@Suppress("SpellCheckingInspection") val multifileClassName: String?,
val constantsMap: LinkedHashMap<String, Any>,
val inlineFunctionsMap: LinkedHashMap<String, Long>
) {
constructor(kotlinClass: LocalFileKotlinClass) : this(
kotlinClass.classId,
kotlinClass.classHeader.kind,
kotlinClass.classHeader.data,
kotlinClass.classHeader.strings,
kotlinClass.classHeader.multifileClassName,
getConstantsMap(kotlinClass.fileContents),
getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents)
)
val className: JvmClassName by lazy { JvmClassName.byClassId(classId) }
fun scopeFqName(companion: Boolean = false) = when (classKind) {
KotlinClassHeader.Kind.CLASS -> {
className.fqNameForClassNameWithoutDollars.let { if (companion) it.child(DEFAULT_NAME_FOR_COMPANION_OBJECT) else it }
}
else -> className.packageFqName
}
}
private fun getConstantsMap(bytes: ByteArray): LinkedHashMap<String, Any> {
val result = LinkedHashMap<String, Any>()
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
val staticFinal = Opcodes.ACC_STATIC or Opcodes.ACC_FINAL or Opcodes.ACC_PRIVATE
if (value != null && access and staticFinal == Opcodes.ACC_STATIC or Opcodes.ACC_FINAL) {
result[name] = value
}
return null
}
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return result
}
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): LinkedHashMap<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)
if (inlineFunctions.isEmpty()) return LinkedHashMap()
val result = LinkedHashMap<String, Long>()
var dummyVersion: Int = -1
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
dummyVersion = version
}
override fun visitMethod(
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor {
val dummyClassWriter = ClassWriter(0)
dummyClassWriter.visit(dummyVersion, 0, "dummy", null, AsmTypes.OBJECT_TYPE.internalName, null)
return object : MethodVisitor(Opcodes.API_VERSION, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
override fun visitEnd() {
val jvmName = name + desc
if (jvmName !in inlineFunctions) return
val dummyBytes = dummyClassWriter.toByteArray()!!
val hash = dummyBytes.md5()
result[jvmName] = hash
}
}
}
}, 0)
return result
}

View File

@@ -12,8 +12,7 @@ data class IncrementalModuleEntry(
private val projectPath: String,
val name: String,
val buildDir: File,
val buildHistoryFile: File,
val abiSnapshot: File
val buildHistoryFile: File
) : Serializable {
companion object {
private const val serialVersionUID = 0L
@@ -27,9 +26,7 @@ class IncrementalModuleInfo(
val nameToModules: Map<String, Set<IncrementalModuleEntry>>,
val jarToClassListFile: Map<File, File>,
// only for js and mpp
val jarToModule: Map<File, IncrementalModuleEntry>,
//for JVM only
val jarToAbiSnapshot: Map<File, File>
val jarToModule: Map<File, IncrementalModuleEntry>
) : Serializable {
companion object {
private const val serialVersionUID = 1L

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.incremental
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.containers.MultiMap
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -34,8 +33,6 @@ open class LookupStorage(
targetDataDir: File,
pathConverter: FileToPathConverter
) : BasicMapsOwner(targetDataDir) {
val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder")
companion object {
private val DELETED_TO_SIZE_TRESHOLD = 0.5
private val MINIMUM_GARBAGE_COLLECTIBLE_SIZE = 10000
@@ -44,44 +41,36 @@ open class LookupStorage(
private val countersFile = "counters".storageFile
private val idToFile = registerMap(IdToFileMap("id-to-file".storageFile, pathConverter))
private val fileToId = registerMap(FileToIdMap("file-to-id".storageFile, pathConverter))
val lookupMap = registerMap(LookupMap("lookups".storageFile))
private val lookupMap = registerMap(LookupMap("lookups".storageFile))
@Volatile
private var size: Int = 0
@Volatile
private var deletedCount: Int = 0
init {
try {
if (countersFile.exists()) {
val lines = countersFile.readLines()
size = lines[0].toInt()
deletedCount = lines[1].toInt()
}
} catch (e: Exception) {
throw IOException("Could not read $countersFile", e)
}
}
@Synchronized
fun get(lookupSymbol: LookupSymbol): Collection<String> {
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
val fileIds = lookupMap[key] ?: return emptySet()
val paths = mutableSetOf<String>()
val filtered = mutableSetOf<Int>()
for (fileId in fileIds) {
val path = idToFile[fileId]?.path
if (path != null) {
paths.add(path)
filtered.add(fileId)
}
return fileIds.mapNotNull {
// null means it's outdated
idToFile[it]?.path
}
if (size > MINIMUM_GARBAGE_COLLECTIBLE_SIZE && filtered.size.toDouble() / fileIds.size.toDouble() < DELETED_TO_SIZE_TRESHOLD) {
lookupMap[key] = filtered
}
return paths
}
@Synchronized
@@ -92,8 +81,8 @@ open class LookupStorage(
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
val paths = lookups[lookupSymbol]
val fileIds = paths.mapTo(TreeSet()) { pathToId[it]!! }
lookupMap.append(key, fileIds)
fileIds.addAll(lookupMap[key] ?: emptySet())
lookupMap[key] = fileIds
}
}
@@ -103,6 +92,7 @@ open class LookupStorage(
val id = fileToId[file] ?: continue
idToFile.remove(id)
fileToId.remove(file)
deletedCount++
}
}
@@ -113,6 +103,7 @@ open class LookupStorage(
}
size = 0
deletedCount = 0
super.clean()
}
@@ -120,15 +111,18 @@ open class LookupStorage(
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
try {
removeGarbageIfNeeded()
if (size > 0) {
if (!countersFile.exists()) {
countersFile.parentFile.mkdirs()
countersFile.createNewFile()
}
countersFile.writeText("$size\n0")
countersFile.writeText("$size\n$deletedCount")
}
} finally {
}
finally {
super.flush(memoryCachesOnly)
}
}
@@ -143,7 +137,13 @@ open class LookupStorage(
return id
}
private fun removeGarbageForTests() {
private fun removeGarbageIfNeeded(force: Boolean = false) {
if (force || (size > MINIMUM_GARBAGE_COLLECTIBLE_SIZE && deletedCount.toDouble() / size > DELETED_TO_SIZE_TRESHOLD)) {
doRemoveGarbage()
}
}
private fun doRemoveGarbage() {
for (hash in lookupMap.keys) {
lookupMap[hash] = lookupMap[hash]!!.filter { it in idToFile }.toSet()
}
@@ -153,6 +153,7 @@ open class LookupStorage(
idToFile.clean()
fileToId.clean()
size = 0
deletedCount = 0
for ((file, oldId) in oldFileToId.entries.sortedBy { it.key.path }) {
val newId = addFileIfNeeded(file)
@@ -164,16 +165,15 @@ open class LookupStorage(
if (fileIds.isEmpty()) {
lookupMap.remove(lookup)
} else {
}
else {
lookupMap[lookup] = fileIds
}
}
}
@TestOnly
fun forceGC() {
removeGarbageForTests()
@TestOnly fun forceGC() {
removeGarbageIfNeeded(force = true)
flush(false)
}

View File

@@ -1104,11 +1104,6 @@ open class ProtoCompareGenerated(
if (!checkEquals(old.setter, new.setter)) return false
}
if (old.hasDelegateMethod() != new.hasDelegateMethod()) return false
if (old.hasDelegateMethod()) {
if (!checkEquals(old.delegateMethod, new.delegateMethod)) return false
}
return true
}
@@ -2358,10 +2353,6 @@ fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int, fqNam
hashCode = 31 * hashCode + setter.hashCode(stringIndexes, fqNameIndexes, typeById)
}
if (hasDelegateMethod()) {
hashCode = 31 * hashCode + delegateMethod.hashCode(stringIndexes, fqNameIndexes, typeById)
}
return hashCode
}

View File

@@ -255,23 +255,22 @@ fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
): Set<FqName> {
val typesToProccess = LinkedHashSet(listOf(typeFqName))
val proccessedTypes = hashSetOf<FqName>()
val types = LinkedHashSet(listOf(typeFqName))
val subtypes = hashSetOf<FqName>()
while (typesToProccess.isNotEmpty()) {
val iterator = typesToProccess.iterator()
while (types.isNotEmpty()) {
val iterator = types.iterator()
val unprocessedType = iterator.next()
iterator.remove()
caches.asSequence()
.flatMap { it.getSubtypesOf(unprocessedType) }
.filter { it !in proccessedTypes }
.forEach { typesToProccess.add(it) }
.filter { it !in subtypes }
.forEach { types.add(it) }
proccessedTypes.add(unprocessedType)
subtypes.add(unprocessedType)
}
return proccessedTypes
return subtypes
}

View File

@@ -47,16 +47,10 @@ abstract class BasicMap<K : Comparable<K>, V>(
storage.flush(memoryCachesOnly)
}
// avoid unsynchronized close
fun close() {
storage.close()
}
@TestOnly
fun closeForTest() {
close()
}
@TestOnly
fun dump(): String {
return with(StringBuilder()) {

View File

@@ -34,6 +34,7 @@ class CachingLazyStorage<K, V>(
) : LazyStorage<K, V> {
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
@@ -45,36 +46,32 @@ class CachingLazyStorage<K, V>(
return null
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
@Synchronized
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
@Synchronized
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
@Synchronized
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
@Synchronized
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
@Synchronized
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
@Synchronized
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendData(key, { valueExternalizer.save(it, value) })
}
@@ -106,11 +103,7 @@ class CachingLazyStorage<K, V>(
@Synchronized
override fun close() {
try {
storage?.close()
} finally {
storage = null
}
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> = PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)

View File

@@ -28,7 +28,6 @@ internal open class ClassOneToManyMap(storageFile: File) : BasicStringMap<Collec
storage.append(key.asString(), listOf(value.asString()))
}
@Synchronized
operator fun get(key: FqName): Collection<FqName> =
storage[key.asString()]?.map(::FqName) ?: setOf()

View File

@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.incremental.storage
import java.io.File
class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(storage, LookupSymbolKeyDescriptor, IntCollectionExternalizer) {
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()
@@ -27,10 +27,6 @@ class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(stor
storage.append(LookupSymbolKey(name, scope), listOf(fileId))
}
fun append(lookup: LookupSymbolKey, fileIds: Collection<Int>) {
storage.append(lookup, fileIds)
}
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {

View File

@@ -31,6 +31,7 @@ class NonCachingLazyStorage<K, V>(
) : LazyStorage<K, V> {
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
@@ -42,6 +43,7 @@ class NonCachingLazyStorage<K, V>(
return null
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
@@ -51,28 +53,22 @@ class NonCachingLazyStorage<K, V>(
}
override val keys: Collection<K>
@Synchronized
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
@Synchronized
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
@Synchronized
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
@Synchronized
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
@Synchronized
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
@Synchronized
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
}
@@ -104,11 +100,7 @@ class NonCachingLazyStorage<K, V>(
@Synchronized
override fun close() {
try {
storage?.close()
} finally {
storage = null
}
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> =

View File

@@ -1,43 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import java.io.File
class SourceToJsOutputMap(storageFile: File, private val pathConverter: FileToPathConverter) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
@Synchronized
fun add(key: File, value: File) {
storage.append(pathConverter.toPath(key), listOf(pathConverter.toPath(value)))
}
operator fun get(sourceFile: File): Collection<File> =
storage[pathConverter.toPath(sourceFile)]?.map { pathConverter.toFile(it) } ?: setOf()
@Synchronized
operator fun set(key: File, values: Collection<File>) {
if (values.isEmpty()) {
remove(key)
return
}
storage[pathConverter.toPath(key)] = values.map { pathConverter.toPath(it) }
}
@Synchronized
fun remove(key: File) {
storage.remove(pathConverter.toPath(key))
}
@Synchronized
fun removeValues(key: File, removed: Set<File>) {
val notRemoved = this[key].filter { it !in removed }
this[key] = notRemoved
}
}

View File

@@ -21,49 +21,23 @@ import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.EnumeratorStringDescriptor
import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.cli.common.toBooleanLenient
import java.io.DataInput
import java.io.DataInputStream
import java.io.DataOutput
import java.io.File
import java.util.*
/**
* Storage versioning:
* 0 - only name and value hashes are saved
* 1 - name and scope are saved
*/
object LookupSymbolKeyDescriptor : KeyDescriptor<LookupSymbolKey> {
override fun read(input: DataInput): LookupSymbolKey {
val version = input.readByte()
return when (version.toInt()) {
0 -> {
val name = input.readUTF()
val scope = input.readUTF()
LookupSymbolKey(name.hashCode(), scope.hashCode(), name, scope)
}
1 -> {
val first = input.readInt()
val second = input.readInt()
LookupSymbolKey(first, second, "", "")
}
else -> throw RuntimeException("Unknown version of LookupSymbolKeyDescriptor=${version}")
}
val first = input.readInt()
val second = input.readInt()
return LookupSymbolKey(first, second)
}
private val storeFullFqName = CompilerSystemProperties.COMPILE_INCREMENTAL_WITH_CLASSPATH_SHAPSHOTS.value.toBooleanLenient() ?: false
override fun save(output: DataOutput, value: LookupSymbolKey) {
if (storeFullFqName) {
output.writeByte(0)
output.writeUTF(value.name)
output.writeUTF(value.scope)
} else {
output.writeByte(1)
output.writeInt(value.nameHash)
output.writeInt(value.scopeHash)
}
output.writeInt(value.nameHash)
output.writeInt(value.scopeHash)
}
override fun getHashCode(value: LookupSymbolKey): Int = value.hashCode()

View File

@@ -16,8 +16,8 @@
package org.jetbrains.kotlin.incremental.storage
data class LookupSymbolKey(val nameHash: Int, val scopeHash: Int, val name:String, val scope:String) : Comparable<LookupSymbolKey> {
constructor(name: String, scope: String) : this(name.hashCode(), scope.hashCode(), name, scope)
data class LookupSymbolKey(val nameHash: Int, val scopeHash: Int) : Comparable<LookupSymbolKey> {
constructor(name: String, scope: String) : this(name.hashCode(), scope.hashCode())
override fun compareTo(other: LookupSymbolKey): Int {
val nameCmp = nameHash.compareTo(other.nameHash)
@@ -26,26 +26,6 @@ data class LookupSymbolKey(val nameHash: Int, val scopeHash: Int, val name:Strin
return scopeHash.compareTo(other.scopeHash)
}
override fun hashCode(): Int {
var result = nameHash
result = 31 * result + scopeHash
return result
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as LookupSymbolKey
if (nameHash != other.nameHash) return false
if (scopeHash != other.scopeHash) return false
return true
}
}
data class ProtoMapValue(val isPackageFacade: Boolean, val bytes: ByteArray, val strings: Array<String>)

View File

@@ -3443,34 +3443,6 @@ public final class DebugJvmProtoBuf {
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature setter = 4;</code>
*/
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getSetterOrBuilder();
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
boolean hasDelegateMethod();
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature getDelegateMethod();
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getDelegateMethodOrBuilder();
}
/**
* Protobuf type {@code org.jetbrains.kotlin.metadata.jvm.JvmPropertySignature}
@@ -3576,19 +3548,6 @@ public final class DebugJvmProtoBuf {
bitField0_ |= 0x00000008;
break;
}
case 42: {
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder subBuilder = null;
if (((bitField0_ & 0x00000010) == 0x00000010)) {
subBuilder = delegateMethod_.toBuilder();
}
delegateMethod_ = input.readMessage(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(delegateMethod_);
delegateMethod_ = subBuilder.buildPartial();
}
bitField0_ |= 0x00000010;
break;
}
}
}
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
@@ -3725,48 +3684,11 @@ public final class DebugJvmProtoBuf {
return setter_;
}
public static final int DELEGATE_METHOD_FIELD_NUMBER = 5;
private org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature delegateMethod_;
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public boolean hasDelegateMethod() {
return ((bitField0_ & 0x00000010) == 0x00000010);
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature getDelegateMethod() {
return delegateMethod_;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getDelegateMethodOrBuilder() {
return delegateMethod_;
}
private void initFields() {
field_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmFieldSignature.getDefaultInstance();
syntheticMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
getter_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
setter_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -3793,9 +3715,6 @@ public final class DebugJvmProtoBuf {
if (((bitField0_ & 0x00000008) == 0x00000008)) {
output.writeMessage(4, setter_);
}
if (((bitField0_ & 0x00000010) == 0x00000010)) {
output.writeMessage(5, delegateMethod_);
}
getUnknownFields().writeTo(output);
}
@@ -3821,10 +3740,6 @@ public final class DebugJvmProtoBuf {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(4, setter_);
}
if (((bitField0_ & 0x00000010) == 0x00000010)) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(5, delegateMethod_);
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -3938,7 +3853,6 @@ public final class DebugJvmProtoBuf {
getSyntheticMethodFieldBuilder();
getGetterFieldBuilder();
getSetterFieldBuilder();
getDelegateMethodFieldBuilder();
}
}
private static Builder create() {
@@ -3971,12 +3885,6 @@ public final class DebugJvmProtoBuf {
setterBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000008);
if (delegateMethodBuilder_ == null) {
delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
} else {
delegateMethodBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000010);
return this;
}
@@ -4037,14 +3945,6 @@ public final class DebugJvmProtoBuf {
} else {
result.setter_ = setterBuilder_.build();
}
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
to_bitField0_ |= 0x00000010;
}
if (delegateMethodBuilder_ == null) {
result.delegateMethod_ = delegateMethod_;
} else {
result.delegateMethod_ = delegateMethodBuilder_.build();
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -4073,9 +3973,6 @@ public final class DebugJvmProtoBuf {
if (other.hasSetter()) {
mergeSetter(other.getSetter());
}
if (other.hasDelegateMethod()) {
mergeDelegateMethod(other.getDelegateMethod());
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -4603,167 +4500,6 @@ public final class DebugJvmProtoBuf {
return setterBuilder_;
}
private org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder> delegateMethodBuilder_;
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public boolean hasDelegateMethod() {
return ((bitField0_ & 0x00000010) == 0x00000010);
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature getDelegateMethod() {
if (delegateMethodBuilder_ == null) {
return delegateMethod_;
} else {
return delegateMethodBuilder_.getMessage();
}
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder setDelegateMethod(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature value) {
if (delegateMethodBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
delegateMethod_ = value;
onChanged();
} else {
delegateMethodBuilder_.setMessage(value);
}
bitField0_ |= 0x00000010;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder setDelegateMethod(
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder builderForValue) {
if (delegateMethodBuilder_ == null) {
delegateMethod_ = builderForValue.build();
onChanged();
} else {
delegateMethodBuilder_.setMessage(builderForValue.build());
}
bitField0_ |= 0x00000010;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder mergeDelegateMethod(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature value) {
if (delegateMethodBuilder_ == null) {
if (((bitField0_ & 0x00000010) == 0x00000010) &&
delegateMethod_ != org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance()) {
delegateMethod_ =
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.newBuilder(delegateMethod_).mergeFrom(value).buildPartial();
} else {
delegateMethod_ = value;
}
onChanged();
} else {
delegateMethodBuilder_.mergeFrom(value);
}
bitField0_ |= 0x00000010;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder clearDelegateMethod() {
if (delegateMethodBuilder_ == null) {
delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
onChanged();
} else {
delegateMethodBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000010);
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder getDelegateMethodBuilder() {
bitField0_ |= 0x00000010;
onChanged();
return getDelegateMethodFieldBuilder().getBuilder();
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getDelegateMethodOrBuilder() {
if (delegateMethodBuilder_ != null) {
return delegateMethodBuilder_.getMessageOrBuilder();
} else {
return delegateMethod_;
}
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder>
getDelegateMethodFieldBuilder() {
if (delegateMethodBuilder_ == null) {
delegateMethodBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder>(
getDelegateMethod(),
getParentForChildren(),
isClean());
delegateMethod_ = null;
}
return delegateMethodBuilder_;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.metadata.jvm.JvmPropertySignature)
}
@@ -5004,7 +4740,7 @@ public final class DebugJvmProtoBuf {
"\020DESC_TO_CLASS_ID\020\002\"<\n\022JvmMethodSignatur" +
"e\022\022\n\004name\030\001 \001(\005B\004\230\265\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030" +
"\001\";\n\021JvmFieldSignature\022\022\n\004name\030\001 \001(\005B\004\230\265" +
"\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030\001\"\212\003\n\024JvmPropertySi" +
"\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030\001\"\272\002\n\024JvmPropertySi" +
"gnature\022C\n\005field\030\001 \001(\01324.org.jetbrains.k" +
"otlin.metadata.jvm.JvmFieldSignature\022O\n\020",
"synthetic_method\030\002 \001(\01325.org.jetbrains.k" +
@@ -5012,13 +4748,11 @@ public final class DebugJvmProtoBuf {
"\006getter\030\003 \001(\01325.org.jetbrains.kotlin.met" +
"adata.jvm.JvmMethodSignature\022E\n\006setter\030\004" +
" \001(\01325.org.jetbrains.kotlin.metadata.jvm" +
".JvmMethodSignature\022N\n\017delegate_method\030\005" +
" \001(\01325.org.jetbrains.kotlin.metadata.jvm" +
".JvmMethodSignature:\200\001\n\025constructor_sign" +
"ature\022*.org.jetbrains.kotlin.metadata.Co" +
"nstructor\030d \001(\01325.org.jetbrains.kotlin.m",
"nstructor\030d \001(\01325.org.jetbrains.kotlin.m" +
"etadata.jvm.JvmMethodSignature:x\n\020method" +
"_signature\022\'.org.jetbrains.kotlin.metada" +
"_signature\022\'.org.jetbrains.kotlin.metada",
"ta.Function\030d \001(\01325.org.jetbrains.kotlin" +
".metadata.jvm.JvmMethodSignature:O\n\030lamb" +
"da_class_origin_name\022\'.org.jetbrains.kot" +
@@ -5026,9 +4760,9 @@ public final class DebugJvmProtoBuf {
"perty_signature\022\'.org.jetbrains.kotlin.m" +
"etadata.Property\030d \001(\01327.org.jetbrains.k" +
"otlin.metadata.jvm.JvmPropertySignature:" +
"9\n\005flags\022\'.org.jetbrains.kotlin.metadata",
"9\n\005flags\022\'.org.jetbrains.kotlin.metadata" +
".Property\030e \001(\005:\0010:g\n\017type_annotation\022#." +
"org.jetbrains.kotlin.metadata.Type\030d \003(\013" +
"org.jetbrains.kotlin.metadata.Type\030d \003(\013",
"2).org.jetbrains.kotlin.metadata.Annotat" +
"ion:3\n\006is_raw\022#.org.jetbrains.kotlin.met" +
"adata.Type\030e \001(\010:z\n\031type_parameter_annot" +
@@ -5036,9 +4770,9 @@ public final class DebugJvmProtoBuf {
"peParameter\030d \003(\0132).org.jetbrains.kotlin" +
".metadata.Annotation:E\n\021class_module_nam" +
"e\022$.org.jetbrains.kotlin.metadata.Class\030" +
"e \001(\005B\004\230\265\030\001:k\n\024class_local_variable\022$.or",
"e \001(\005B\004\230\265\030\001:k\n\024class_local_variable\022$.or" +
"g.jetbrains.kotlin.metadata.Class\030f \003(\0132" +
"\'.org.jetbrains.kotlin.metadata.Property" +
"\'.org.jetbrains.kotlin.metadata.Property",
":P\n\034anonymous_object_origin_name\022$.org.j" +
"etbrains.kotlin.metadata.Class\030g \001(\005B\004\230\265" +
"\030\001:@\n\017jvm_class_flags\022$.org.jetbrains.ko" +
@@ -5046,7 +4780,7 @@ public final class DebugJvmProtoBuf {
"module_name\022&.org.jetbrains.kotlin.metad" +
"ata.Package\030e \001(\005B\004\230\265\030\001:o\n\026package_local" +
"_variable\022&.org.jetbrains.kotlin.metadat" +
"a.Package\030f \003(\0132\'.org.jetbrains.kotlin.m",
"a.Package\030f \003(\0132\'.org.jetbrains.kotlin.m" +
"etadata.PropertyB\022B\020DebugJvmProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
@@ -5092,7 +4826,7 @@ public final class DebugJvmProtoBuf {
internal_static_org_jetbrains_kotlin_metadata_jvm_JvmPropertySignature_fieldAccessorTable = new
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_org_jetbrains_kotlin_metadata_jvm_JvmPropertySignature_descriptor,
new java.lang.String[] { "Field", "SyntheticMethod", "Getter", "Setter", "DelegateMethod", });
new java.lang.String[] { "Field", "SyntheticMethod", "Getter", "Setter", });
constructorSignature.internalInit(descriptor.getExtensions().get(0));
methodSignature.internalInit(descriptor.getExtensions().get(1));
lambdaClassOriginName.internalInit(descriptor.getExtensions().get(2));

View File

@@ -1,6 +1,7 @@
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
buildscript {
@@ -13,11 +14,8 @@ buildscript {
if (cacheRedirectorEnabled) {
maven("https://cache-redirector.jetbrains.com/plugins.gradle.org/m2")
maven("https://cache-redirector.jetbrains.com/repo.maven.apache.org/maven2")
} else {
maven("https://plugins.gradle.org/m2")
mavenCentral()
}
}
@@ -29,13 +27,18 @@ buildscript {
dependencies {
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.31")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
classpath(kotlin("serialization", bootstrapKotlinVersion))
classpath("org.jetbrains.dokka:dokka-gradle-plugin:0.9.17")
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4.17.2")
}
}
if (kotlinBuildProperties.buildScanServer != null) {
apply(from = "gradle/buildScanUserData.gradle")
}
plugins {
base
idea
@@ -55,6 +58,13 @@ pill {
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
val configuredJdks: List<JdkId> =
getConfiguredJdks().also {
it.forEach { jdkId ->
logger.info("Using ${jdkId.majorVersion} home: ${jdkId.homeDir}")
}
}
val defaultSnapshotVersion: String by extra
val buildNumber by extra(findProperty("build.number")?.toString() ?: defaultSnapshotVersion)
val kotlinVersion by extra(
@@ -80,8 +90,10 @@ val distKotlinHomeDir by extra("$distDir/kotlinc")
val distLibDir = "$distKotlinHomeDir/lib"
val commonLocalDataDir = "$rootDir/local"
val ideaSandboxDir = "$commonLocalDataDir/ideaSandbox"
val ideaUltimateSandboxDir = "$commonLocalDataDir/ideaUltimateSandbox"
val artifactsDir = "$distDir/artifacts"
val ideaPluginDir = "$artifactsDir/ideaPlugin/Kotlin"
val ideaUltimatePluginDir = "$artifactsDir/ideaUltimatePlugin/Kotlin"
extra["ktorExcludesForDaemon"] = listOf(
"org.jetbrains.kotlin" to "kotlin-reflect",
@@ -99,13 +111,46 @@ extra["distLibDir"] = project.file(distLibDir)
extra["libsDir"] = project.file(distLibDir)
extra["commonLocalDataDir"] = project.file(commonLocalDataDir)
extra["ideaSandboxDir"] = project.file(ideaSandboxDir)
extra["ideaUltimateSandboxDir"] = project.file(ideaUltimateSandboxDir)
extra["ideaPluginDir"] = project.file(ideaPluginDir)
extra["ideaUltimatePluginDir"] = project.file(ideaUltimatePluginDir)
extra["isSonatypeRelease"] = false
val kotlinNativeVersionObject = project.kotlinNativeVersionValue()
subprojects {
extra["kotlinNativeVersion"] = kotlinNativeVersionObject
}
// Work-around necessary to avoid setting null javaHome. Will be removed after support of lazy task configuration
val jdkNotFoundConst = "JDK NOT FOUND"
if (isTeamcityBuild) {
extra["JDK_16"] = jdkPath("1.6")
extra["JDK_17"] = jdkPath("1.7")
} else {
extra["JDK_16"] = jdkPath("1.6", "1.8")
extra["JDK_17"] = jdkPath("1.7", "1.8")
}
extra["JDK_18"] = jdkPath("1.8")
extra["JDK_9"] = jdkPath("9")
extra["JDK_10"] = jdkPath("10")
extra["JDK_11"] = jdkPath("11")
extra["JDK_15"] = jdkPath("15")
// allow opening the project without setting up all env variables (see KT-26413)
if (!kotlinBuildProperties.isInIdeaSync) {
checkJDK()
}
fun checkJDK() {
val missingEnvVars = JdkMajorVersion.values()
.filter { it.isMandatory() && extra[it.name] == jdkNotFoundConst }
.mapTo(ArrayList()) { it.name }
if (missingEnvVars.isNotEmpty()) {
throw GradleException("Required environment variables are missing: ${missingEnvVars.joinToString()}")
}
}
rootProject.apply {
from(rootProject.file("gradle/versions.gradle.kts"))
from(rootProject.file("gradle/report.gradle.kts"))
@@ -128,9 +173,8 @@ extra["versions.junit"] = "4.12"
extra["versions.javaslang"] = "2.0.6"
extra["versions.ant"] = "1.10.7"
extra["versions.android"] = "2.3.1"
extra["versions.kotlinx-coroutines-core"] = "1.5.0"
extra["versions.kotlinx-coroutines-core-jvm"] = "1.5.0"
extra["versions.kotlinx-coroutines-jdk8"] = "1.5.0"
extra["versions.kotlinx-coroutines-core"] = "1.3.8"
extra["versions.kotlinx-coroutines-jdk8"] = "1.3.8"
extra["versions.json"] = "20160807"
extra["versions.native-platform"] = "0.14"
extra["versions.robolectric"] = "4.0"
@@ -139,7 +183,7 @@ 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.2.64"
extra["versions.r8"] = "2.1.96"
val immutablesVersion = "0.3.1"
extra["versions.kotlinx-collections-immutable"] = immutablesVersion
extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
@@ -148,9 +192,13 @@ 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.6.0-dev-1728"
extra["versions.kotlin-native"] = "1.5.20-dev-5613"
}
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.kotlinBuildProperties.useIR)
val useJvmFir by extra(project.kotlinBuildProperties.useFir)
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
@@ -159,11 +207,15 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
extra["IntellijCoreDependencies"] =
listOf(
"asm-all-9.0",
when {
Platform[202].orHigher() -> "asm-all-8.0.1"
else -> "asm-all-7.0.1"
},
"guava",
"jdom",
"jna",
"log4j",
if (Platform[201].orHigher()) null else "picocontainer",
"snappy-in-java",
"streamex",
"trove4j"
@@ -211,7 +263,6 @@ extra["compilerModules"] = arrayOf(
":compiler:incremental-compilation-impl",
":compiler:compiler.version",
":js:js.ast",
":js:js.sourcemap",
":js:js.serializer",
":js:js.parser",
":js:js.config",
@@ -247,7 +298,6 @@ extra["compilerModules"] = arrayOf(
":compiler:fir:java",
":compiler:fir:jvm",
":compiler:fir:checkers",
":compiler:fir:checkers:checkers.jvm",
":compiler:fir:entrypoint",
":compiler:fir:analysis-tests",
":compiler:fir:analysis-tests:legacy-fir-tests",
@@ -267,6 +317,7 @@ extra["compilerModulesForJps"] = listOf(
":core:compiler.common.jvm",
":core:descriptors",
":core:descriptors.jvm",
":idea:idea-jps-common",
":kotlin-preloader",
":compiler:util",
":compiler:config",
@@ -276,54 +327,13 @@ extra["compilerModulesForJps"] = listOf(
":compiler:compiler.version"
)
extra["compilerArtifactsForIde"] = listOf(
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide",
":prepare:ide-plugin-dependencies:js-ir-runtime-for-ide",
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-cli-for-ide",
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide",
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:compiler-components-for-jps",
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:lombok-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-tests-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-testdata-for-ide",
":prepare:ide-plugin-dependencies:kotlin-stdlib-minimal-for-test-for-ide",
":prepare:ide-plugin-dependencies:low-level-api-fir-for-ide",
":prepare:ide-plugin-dependencies:high-level-api-for-ide",
":prepare:ide-plugin-dependencies:high-level-api-fir-for-ide",
":prepare:ide-plugin-dependencies:high-level-api-fir-tests-for-ide",
":kotlin-script-runtime",
":kotlin-script-util",
":kotlin-scripting-common",
":kotlin-scripting-jvm",
":kotlin-scripting-compiler",
":kotlin-scripting-compiler-impl",
":kotlin-android-extensions-runtime",
":kotlin-stdlib-common",
":kotlin-stdlib",
":kotlin-stdlib-jdk7",
":kotlin-stdlib-jdk8",
":kotlin-reflect",
":kotlin-main-kts"
)
// TODO: fix remaining warnings and remove this property.
extra["tasksWithWarnings"] = listOf(
":kotlin-stdlib:compileTestKotlin",
":kotlin-stdlib-jdk7:compileTestKotlin",
":kotlin-stdlib-jdk8:compileTestKotlin",
":plugins:uast-kotlin-base:compileKotlin",
":plugins:uast-kotlin-base:compileTestKotlin",
":plugins:uast-kotlin:compileKotlin",
":plugins:uast-kotlin:compileTestKotlin",
":plugins:uast-kotlin-fir:compileKotlin",
":plugins:uast-kotlin-fir:compileTestKotlin"
":plugins:uast-kotlin:compileTestKotlin"
)
val tasksWithWarnings: List<String> by extra
@@ -348,12 +358,7 @@ val coreLibProjects = listOfNotNull(
val projectsWithDisabledFirBootstrap = coreLibProjects + listOf(
":kotlin-gradle-plugin",
":kotlinx-metadata",
":kotlinx-metadata-jvm",
// For some reason stdlib isn't imported correctly for this module
// Probably it's related to kotlin-test module usage
":kotlin-gradle-statistics",
// Requires serialization plugin
":wasm:wasm.ir"
":kotlinx-metadata-jvm"
)
val gradlePluginProjects = listOf(
@@ -373,7 +378,7 @@ apply {
}
apply {
if (extra["isDeployStagingRepoGenerationRequired"] as? Boolean == true) {
if (extra["isSonatypeRelease"] as? Boolean == true) {
logger.info("Applying configuration for sonatype release")
from("libraries/prepareSonatypeStaging.gradle")
}
@@ -387,9 +392,39 @@ fun Task.listConfigurationContents(configName: String) {
}
}
val defaultJvmTarget = "1.8"
val defaultJavaHome = jdkPath(if (Platform[203].orHigher()) "11" else 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"))
}
}
jvmTarget = defaultJvmTarget
javaHome = defaultJavaHome
// There are problems with common build dir:
// - some tests (in particular js and binary-compatibility-validator depend on the fixed (default) location
// - idea seems unable to exclude common buildDir from indexing
// therefore it is disabled by default
// buildDir = File(commonBuildDir, project.name)
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
repositories {
@@ -410,41 +445,11 @@ allprojects {
jcenter()
}
if (path.startsWith(":kotlin-ide.")) {
return@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"))
}
}
// There are problems with common build dir:
// - some tests (in particular js and binary-compatibility-validator depend on the fixed (default) location
// - idea seems unable to exclude common buildDir from indexing
// therefore it is disabled by default
// buildDir = File(commonBuildDir, project.name)
project.configureJvmDefaultToolchain()
plugins.withId("java-base") {
project.configureShadowJarSubstitutionInCompileClasspath()
}
configureJvmProject(javaHome!!, jvmTarget!!)
val commonCompilerArgs = listOfNotNull(
"-Xopt-in=kotlin.RequiresOptIn",
"-Xread-deserialized-contracts",
"-progressive".takeIf { hasProperty("test.progressive.mode") }
)
@@ -460,21 +465,25 @@ allprojects {
"-Xjvm-default=compatibility",
"-Xno-optimized-callable-references",
"-Xno-kotlin-nothing-value-exception",
"-Xsuppress-deprecated-jvm-target-warning" // Remove as soon as there are no modules for JDK 1.6 & 1.7
"-Xnormalize-constructor-calls=enable"
)
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
kotlinOptions {
freeCompilerArgs = commonCompilerArgs + jvmCompilerArgs
if (useJvmFir && this@allprojects.path !in projectsWithDisabledFirBootstrap) {
if (useJvmIrBackend) {
useIR = true
}
if (useJvmFir && this@allprojects.name !in projectsWithDisabledFirBootstrap) {
freeCompilerArgs += "-Xuse-fir"
freeCompilerArgs += "-Xabi-stability=stable"
}
}
}
if (!kotlinBuildProperties.disableWerror) {
if (!kotlinBuildProperties.isInJpsBuildIdeaSync && !kotlinBuildProperties.useFir && !kotlinBuildProperties.disableWerror) {
// For compiler and stdlib, allWarningsAsErrors is configured in the corresponding "root" projects
// (compiler/build.gradle.kts and libraries/commonConfiguration.gradle).
val projectsWithWarningsAsErrors = listOf("core", "plugins").map { File(it).absoluteFile }
@@ -510,16 +519,12 @@ allprojects {
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KTI-112") { true }
}
if (isConfigurationCacheDisabled) {
// Custom input normolization isn't supported by configuration cache at the moment
// See https://github.com/gradle/gradle/issues/13706
normalization {
runtimeClasspath {
ignore("META-INF/MANIFEST.MF")
ignore("META-INF/compiler.version")
ignore("META-INF/plugin.xml")
ignore("kotlin/KotlinVersionCurrentValue.class")
}
normalization {
runtimeClasspath {
ignore("META-INF/MANIFEST.MF")
ignore("META-INF/compiler.version")
ignore("META-INF/plugin.xml")
ignore("kotlin/KotlinVersionCurrentValue.class")
}
}
@@ -534,9 +539,12 @@ allprojects {
register("checkBuild")
}
apply(from = "$rootDir/gradle/cacheRedirector.gradle.kts")
afterEvaluate {
if (javaHome != defaultJavaHome || jvmTarget != defaultJvmTarget) {
logger.info("configuring project $name to compile to the target jvm version $jvmTarget using jdk: $javaHome")
configureJvmProject(javaHome!!, jvmTarget!!)
} // else we will actually fail during the first task execution. We could not fail before configuration is done due to impact on import in IDE
fun File.toProjectRootRelativePathOrSelf() = (relativeToOrNull(rootDir)?.takeUnless { it.startsWith("..") } ?: this).path
fun FileCollection.printClassPath(role: String) =
@@ -565,6 +573,7 @@ allprojects {
?.exclude("org.jetbrains.kotlin", "kotlin-scripting-compiler-embeddable")
}
apply(from = "$rootDir/gradle/cacheRedirector.gradle.kts")
apply(from = "$rootDir/gradle/testRetry.gradle.kts")
}
}
@@ -772,7 +781,6 @@ tasks {
register("distTest") {
dependsOn("compilerTest")
dependsOn("frontendApiTests")
dependsOn("toolsTest")
dependsOn("gradlePluginTest")
dependsOn("examplesTest")
@@ -834,22 +842,12 @@ tasks {
dependsOn("dist")
dependsOn(
":idea:idea-fir:test",
":idea:idea-frontend-fir:fir-low-level-api-ide-impl:test",
":plugins:uast-kotlin-fir:test",
":idea:idea-fir-fe10-binding:test"
":idea:idea-frontend-api:test",
":idea:idea-frontend-fir:test",
":idea:idea-frontend-fir:idea-fir-low-level-api:test"
)
}
register("frontendApiTests") {
dependsOn("dist")
dependsOn(
":idea-frontend-api:test",
":idea-frontend-fir:test",
":idea-frontend-fir:idea-fir-low-level-api:test"
)
}
register("android-ide-tests") {
dependsOn("dist")
@@ -896,6 +894,7 @@ tasks {
}
}
register("kaptIdeTest") {
dependsOn(":kotlin-annotation-processing:test")
dependsOn(":kotlin-annotation-processing-base:test")
@@ -909,6 +908,22 @@ tasks {
)
}
register("kmmTest", AggregateTest::class) {
dependsOn(
":idea:idea-gradle:test",
":idea:test",
":compiler:test",
":compiler:container:test",
":js:js.tests:test"
)
dependsOn(":kotlin-gradle-plugin-integration-tests:test")
if (Ide.AS40.orHigher())
dependsOn(":kotlin-ultimate:ide:android-studio-native:test")
testPatternFile = file("tests/mpp/kmm-patterns.csv")
}
register("test") {
doLast {
throw GradleException("Don't use directly, use aggregate tasks *-check instead")
@@ -935,13 +950,32 @@ tasks {
register("publishIdeArtifacts") {
idePluginDependency {
dependsOn((rootProject.extra["compilerArtifactsForIde"] as List<String>).map { "$it:publish" })
}
}
register("installIdeArtifacts") {
idePluginDependency {
dependsOn((rootProject.extra["compilerArtifactsForIde"] as List<String>).map { "$it:install" })
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: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-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"
)
}
}
}
@@ -993,7 +1027,8 @@ val zipTestData by task<Zip> {
val zipPlugin by task<Zip> {
val src = when (project.findProperty("pluginArtifactDir") as String?) {
"Kotlin" -> ideaPluginDir
null -> ideaPluginDir
"KotlinUltimate" -> ideaUltimatePluginDir
null -> if (project.hasProperty("ultimate")) ideaUltimatePluginDir else ideaPluginDir
else -> error("Unsupported plugin artifact dir")
}
val destPath = project.findProperty("pluginZipPath") as String?
@@ -1050,6 +1085,66 @@ configure<IdeaModel> {
}
}
fun jdkPathOrNull(version: String): String? {
val jdkName = "JDK_${version.replace(".", "")}"
val jdkMajorVersion = JdkMajorVersion.valueOf(jdkName)
return configuredJdks.find { it.majorVersion == jdkMajorVersion }?.homeDir?.canonicalPath
}
fun jdkPath(version: String, vararg replacementVersions: String): String {
return jdkPathOrNull(version) ?: run {
replacementVersions.asSequence().map { jdkPathOrNull(it) }.find { it != null }
} ?: jdkNotFoundConst
}
fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
val currentJavaHome = File(System.getProperty("java.home")!!).canonicalPath
val shouldFork = !currentJavaHome.startsWith(File(javaHome).canonicalPath)
tasks.withType<JavaCompile> {
if (name != "compileJava9Java") {
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
options.isFork = shouldFork
options.forkOptions.javaHome = file(javaHome)
options.compilerArgs.add("-proc:none")
options.encoding = "UTF-8"
}
}
tasks.withType<KotlinCompile> {
kotlinOptions.jdkHome = javaHome
kotlinOptions.jvmTarget = javaVersion
kotlinOptions.freeCompilerArgs += "-Xjvm-default=compatibility"
}
tasks.withType<Test> {
executable = File(javaHome, "bin/java").canonicalPath
}
plugins.withId("java-base") {
configureShadowJarSubstitutionInCompileClasspath()
}
}
fun Project.configureShadowJarSubstitutionInCompileClasspath() {
val substitutionMap = mapOf(":kotlin-reflect" to ":kotlin-reflect-api")
fun configureSubstitution(substitution: DependencySubstitution) {
val requestedProject = (substitution.requested as? ProjectComponentSelector)?.projectPath ?: return
val replacementProject = substitutionMap[requestedProject] ?: return
substitution.useTarget(project(replacementProject), "Non-default shadow jars should not be used in compile classpath")
}
sourceSets.all {
for (configName in listOf(compileOnlyConfigurationName, compileClasspathConfigurationName)) {
configurations.getByName(configName).resolutionStrategy.dependencySubstitution {
all(::configureSubstitution)
}
}
}
}
tasks.register("findShadowJarsInClasspath") {
doLast {
fun Collection<File>.printSorted(indent: String = " ") {
@@ -1117,19 +1212,3 @@ if (disableVerificationTasks) {
}
}
}
plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin::class) {
extensions.configure(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension::class.java) {
nodeVersion = "16.2.0"
}
}
afterEvaluate {
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
if (cacheRedirectorEnabled) {
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin::class.java) {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().downloadBaseUrl =
"https://cache-redirector.jetbrains.com/github.com/yarnpkg/yarn/releases/download"
}
}
}

View File

@@ -22,7 +22,7 @@ buildscript {
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.31")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
}
@@ -69,6 +69,7 @@ rootProject.apply {
}
val isTeamcityBuild = kotlinBuildProperties.isTeamcityBuild
val intellijUltimateEnabled by extra(kotlinBuildProperties.intellijUltimateEnabled)
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
extra["intellijReleaseType"] = when {
@@ -143,7 +144,7 @@ java {
dependencies {
implementation(kotlin("stdlib", embeddedKotlinVersion))
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.31")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
implementation("com.gradle.publish:plugin-publish-plugin:0.14.0")
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
@@ -155,10 +156,10 @@ dependencies {
implementation("net.sf.proguard:proguard-gradle:6.2.2")
implementation("org.jetbrains.intellij.deps:asm-all:8.0.1")
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:1.0.1")
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
implementation("org.gradle:test-retry-gradle-plugin:1.2.0")
implementation("com.gradle.enterprise:test-distribution-gradle-plugin:2.1")
implementation("com.gradle.enterprise:test-distribution-gradle-plugin:1.2.1")
compileOnly(gradleApi())

View File

@@ -15,28 +15,30 @@ plugins {
base
}
val intellijUltimateEnabled: Boolean by rootProject.extra
val intellijReleaseType: String by rootProject.extra
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
val intellijVersionForIde = rootProject.intellijSdkVersionForIde()
val asmVersion = rootProject.findProperty("versions.jar.asm-all") as String?
val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelease") as String?
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
val intellijSeparateSdks: Boolean by rootProject.extra
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
val installIntellijUltimate = intellijUltimateEnabled && androidStudioRelease == null
fun checkIntellijVersion(intellijVersion: String) {
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
if (intellijVersionDelimiterIndex == -1) {
error("Invalid IDEA version $intellijVersion")
}
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
if (intellijVersionDelimiterIndex == -1) {
error("Invalid IDEA version $intellijVersion")
}
checkIntellijVersion(intellijVersion)
intellijVersionForIde?.let { checkIntellijVersion(it) }
val platformBaseVersion = intellijVersion.substring(0, intellijVersionDelimiterIndex)
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
logger.info("intellijVersion: $intellijVersion")
logger.info("intellijVersionForIde: $intellijVersionForIde")
logger.info("androidStudioRelease: $androidStudioRelease")
logger.info("androidStudioBuild: $androidStudioBuild")
logger.info("intellijSeparateSdks: $intellijSeparateSdks")
logger.info("installIntellijCommunity: $installIntellijCommunity")
logger.info("installIntellijUltimate: $installIntellijUltimate")
val androidStudioOs by lazy {
when {
@@ -71,14 +73,11 @@ repositories {
}
val intellij by configurations.creating
val intellijForIde by configurations.creating
val intellijUltimate by configurations.creating
val androidStudio by configurations.creating
val sources by configurations.creating
val sourcesForIde by configurations.creating
val jpsStandalone by configurations.creating
val jpsStandaloneForIde by configurations.creating
val intellijCore by configurations.creating
val intellijCoreForIde by configurations.creating
val nodeJSPlugin by configurations.creating
/**
@@ -94,6 +93,7 @@ val dependenciesDir = (findProperty("kotlin.build.dependencies.dir") as String?)
val customDepsRepoDir = dependenciesDir.resolve("repo")
val customDepsOrg: String by rootProject.extra
val customDepsRevision = intellijVersion
val repoDir = File(customDepsRepoDir, customDepsOrg)
dependencies {
@@ -105,8 +105,12 @@ dependencies {
androidStudio("google:android-studio-ide:$androidStudioBuild@$extension")
} else {
intellij("com.jetbrains.intellij.idea:ideaIC:$intellijVersion")
intellijVersionForIde?.let { intellijForIde("com.jetbrains.intellij.idea:ideaIC:$it") }
if (installIntellijCommunity) {
intellij("com.jetbrains.intellij.idea:ideaIC:$intellijVersion")
}
if (installIntellijUltimate) {
intellijUltimate("com.jetbrains.intellij.idea:ideaIU:$intellijVersion")
}
}
if (asmVersion != null) {
@@ -114,104 +118,102 @@ dependencies {
}
sources("com.jetbrains.intellij.idea:ideaIC:$intellijVersion:sources@jar")
intellijVersionForIde?.let { sourcesForIde("com.jetbrains.intellij.idea:ideaIC:$it:sources@jar") }
jpsStandalone("com.jetbrains.intellij.idea:jps-standalone:$intellijVersion")
intellijVersionForIde?.let { jpsStandaloneForIde("com.jetbrains.intellij.idea:jps-standalone:$it") }
intellijCore("com.jetbrains.intellij.idea:intellij-core:$intellijVersion")
intellijVersionForIde?.let { intellijCoreForIde("com.jetbrains.intellij.idea:intellij-core:$it") }
if (intellijUltimateEnabled) {
nodeJSPlugin("com.jetbrains.plugins:NodeJS:${rootProject.extra["versions.idea.NodeJS"]}@zip")
}
}
fun prepareDeps(
intellij: Configuration,
intellijCore: Configuration,
sources: Configuration,
jpsStandalone: Configuration,
intellijVersion: String
) {
val makeIntellijCore = buildIvyRepositoryTask(intellijCore, customDepsOrg, customDepsRepoDir)
val makeIntellijCore = buildIvyRepositoryTask(intellijCore, customDepsOrg, customDepsRepoDir)
val makeIntellijAnnotations = tasks.register("makeIntellijAnnotations${intellij.name.capitalize()}", Copy::class) {
dependsOn(makeIntellijCore)
val makeIntellijAnnotations by tasks.registering(Copy::class) {
dependsOn(makeIntellijCore)
val intellijCoreRepo = CleanableStore[repoDir.resolve("intellij-core").absolutePath][intellijVersion].use()
from(intellijCoreRepo.resolve("artifacts/annotations.jar"))
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()
into(targetDir)
val annotationsStore = CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath]
val targetDir = annotationsStore[intellijVersion].use()
into(targetDir)
val ivyFile = File(targetDir, "$intellijRuntimeAnnotations.ivy.xml")
outputs.files(ivyFile)
val ivyFile = File(targetDir, "$intellijRuntimeAnnotations.ivy.xml")
outputs.files(ivyFile)
doFirst {
annotationsStore.cleanStore()
}
doLast {
writeIvyXml(
customDepsOrg,
intellijRuntimeAnnotations,
intellijVersion,
intellijRuntimeAnnotations,
targetDir,
targetDir,
targetDir,
allowAnnotations = true
)
}
doFirst {
annotationsStore.cleanStore()
}
val mergeSources = tasks.create("mergeSources${intellij.name.capitalize()}", Jar::class.java) {
dependsOn(sources)
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
isZip64 = true
if (!kotlinBuildProperties.isTeamcityBuild) {
from(provider { sources.map(::zipTree) })
}
destinationDirectory.set(File(repoDir, sources.name))
archiveBaseName.set("intellij")
archiveClassifier.set("sources")
archiveVersion.set(intellijVersion)
}
val sourcesFile = mergeSources.outputs.files.singleFile
val makeIde = if (androidStudioBuild != null) {
buildIvyRepositoryTask(
androidStudio,
doLast {
writeIvyXml(
customDepsOrg,
customDepsRepoDir,
if (androidStudioOs == "mac")
::skipContentsDirectory
else
::skipToplevelDirectory
)
} else {
val task = buildIvyRepositoryTask(intellij, customDepsOrg, customDepsRepoDir, null, sourcesFile)
task.configure {
dependsOn(mergeSources)
}
task
}
val buildJpsStandalone = buildIvyRepositoryTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
tasks.named("build") {
dependsOn(
makeIntellijCore,
makeIde,
buildJpsStandalone,
makeIntellijAnnotations
intellijRuntimeAnnotations,
intellijVersion,
intellijRuntimeAnnotations,
targetDir,
targetDir,
targetDir,
allowAnnotations = true
)
}
}
prepareDeps(intellij, intellijCore, sources, jpsStandalone, intellijVersion)
if (intellijVersionForIde != null) {
prepareDeps(intellijForIde, intellijCoreForIde, sourcesForIde, jpsStandaloneForIde, intellijVersionForIde)
val mergeSources by tasks.creating(Jar::class.java) {
dependsOn(sources)
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
isZip64 = true
if (!kotlinBuildProperties.isTeamcityBuild) {
from(provider { sources.map(::zipTree) })
}
destinationDirectory.set(File(repoDir, sources.name))
archiveBaseName.set("intellij")
archiveClassifier.set("sources")
archiveVersion.set(intellijVersion)
}
val sourcesFile = mergeSources.outputs.files.singleFile
val makeIde = if (androidStudioBuild != null) {
buildIvyRepositoryTask(
androidStudio,
customDepsOrg,
customDepsRepoDir,
if (androidStudioOs == "mac")
::skipContentsDirectory
else
::skipToplevelDirectory
)
} else {
val task = if (installIntellijUltimate) {
buildIvyRepositoryTask(intellijUltimate, customDepsOrg, customDepsRepoDir, null, sourcesFile)
} else {
buildIvyRepositoryTask(intellij, customDepsOrg, customDepsRepoDir, null, sourcesFile)
}
task.configure {
dependsOn(mergeSources)
}
task
}
val buildJpsStandalone = buildIvyRepositoryTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
tasks.named("build") {
dependsOn(
makeIntellijCore,
makeIde,
buildJpsStandalone,
makeIntellijAnnotations
)
}
if (installIntellijUltimate) {
val buildNodeJsPlugin =
buildIvyRepositoryTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
tasks.named("build") { dependsOn(buildNodeJsPlugin) }
}
tasks.named<Delete>("clean") {
@@ -398,11 +400,6 @@ fun skipToplevelDirectory(path: String) = path.substringAfter('/')
fun skipContentsDirectory(path: String) = path.substringAfter("Contents/")
fun Project.intellijSdkVersionForIde(): String? {
val majorVersion = kotlinBuildProperties.getOrNull("attachedIntellijVersion") as? String ?: return null
return rootProject.findProperty("versions.intellijSdk.forIde.$majorVersion") as? String
}
class XMLWriter(private val outputStreamWriter: OutputStreamWriter) : Closeable {
private val xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStreamWriter)

View File

@@ -18,11 +18,55 @@ buildscript {
} else {
maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies" }
}
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.30")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
}
}
include "prepare-deps"
def buildProperties = BuildPropertiesKt.getKotlinBuildPropertiesForSettings(settings)
def projectVersions = file("../gradle/versions.properties").text
include "prepare-deps"
def target_AppCode_Clion = buildProperties.includeCidrPlugins && !projectVersions.contains("versions.androidStudioRelease")
def target_AndroidStudio = buildProperties.includeCidrPlugins && projectVersions.contains("versions.androidStudioRelease")
def target_IdeaUltimate = buildProperties.includeUltimate
if (target_AppCode_Clion) {
logger.info("Including modules for AC and CL in buildSrc/settings.gradle")
include ":prepare-deps:kotlin-native-platform-deps"
include ":prepare-deps:native-debug-plugin"
project(":prepare-deps:kotlin-native-platform-deps").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/kotlin-native-platform-deps")
project(":prepare-deps:native-debug-plugin").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/native-debug-plugin")
} else if (target_AndroidStudio) {
logger.info("Including modules for AS (mobile plugin) in buildSrc/settings.gradle")
include ":prepare-deps:appcode-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:lldb-framework").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-framework")
project(":prepare-deps:lldb-frontend").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-frontend")
} else if (target_IdeaUltimate) {
logger.info("Including modules for IU in buildSrc/settings.gradle")
include ":prepare-deps:lldb-frontend"
include ":prepare-deps:native-debug-plugin"
project(":prepare-deps:lldb-frontend").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-frontend")
project(":prepare-deps:native-debug-plugin").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/native-debug-plugin")
} else {
logger.info("Not including extra modules in buildSrc/settings.gradle")
}

View File

@@ -19,8 +19,4 @@ val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.bui
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
val KotlinBuildProperties.disableWerror: Boolean
get() = getBoolean("kotlin.build.disable.werror") || useFir || isInJpsBuildIdeaSync || getBoolean("test.progressive.mode")
val KotlinBuildProperties.isObsoleteJdkOverrideEnabled: Boolean
get() = getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)
val KotlinBuildProperties.disableWerror: Boolean get() = getBoolean("kotlin.build.disable.werror", false)

View File

@@ -4,36 +4,32 @@
*/
import groovy.lang.Closure
import org.gradle.api.JavaVersion
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.kotlin.dsl.property
import org.gradle.internal.jvm.Jvm
import org.gradle.internal.jvm.inspection.JvmVersionDetector
import proguard.ClassSpecification
import java.io.File
import javax.inject.Inject
@CacheableTask
open class CacheableProguardTask : proguard.gradle.ProGuardTask() {
open class CacheableProguardTask @Inject constructor(
private val jvmVersionDetector: JvmVersionDetector
) : proguard.gradle.ProGuardTask() {
@get:Internal
val javaLauncher: Property<JavaLauncher> = project.objects.property()
@get:Internal
val jdkHomePath: Provider<File> = javaLauncher.map { it.metadata.installationPath.asFile }
@Internal
var jdkHome: File? = null
@get:Optional
@get:Input
internal val jdkMajorVersion: Provider<JavaVersion> = javaLauncher.map {
JavaVersion.toVersion(it.metadata.languageVersion.toString())
}
internal val jdkMajorVersion: String?
get() = jdkHome?.let { jvmVersionDetector.getJavaVersion(Jvm.forHome(jdkHome)) }?.majorVersion
@CompileClasspath
override fun getLibraryJarFileCollection(): FileCollection = super.getLibraryJarFileCollection()
.filter { libraryFile ->
jdkHomePath.orNull?.let { !libraryFile.absoluteFile.startsWith(it.absoluteFile) } ?: true
}
override fun getLibraryJarFileCollection(): FileCollection = super.getLibraryJarFileCollection().filter { libraryFile ->
jdkHome?.let { !libraryFile.absoluteFile.startsWith(it.absoluteFile) } ?: true
}
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)

View File

@@ -81,12 +81,3 @@ fun Task.singleOutputFile(): File = when (this) {
is ProGuardTask -> project.file(outJarFiles.single()!!)
else -> outputs.files.singleFile
}
val Project.isConfigurationCacheDisabled
get() = (gradle.startParameter as? org.gradle.api.internal.StartParameterInternal)?.isConfigurationCache != true
val Project.isIdeaActive
get() = providers.systemProperty("idea.active").forUseAtConfigurationTime().isPresent
val Project.intellijCommunityDir: File
get() = rootDir.resolve("kotlin-ide/intellij/community").takeIf { it.isDirectory } ?: rootDir.resolve("kotlin-ide/intellij")

View File

@@ -1,144 +0,0 @@
/*
* Copyright 2010-2021 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.github.jengelman.gradle.plugins.shadow.relocation.RelocateClassContext
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import org.gradle.api.file.FileTreeElement
import shadow.org.apache.tools.zip.ZipEntry
import shadow.org.apache.tools.zip.ZipOutputStream
import shadow.org.codehaus.plexus.util.IOUtil
import shadow.org.codehaus.plexus.util.ReaderFactory
import shadow.org.codehaus.plexus.util.WriterFactory
import shadow.org.codehaus.plexus.util.xml.Xpp3Dom
import shadow.org.codehaus.plexus.util.xml.Xpp3DomBuilder
import shadow.org.codehaus.plexus.util.xml.Xpp3DomWriter
import java.io.*
import java.lang.Exception
import java.util.LinkedHashMap
/**
* A resource processor that aggregates plexus `components.xml` files.
*
* Fixed version of [com.github.jengelman.gradle.plugins.shadow.transformers.ComponentsXmlResourceTransformer],
* may be dropped after [the fix in ShadowJAR](https://github.com/johnrengelman/shadow/pull/678/files) will be accepted
*/
class ComponentsXmlResourceTransformerPatched : Transformer {
private val components: MutableMap<String, Xpp3Dom> =
LinkedHashMap<String, Xpp3Dom>()
override fun canTransformResource(element: FileTreeElement): Boolean {
val path = element.relativePath.pathString
return COMPONENTS_XML_PATH == path
}
override fun transform(context: TransformerContext) {
val newDom: Xpp3Dom = try {
val bis: BufferedInputStream = object : BufferedInputStream(context.getIs()) {
override fun close() {
// leave ZIP open
}
}
val reader: Reader = ReaderFactory.newXmlReader(bis)
Xpp3DomBuilder.build(reader)
} catch (e: Exception) {
throw (IOException("Error parsing components.xml in " + context.getIs()).initCause(e) as IOException)
}
// Only try to merge in components if there are some elements in the component-set
if (newDom.getChild("components") == null) {
return
}
val children: Array<Xpp3Dom>? = newDom.getChild("components")?.getChildren("component")
children?.forEach { component ->
var role: String? = getValue(component, "role")
role = getRelocatedClass(role, context)
setValue(component, "role", role)
val roleHint = getValue(component, "role-hint")
var impl: String? = getValue(component, "implementation")
impl = getRelocatedClass(impl, context)
setValue(component, "implementation", impl)
val key = "$role:$roleHint"
if (components.containsKey(key)) {
// configuration carry over
val dom: Xpp3Dom? = components[key]
if (dom?.getChild("configuration") != null) {
component.addChild(dom.getChild("configuration"))
}
}
val requirements: Xpp3Dom? = component.getChild("requirements")
if (requirements != null && requirements.childCount > 0) {
for (r in requirements.childCount - 1 downTo 0) {
val requirement: Xpp3Dom = requirements.getChild(r)
var requiredRole: String? = getValue(requirement, "role")
requiredRole = getRelocatedClass(requiredRole, context)
setValue(requirement, "role", requiredRole)
}
}
components[key] = component
}
}
override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
val data = transformedResource
val entry = ZipEntry(COMPONENTS_XML_PATH)
entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time)
os.putNextEntry(entry)
IOUtil.copy(data, os)
components.clear()
}
override fun hasTransformedResource(): Boolean {
return components.isNotEmpty()
}
private val transformedResource: ByteArray
get() {
val baos = ByteArrayOutputStream(1024 * 4)
val writer: Writer = WriterFactory.newXmlWriter(baos)
try {
val dom = Xpp3Dom("component-set")
val componentDom = Xpp3Dom("components")
dom.addChild(componentDom)
for (component in components.values) {
componentDom.addChild(component)
}
Xpp3DomWriter.write(writer, dom)
} finally {
IOUtil.close(writer)
}
return baos.toByteArray()
}
companion object {
private const val COMPONENTS_XML_PATH = "META-INF/plexus/components.xml"
private fun getRelocatedClass(className: String?, context: TransformerContext): String? {
val relocators = context.relocators
val stats = context.stats
if (className != null && className.isNotEmpty() && relocators != null) {
for (relocator in relocators) {
if (relocator.canRelocateClass(className)) {
val relocateClassContext = RelocateClassContext(className, stats)
return relocator.relocateClass(relocateClassContext)
}
}
}
return className
}
private fun getValue(dom: Xpp3Dom, element: String): String {
val child: Xpp3Dom? = dom.getChild(element)
return if (child?.value != null) child.value else ""
}
private fun setValue(dom: Xpp3Dom, element: String, value: String?) {
val child: Xpp3Dom? = dom.getChild(element)
if (value == null || value.isEmpty()) {
return
}
child?.value = value
}
}
}

View File

@@ -26,7 +26,7 @@ fun CompatibilityPredicate.or(other: CompatibilityPredicate): CompatibilityPredi
}
enum class Platform : CompatibilityPredicate {
P203;
P183, P191, P192, P193, P201, P202, P203;
val version: Int = name.drop(1).toInt()
@@ -43,7 +43,18 @@ enum class Platform : CompatibilityPredicate {
}
enum class Ide(val platform: Platform) : CompatibilityPredicate {
IJ203(Platform.P203);
IJ191(Platform.P191),
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);
val kind = Kind.values().first { it.shortName == name.take(2) }
val version = name.dropWhile { !it.isDigit() }.toInt()

View File

@@ -1,184 +0,0 @@
@file:JvmName("JvmToolchain")
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.toolchain.*
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
enum class JdkMajorVersion(
val majorVersion: Int,
val targetName: String = majorVersion.toString(),
val overrideMajorVersion: Int? = null,
private val mandatory: Boolean = true
) {
JDK_1_6(6, targetName = "1.6", overrideMajorVersion = 8),
JDK_1_7(7, targetName = "1.7", overrideMajorVersion = 8),
JDK_1_8(8, targetName = "1.8"),
JDK_9(9, overrideMajorVersion = 11),
JDK_10(10, mandatory = false, overrideMajorVersion = 11),
JDK_11(11, mandatory = false),
JDK_15(15, mandatory = false),
JDK_16(16, mandatory = false),
JDK_17(17, mandatory = false);
fun isMandatory(): Boolean = mandatory
companion object {
fun fromMajorVersion(majorVersion: Int) = values().first { it.majorVersion == majorVersion }
}
}
fun Project.configureJvmDefaultToolchain() {
configureJvmToolchain(JdkMajorVersion.JDK_1_8)
}
fun Project.shouldOverrideObsoleteJdk(
jdkVersion: JdkMajorVersion
): Boolean = kotlinBuildProperties.isObsoleteJdkOverrideEnabled &&
jdkVersion.overrideMajorVersion != null
fun Project.configureJvmToolchain(
jdkVersion: JdkMajorVersion
) {
// Ensure java only modules also set default toolchain
configureJavaOnlyToolchain(jdkVersion)
plugins.withId("org.jetbrains.kotlin.jvm") {
val kotlinExtension = extensions.getByType<KotlinTopLevelExtension>()
if (shouldOverrideObsoleteJdk(jdkVersion)) {
kotlinExtension.jvmToolchain {
(this as JavaToolchainSpec).languageVersion
.set(JavaLanguageVersion.of(jdkVersion.overrideMajorVersion!!))
}
updateJvmTarget(jdkVersion.targetName)
} else {
kotlinExtension.jvmToolchain {
(this as JavaToolchainSpec).languageVersion
.set(JavaLanguageVersion.of(jdkVersion.majorVersion))
}
}
tasks
.matching { it.name != "compileJava9Java" && it is JavaCompile }
.configureEach {
with(this as JavaCompile) {
options.compilerArgs.add("-proc:none")
options.encoding = "UTF-8"
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += "-Xjvm-default=compatibility"
}
}
}
fun Project.configureJavaOnlyToolchain(
jdkVersion: JdkMajorVersion
) {
plugins.withId("java-base") {
val javaExtension = extensions.getByType<JavaPluginExtension>()
if (shouldOverrideObsoleteJdk(jdkVersion)) {
javaExtension.toolchain {
languageVersion.set(
JavaLanguageVersion.of(jdkVersion.overrideMajorVersion!!)
)
}
tasks.withType<JavaCompile>().configureEach {
targetCompatibility = jdkVersion.targetName
sourceCompatibility = jdkVersion.targetName
}
} else {
javaExtension.toolchain {
languageVersion.set(
JavaLanguageVersion.of(jdkVersion.majorVersion)
)
}
}
}
}
fun KotlinCompile.configureTaskToolchain(
jdkVersion: JdkMajorVersion
) {
if (project.shouldOverrideObsoleteJdk(jdkVersion)) {
kotlinJavaToolchain.toolchain.use(
project.getToolchainLauncherFor(
JdkMajorVersion.fromMajorVersion(
jdkVersion.overrideMajorVersion!!
)
)
)
kotlinOptions {
jvmTarget = jdkVersion.targetName
}
} else {
kotlinJavaToolchain.toolchain.use(
project.getToolchainLauncherFor(jdkVersion)
)
}
}
fun JavaCompile.configureTaskToolchain(
jdkVersion: JdkMajorVersion
) {
if (project.shouldOverrideObsoleteJdk(jdkVersion)) {
javaCompiler.set(
project.getToolchainCompilerFor(
JdkMajorVersion.fromMajorVersion(
jdkVersion.overrideMajorVersion!!
)
)
)
targetCompatibility = jdkVersion.targetName
sourceCompatibility = jdkVersion.targetName
} else {
javaCompiler.set(project.getToolchainCompilerFor(jdkVersion))
}
}
fun Project.updateJvmTarget(
jvmTarget: String
) {
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.jvmTarget = jvmTarget
}
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = jvmTarget
targetCompatibility = jvmTarget
}
}
private fun Project.getToolchainCompilerFor(
jdkVersion: JdkMajorVersion
): Provider<JavaCompiler> {
val service = project.extensions.getByType<JavaToolchainService>()
return service.compilerFor {
this.languageVersion.set(JavaLanguageVersion.of(jdkVersion.majorVersion))
}
}
fun Project.getToolchainLauncherFor(
jdkVersion: JdkMajorVersion
): Provider<JavaLauncher> {
val service = project.extensions.getByType<JavaToolchainService>()
val jdkVersionWithOverride = project.getJdkVersionWithOverride(jdkVersion)
return service.launcherFor {
this.languageVersion.set(JavaLanguageVersion.of(jdkVersionWithOverride.majorVersion))
}
}
fun Project.getJdkVersionWithOverride(jdkVersion: JdkMajorVersion): JdkMajorVersion {
return if (project.shouldOverrideObsoleteJdk(jdkVersion)) {
JdkMajorVersion.fromMajorVersion(jdkVersion.overrideMajorVersion!!)
} else {
jdkVersion
}
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright 2010-2021 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("LibrariesCommon")
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.kotlin.dsl.get
import org.gradle.process.CommandLineArgumentProvider
@JvmOverloads
fun Project.configureJava9Compilation(
moduleName: String,
moduleOutputs: Collection<FileCollection> = setOf(sourceSets["main"].output)
) {
configurations["java9CompileClasspath"].extendsFrom(configurations["compileClasspath"])
tasks.named("compileJava9Java", JavaCompile::class.java) {
dependsOn(moduleOutputs)
targetCompatibility = JavaVersion.VERSION_1_9.toString()
sourceCompatibility = JavaVersion.VERSION_1_9.toString()
configureTaskToolchain(JdkMajorVersion.JDK_9)
// module-info.java should be in java9 source set by convention
val java9SourceSet = sourceSets["java9"].java
destinationDir = file("${java9SourceSet.outputDir}/META-INF/versions/9")
options.sourcepath = files(java9SourceSet.srcDirs)
val compileClasspath = configurations["java9CompileClasspath"]
val moduleFiles = objects.fileCollection().from(moduleOutputs)
val modulePath = compileClasspath.filter { it !in moduleFiles.files }
classpath = objects.fileCollection().from()
options.compilerArgumentProviders.add(
Java9AdditionalArgumentsProvider(
moduleName,
moduleFiles,
modulePath
)
)
}
}
private class Java9AdditionalArgumentsProvider(
private val moduleName: String,
private val moduleFiles: FileCollection,
private val modulePath: FileCollection
) : CommandLineArgumentProvider {
override fun asArguments(): Iterable<String> = listOf(
"--module-path", modulePath.asPath,
"--patch-module", "$moduleName=${moduleFiles.asPath}",
"-Xlint:-requires-transitive-automatic" // suppress automatic module transitive dependencies in kotlin.test
)
}

View File

@@ -1,6 +1,6 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import com.gradle.publish.PublishTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.ConfigurablePublishArtifact
@@ -22,12 +22,12 @@ 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.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetContainer
import plugins.KotlinBuildPublishingPlugin
import plugins.mainPublicationName
private const val MAGIC_DO_NOT_CHANGE_TEST_JAR_TASK_NAME = "testJar"
@@ -62,6 +62,8 @@ fun Project.removeArtifacts(configuration: Configuration, task: Task) {
fun Project.noDefaultJar() {
tasks.named("jar").configure {
enabled = false
actions = emptyList()
configurations.forEach { cfg ->
removeArtifacts(cfg, this)
}
@@ -110,8 +112,6 @@ fun <T : Jar> Project.runtimeJar(task: TaskProvider<T>, body: T.() -> Unit = {})
addVariantsFromConfiguration(runtimeJar) { }
}
(components.findByName("java") as AdhocComponentWithVariants?)?.addVariantsFromConfiguration(runtimeJar) { }
return task
}
@@ -225,20 +225,24 @@ fun Project.publish(moduleMetadata: Boolean = false, configure: MavenPublication
val publication = extensions.findByType<PublishingExtension>()
?.publications
?.findByName(mainPublicationName) as MavenPublication
?.findByName(KotlinBuildPublishingPlugin.PUBLICATION_NAME) as MavenPublication
publication.configure()
}
fun Project.publishGradlePlugin() {
mainPublicationName = "pluginMaven"
publish()
fun Project.publishWithLegacyMavenPlugin(body: Upload.() -> Unit = {}): Upload {
apply<plugins.PublishedKotlinModule>()
if (artifactsRemovedDiagnosticFlag) {
error("`publish()` should be called before removing artifacts typically done in `noDefaultJar()` or `runtimeJar()` call")
}
afterEvaluate {
tasks.withType<PublishTask> {
// Makes plugin publication task reuse poms and metadata from publication named "pluginMaven"
useAutomatedPublishing()
useGradleModuleMetadataIfAvailable()
}
if (configurations.findByName("classes-dirs") != null)
throw GradleException("classesDirsArtifact() is incompatible with publish(), see sources comments for details")
}
return (tasks.getByName("uploadArchives") as Upload).apply {
body()
}
}
@@ -249,41 +253,6 @@ fun Project.idePluginDependency(block: () -> Unit) {
}
}
fun Project.publishJarsForIde(projects: List<String>, libraryDependencies: List<String> = emptyList()) {
idePluginDependency {
publishProjectJars(projects, libraryDependencies)
}
configurations.all {
// Don't allow `ideaIC` from compiler to leak into Kotlin plugin modules. Compiler and
// plugin may depend on different versions of IDEA and it will lead to version conflict
exclude(module = ideModuleName())
}
dependencies {
projects.forEach {
jpsLikeJarDependency(project(it), JpsDepScope.COMPILE, { isTransitive = false }, exported = true)
}
libraryDependencies.forEach {
jpsLikeJarDependency(it, JpsDepScope.COMPILE, exported = true)
}
}
}
fun Project.publishTestJarsForIde(projectNames: List<String>) {
idePluginDependency {
publishTestJar(projectNames)
}
configurations.all {
// Don't allow `ideaIC` from compiler to leak into Kotlin plugin modules. Compiler and
// plugin may depend on different versions of IDEA and it will lead to version conflict
exclude(module = ideModuleName())
}
dependencies {
for (projectName in projectNames) {
jpsLikeJarDependency(projectTests(projectName), JpsDepScope.COMPILE, exported = true)
}
}
}
fun Project.publishProjectJars(projects: List<String>, libraryDependencies: List<String> = emptyList()) {
apply<JavaPlugin>()
@@ -322,15 +291,13 @@ fun Project.publishProjectJars(projects: List<String>, libraryDependencies: List
javadocJar()
}
fun Project.publishTestJar(projects: List<String>) {
fun Project.publishTestJar(projectName: String) {
apply<JavaPlugin>()
val fatJarContents by configurations.creating
dependencies {
for (projectName in projects) {
fatJarContents(project(projectName, configuration = "tests-jar")) { isTransitive = false }
}
fatJarContents(project(projectName, configuration = "tests-jar")) { isTransitive = false }
}
publish()
@@ -347,7 +314,7 @@ fun Project.publishTestJar(projects: List<String>) {
sourcesJar {
from {
projects.map { project(it).testSourceSet.allSource }
project(projectName).testSourceSet.allSource
}
}

View File

@@ -9,15 +9,13 @@
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.internal.jvm.Jvm
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.accessors.runtime.addDependencyTo
import org.gradle.kotlin.dsl.closureOf
import org.gradle.kotlin.dsl.exclude
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.project
import java.io.File
@@ -36,7 +34,7 @@ val Project.internalBootstrapRepo: String? get() =
when {
bootstrapKotlinRepo?.startsWith("https://buildserver.labs.intellij.net") == true ->
bootstrapKotlinRepo!!.replace("artifacts/content/maven", "artifacts/content/internal/repo")
else -> "https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Aggregate),number:$bootstrapKotlinVersion," +
else -> "https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:$bootstrapKotlinVersion," +
"branch:default:any/artifacts/content/internal/repo/"
}
@@ -91,6 +89,12 @@ fun Project.preloadedDeps(
return files(*matchingFiles.map { it.canonicalPath }.toTypedArray())
}
fun Project.ideaUltimatePreloadedDeps(vararg artifactBaseNames: String, subdir: String? = null): ConfigurableFileCollection {
val ultimateDepsDir = fileFrom(rootDir, "ultimate", "dependencies")
return if (ultimateDepsDir.isDirectory) preloadedDeps(*artifactBaseNames, baseDir = ultimateDepsDir, subdir = subdir)
else files()
}
fun Project.kotlinDep(artifactBaseName: String, version: String, classifier: String? = null): String =
listOfNotNull("org.jetbrains.kotlin:kotlin-$artifactBaseName:$version", classifier).joinToString(":")
@@ -111,95 +115,6 @@ fun DependencyHandler.projectTests(name: String): ProjectDependency = project(na
fun DependencyHandler.projectRuntimeJar(name: String): ProjectDependency = project(name, configuration = "runtimeJar")
fun DependencyHandler.projectArchives(name: String): ProjectDependency = project(name, configuration = "archives")
enum class JpsDepScope {
COMPILE, TEST, RUNTIME, PROVIDED
}
fun DependencyHandler.add(configurationName: String, dependencyNotation: Any, configure: (ModuleDependency.() -> Unit)?) {
// Avoid `dependencyNotation` to `ModuleDependency` class cast exception if possible
if (configure != null) {
add(configurationName, dependencyNotation, closureOf(configure))
} else {
add(configurationName, dependencyNotation)
}
}
fun Project.disableDependencyVerification() {
configurations.all {
resolutionStrategy {
disableDependencyVerification()
}
}
}
fun DependencyHandler.jpsLikeJarDependency(
dependencyNotation: Any,
scope: JpsDepScope,
dependencyConfiguration: (ModuleDependency.() -> Unit)? = null,
exported: Boolean = false
) {
when (scope) {
JpsDepScope.COMPILE -> {
if (exported) {
add("api", dependencyNotation, dependencyConfiguration)
add("testCompile", dependencyNotation, dependencyConfiguration)
} else {
add("implementation", dependencyNotation, dependencyConfiguration)
}
}
JpsDepScope.TEST -> {
if (exported) {
add("testCompile", dependencyNotation, dependencyConfiguration)
} else {
add("testImplementation", dependencyNotation, dependencyConfiguration)
}
}
JpsDepScope.RUNTIME -> {
add("testRuntimeOnly", dependencyNotation, dependencyConfiguration)
}
JpsDepScope.PROVIDED -> {
if (exported) {
add("compileOnlyApi", dependencyNotation, dependencyConfiguration)
add("testCompile", dependencyNotation, dependencyConfiguration)
} else {
add("compileOnly", dependencyNotation, dependencyConfiguration)
add("testImplementation", dependencyNotation, dependencyConfiguration)
}
}
}
}
fun DependencyHandler.jpsLikeModuleDependency(moduleName: String, scope: JpsDepScope, exported: Boolean = false) {
jpsLikeJarDependency(project(moduleName), scope, exported = exported)
when (scope) {
JpsDepScope.COMPILE -> {
if (exported) {
add("testCompile", projectTests(moduleName))
} else {
add("testImplementation", projectTests(moduleName))
}
}
JpsDepScope.TEST -> {
if (exported) {
add("testCompile", projectTests(moduleName))
} else {
add("testImplementation", projectTests(moduleName))
}
}
JpsDepScope.RUNTIME -> {
add("runtimeOnly", projectTests(moduleName))
}
JpsDepScope.PROVIDED -> {
if (exported) {
add("testCompile", projectTests(moduleName))
} else {
add("testImplementation", projectTests(moduleName))
}
}
}
}
fun Project.testApiJUnit5(
vintageEngine: Boolean = false,
runner: Boolean = false,
@@ -289,16 +204,14 @@ fun Project.firstFromJavaHomeThatExists(vararg paths: String, jdkHome: File = Fi
fun Project.toolsJarApi(): Any =
if (kotlinBuildProperties.isInJpsBuildIdeaSync)
toolsJar()
files(toolsJarFile() ?: error("tools.jar is not found!"))
else
dependencies.project(":dependencies:tools-jar-api")
fun Project.toolsJar(): FileCollection = files(
getToolchainLauncherFor(JdkMajorVersion.JDK_1_8)
.map {
Jvm.forHome(it.metadata.installationPath.asFile).toolsJar ?: throw GradleException("tools.jar not found!")
}
)
fun Project.toolsJar(): FileCollection = files(toolsJarFile() ?: error("tools.jar is not found!"))
fun Project.toolsJarFile(jdkHome: File = File(this.property("JDK_18") as String)): File? =
firstFromJavaHomeThatExists("lib/tools.jar", jdkHome = jdkHome)
val compilerManifestClassPath
get() = "annotations-13.0.jar kotlin-stdlib.jar kotlin-reflect.jar kotlin-script-runtime.jar trove4j.jar"

View File

@@ -2,8 +2,6 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.Project
import org.gradle.api.artifacts.DependencySubstitution
import org.gradle.api.artifacts.component.ProjectComponentSelector
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
@@ -82,24 +80,6 @@ private fun Project.compilerShadowJar(taskName: String, body: ShadowJar.() -> Un
}
}
fun Project.configureShadowJarSubstitutionInCompileClasspath() {
val substitutionMap = mapOf(":kotlin-reflect" to ":kotlin-reflect-api")
fun configureSubstitution(substitution: DependencySubstitution) {
val requestedProject = (substitution.requested as? ProjectComponentSelector)?.projectPath ?: return
val replacementProject = substitutionMap[requestedProject] ?: return
substitution.useTarget(project(replacementProject), "Non-default shadow jars should not be used in compile classpath")
}
sourceSets.all {
for (configName in listOf(compileOnlyConfigurationName, compileClasspathConfigurationName)) {
configurations.getByName(configName).resolutionStrategy.dependencySubstitution {
all(::configureSubstitution)
}
}
}
}
fun Project.embeddableCompiler(taskName: String = "embeddable", body: ShadowJar.() -> Unit = {}): TaskProvider<out ShadowJar> =
compilerShadowJar(taskName) {
configureEmbeddableCompilerRelocation()
@@ -113,6 +93,7 @@ fun Project.compilerDummyForDependenciesRewriting(
exclude(packagesToExcludeFromDummy)
body()
}
const val COMPILER_DUMMY_JAR_CONFIGURATION_NAME = "compilerDummyJar"
fun Project.compilerDummyJar(task: TaskProvider<out Jar>, body: Jar.() -> Unit = {}) {

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2010-2021 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.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
}
publishGradlePlugin()
standardPublicJars()
extensions.extraProperties["kotlin.stdlib.default.dependency"] = "false"
dependencies {
compileOnly(kotlinStdlib())
compileOnly(gradleApi())
}
// These dependencies will be provided by Gradle and we should prevent version conflict
fun Configuration.excludeGradleCommonDependencies() {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk7")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk8")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-common")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-script-runtime")
}
configurations {
"implementation" {
excludeGradleCommonDependencies()
}
"api" {
excludeGradleCommonDependencies()
}
}
tasks.withType<KotlinCompile> {
kotlinOptions.languageVersion = "1.4"
kotlinOptions.apiVersion = "1.4"
kotlinOptions.freeCompilerArgs += listOf(
"-Xskip-prerelease-check",
"-Xskip-runtime-version-check",
"-Xsuppress-version-warnings",
"-Xuse-ir" // Needed as long as languageVersion is less than 1.5.
)
}
tasks.named<Jar>("jar") {
callGroovy("manifestAttributes", manifest, project)
}

View File

@@ -24,16 +24,16 @@ fun ProjectSettings.compiler(block: IdeaCompilerConfiguration.() -> Unit) =
fun ProjectSettings.delegateActions(block: ActionDelegationConfig.() -> Unit) =
(this@delegateActions as ExtensionAware).extensions.configure(block)
fun ProjectSettings.runConfigurations(block: RunConfigurationContainer.() -> Unit) =
fun ProjectSettings.runConfigurations(block: DefaultRunConfigurationContainer.() -> Unit) =
(this@runConfigurations as ExtensionAware).extensions.configure("runConfigurations", block)
inline fun <reified T: RunConfiguration> RunConfigurationContainer.defaults(noinline block: T.() -> Unit) =
inline fun <reified T: RunConfiguration> DefaultRunConfigurationContainer.defaults(noinline block: T.() -> Unit) =
defaults(T::class.java, block)
fun RunConfigurationContainer.junit(name: String, block: JUnit.() -> Unit) =
fun DefaultRunConfigurationContainer.junit(name: String, block: JUnit.() -> Unit) =
create(name, JUnit::class.java, block)
fun RunConfigurationContainer.application(name: String, block: Application.() -> Unit) =
fun DefaultRunConfigurationContainer.application(name: String, block: Application.() -> Unit) =
create(name, Application::class.java, block)
fun ProjectSettings.ideArtifacts(block: NamedDomainObjectContainer<org.jetbrains.gradle.ext.TopLevelArtifact>.() -> Unit) =

View File

@@ -0,0 +1,193 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import net.rubygrapefruit.platform.Native
import net.rubygrapefruit.platform.WindowsRegistry
import org.gradle.api.GradleException
import org.gradle.api.Project
import java.nio.file.Paths
import java.io.File
import net.rubygrapefruit.platform.WindowsRegistry.Key.HKEY_LOCAL_MACHINE
import org.gradle.internal.os.OperatingSystem
enum class JdkMajorVersion(private val mandatory: Boolean = true) {
JDK_16, JDK_17, JDK_18, JDK_9, JDK_10(false), JDK_11(false), /*15.0*/JDK_15(false);
fun isMandatory(): Boolean = mandatory
}
val jdkAlternativeVarNames = mapOf(JdkMajorVersion.JDK_9 to listOf("JDK_19"), JdkMajorVersion.JDK_15 to listOf("JDK_15_0"))
data class JdkId(val explicit: Boolean, val majorVersion: JdkMajorVersion, var version: String, var homeDir: File)
fun Project.getConfiguredJdks(): List<JdkId> {
val res = arrayListOf<JdkId>()
for (jdkMajorVersion in JdkMajorVersion.values()) {
val explicitJdkEnvVal = findProperty(jdkMajorVersion.name)?.toString()
?: System.getenv(jdkMajorVersion.name)
?: jdkAlternativeVarNames[jdkMajorVersion]?.mapNotNull { System.getenv(it) }?.firstOrNull()
?: continue
val explicitJdk = Paths.get(explicitJdkEnvVal).toRealPath().toFile()
if (!explicitJdk.isDirectory) {
throw GradleException("Invalid environment value $jdkMajorVersion: $explicitJdkEnvVal, expecting JDK home path")
}
res.add(JdkId(true, jdkMajorVersion, "X", explicitJdk))
}
if (res.size < JdkMajorVersion.values().size) {
res.discoverJdks(this)
}
return res
}
// see JEP 223
private val javaMajorVersionRegex = Regex("""(?:1\.)?(\d+).*""")
private val javaVersionRegex = Regex("""(?:1\.)?(\d+)(\.\d+)?([+-_]\w+){0,3}""")
fun MutableCollection<JdkId>.addIfBetter(project: Project, version: String, id: String, homeDir: File): Boolean {
val matchString = javaMajorVersionRegex.matchEntire(version)?.groupValues?.get(1)
val majorJdkVersion = when (matchString) {
"6" -> JdkMajorVersion.JDK_16
"7" -> JdkMajorVersion.JDK_17
"8" -> JdkMajorVersion.JDK_18
"9" -> JdkMajorVersion.JDK_9
else -> {
project.logger.info("Cannot recognize version string '$version' (found version '$matchString')")
return false
}
}
val prev = find { it.majorVersion == majorJdkVersion }
if (prev == null) {
add(JdkId(false, majorJdkVersion, version, homeDir))
return true
}
if (prev.explicit) return false
val versionsComparisonRes = compareVersions(prev.version, version)
if (versionsComparisonRes < 0 || (versionsComparisonRes == 0 && id.contains("64"))) { // prefer 64-bit
prev.version = version
prev.homeDir = homeDir
return true
}
return false
}
private fun compareVersions(left: String, right: String): Int {
if (left == right) return 0
fun MatchResult.extractNumVer(): List<Int> =
groups.drop(2).map {
it?.value?.filter { it in '0'..'9' }?.toIntOrNull() ?: 0
}
val lmi = (javaVersionRegex.matchEntire(left)?.extractNumVer() ?: emptyList()).iterator()
val rmi = (javaVersionRegex.matchEntire(right)?.extractNumVer() ?: emptyList()).iterator()
while (lmi.hasNext() && rmi.hasNext()) {
val l = lmi.next()
val r = rmi.next()
when {
l < r -> return -1
l > r -> return 1
}
}
return when {
rmi.hasNext() -> -1
lmi.hasNext() -> 1
else -> 0
}
}
fun MutableCollection<JdkId>.discoverJdks(project: Project) {
val os = OperatingSystem.current()
when {
os.isWindows -> discoverJdksOnWindows(project)
os.isMacOsX -> discoverJdksOnMacOS(project)
else -> discoverJdksOnUnix(project)
}
}
private val macOsJavaHomeOutRegexes =
listOf(
Regex("""\s+(\S+),\s+(\S+):\s+".*?"\s+(.+)"""),
Regex("""\s+(\S+)\s+\((.*?)\):\s+(.+)"""),
Regex("""\s+(\S+)\s+\((.*?)\)\s+"[^"]*"\s+-\s+"[^"]*"\s(.+)"""),
Regex("""\s+(\S+)\s+\((.+)\)\s+".+"\s+-\s+".+"\s+(.+)"""))
fun MutableCollection<JdkId>.discoverJdksOnMacOS(project: Project) {
val procBuilder = ProcessBuilder("/usr/libexec/java_home", "-V").redirectErrorStream(true)
val process = procBuilder.start()
val retCode = process.waitFor()
if (retCode != 0) throw GradleException("Unable to run 'java_home', return code $retCode")
process.inputStream.bufferedReader().forEachLine { line ->
for (rex in macOsJavaHomeOutRegexes) {
val matchResult = rex.matchEntire(line)
if (matchResult != null) {
addIfBetter(project, matchResult.groupValues[1], matchResult.groupValues[0], File(matchResult.groupValues[3]))
break
}
}
}
}
private val unixConventionalJdkLocations = listOf(
"/usr/lib/jvm", // *deb, Arch
"/opt", // *rpm, Gentoo, HP/UX
"/usr/lib", // Slackware 32
"/usr/lib64", // Slackware 64
"/usr/local", // OpenBSD, FreeBSD
"/usr/pkg/java", // NetBSD
"/usr/jdk/instances") // Solaris
private val unixConventionalJdkDirRex = Regex("jdk|jre|java|zulu")
fun MutableCollection<JdkId>.discoverJdksOnUnix(project: Project) {
for (loc in unixConventionalJdkLocations) {
val installedJdks = File(loc).listFiles { dir ->
dir.isDirectory &&
unixConventionalJdkDirRex.containsMatchIn(dir.name) &&
fileFrom(dir, "bin", "java").isFile
} ?: continue
for (dir in installedJdks) {
val versionMatch = javaVersionRegex.find(dir.name)
if (versionMatch == null) {
project.logger.info("Unable to extract version from possible JDK dir: $dir")
}
else {
addIfBetter(project, versionMatch.value, dir.name, dir)
}
}
}
}
private val windowsConventionalJdkRegistryPaths = listOf(
"SOFTWARE\\JavaSoft\\Java Development Kit",
"SOFTWARE\\Wow6432Node\\JavaSoft\\Java Development Kit",
"SOFTWARE\\JavaSoft\\JDK",
"SOFTWARE\\Wow6432Node\\JavaSoft\\JDK")
fun MutableCollection<JdkId>.discoverJdksOnWindows(project: Project) {
val registry = Native.get(WindowsRegistry::class.java)
for (regPath in windowsConventionalJdkRegistryPaths) {
val jdkKeys = try {
registry.getSubkeys(HKEY_LOCAL_MACHINE, regPath)
} catch (e: RuntimeException) {
// ignore missing nodes
continue
}
for (jdkKey in jdkKeys) {
try {
val javaHome = registry.getStringValue(HKEY_LOCAL_MACHINE, regPath + "\\" + jdkKey, "JavaHome")
val versionMatch = javaVersionRegex.find(jdkKey)
if (versionMatch == null) {
project.logger.info("Unable to extract version from possible JDK location: $javaHome ($jdkKey)")
}
else {
javaHome.takeIf { it.isNotEmpty() }
?.let { File(it) }
?.takeIf { it.isDirectory && fileFrom(it, "bin", "java.exe").isFile }
?.let {
addIfBetter(project, versionMatch.value, jdkKey, it)
}
}
}
catch (e: RuntimeException) {
// Ignore
}
}
}
}

View File

@@ -17,11 +17,16 @@
// usages in build scripts are not tracked properly
@file:Suppress("unused")
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.register
import java.io.File
private fun Project.kotlinBuildLocalDependenciesDir(): File =
@@ -30,26 +35,16 @@ private fun Project.kotlinBuildLocalDependenciesDir(): File =
private fun Project.kotlinBuildLocalRepoDir(): File = kotlinBuildLocalDependenciesDir().resolve("repo")
fun Project.ideModuleName() = when (IdeVersionConfigurator.currentIde.kind) {
private fun Project.ideModuleName() = when (IdeVersionConfigurator.currentIde.kind) {
Ide.Kind.AndroidStudio -> "android-studio-ide"
Ide.Kind.IntelliJ -> "ideaIC"
}
private fun Project.ideModuleVersion(forIde: Boolean) = when (IdeVersionConfigurator.currentIde.kind) {
Ide.Kind.AndroidStudio -> rootProject.findProperty("versions.androidStudioBuild")
Ide.Kind.IntelliJ -> {
if (forIde) {
intellijSdkVersionForIde()
?: error("Please specify 'attachedIntellijVersion' in your local.properties")
} else {
rootProject.findProperty("versions.intellijSdk")
}
if (kotlinBuildProperties.intellijUltimateEnabled) "ideaIU" else "ideaIC"
}
}
fun Project.intellijSdkVersionForIde(): String? {
val majorVersion = kotlinBuildProperties.getOrNull("attachedIntellijVersion") as? String ?: return null
return rootProject.findProperty("versions.intellijSdk.forIde.$majorVersion") as? String
private fun Project.ideModuleVersion() = when (IdeVersionConfigurator.currentIde.kind) {
Ide.Kind.AndroidStudio -> rootProject.findProperty("versions.androidStudioBuild")
Ide.Kind.IntelliJ -> rootProject.findProperty("versions.intellijSdk")
}
fun RepositoryHandler.kotlinBuildLocalRepo(project: Project): IvyArtifactRepository = ivy {
@@ -63,7 +58,6 @@ fun RepositoryHandler.kotlinBuildLocalRepo(project: Project): IvyArtifactReposit
artifact("[organisation]/[module]/[revision]/artifacts/lib/[artifact](-[classifier]).[ext]")
artifact("[organisation]/[module]/[revision]/artifacts/[artifact](-[classifier]).[ext]")
artifact("[organisation]/intellij-core/[revision]/artifacts/[artifact](-[classifier]).[ext]")
artifact("[organisation]/${project.ideModuleName()}/[revision]/artifacts/plugins/[module]/lib/[artifact](-[classifier]).[ext]") // bundled plugins
artifact("[organisation]/sources/[artifact]-[revision](-[classifier]).[ext]")
artifact("[organisation]/[module]/[revision]/[artifact](-[classifier]).[ext]")
@@ -74,9 +68,7 @@ fun RepositoryHandler.kotlinBuildLocalRepo(project: Project): IvyArtifactReposit
}
}
@JvmOverloads
fun Project.intellijDep(module: String? = null, forIde: Boolean = false) =
"kotlin.build:${module ?: ideModuleName()}:${ideModuleVersion(forIde)}"
fun Project.intellijDep(module: String? = null) = "kotlin.build:${module ?: ideModuleName()}:${ideModuleVersion()}"
fun Project.intellijCoreDep() = "kotlin.build:intellij-core:${rootProject.extra["versions.intellijSdk"]}"
@@ -101,7 +93,11 @@ fun Project.kotlinxCollectionsImmutable() = "org.jetbrains.kotlinx:kotlinx-colle
*/
fun Project.intellijRuntimeAnnotations() = "kotlin.build:intellij-runtime-annotations:${rootProject.extra["versions.intellijSdk"]}"
fun Project.intellijPluginDep(plugin: String, forIde: Boolean = false) = intellijDep(plugin, forIde)
fun Project.intellijPluginDep(plugin: String) = intellijDep(plugin)
fun Project.intellijUltimateDep() = intellijDep("ideaIU")
fun Project.intellijUltimatePluginDep(plugin: String) = intellijDep(plugin)
fun ModuleDependency.includeJars(vararg names: String, rootProject: Project? = null) {
names.forEach {
@@ -129,7 +125,7 @@ object IntellijRootUtils {
fun getIntellijRootDir(project: Project): File = with(project.rootProject) {
return File(
getRepositoryRootDir(this),
"${ideModuleName()}/${ideModuleVersion(forIde = false)}/artifacts"
"${ideModuleName()}/${ideModuleVersion()}/artifacts"
)
}
}
@@ -141,4 +137,83 @@ fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project, jarsFi
rootProject = project.rootProject
)
fun Project.intellijRootDir() = IntellijRootUtils.getIntellijRootDir(project)
fun Project.isIntellijCommunityAvailable() =
!(rootProject.extra["intellijUltimateEnabled"] as Boolean) || rootProject.extra["intellijSeparateSdks"] as Boolean
fun Project.isIntellijUltimateSdkAvailable() = (rootProject.extra["intellijUltimateEnabled"] as Boolean)
fun Project.intellijRootDir() = IntellijRootUtils.getIntellijRootDir(project)
fun Project.intellijUltimateRootDir() =
if (isIntellijUltimateSdkAvailable())
File(kotlinBuildLocalRepoDir(), "kotlin.build/ideaIU/${rootProject.extra["versions.intellijSdk"]}/artifacts")
else
throw GradleException("intellij ultimate SDK is not available")
fun DependencyHandlerScope.excludeInAndroidStudio(rootProject: Project, block: DependencyHandlerScope.() -> Unit) {
if (!rootProject.extra.has("versions.androidStudioRelease")) {
block()
}
}
fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File, body: JavaExec.() -> Unit): TaskProvider<JavaExec> {
return tasks.register<JavaExec>(name) {
val ideaSandboxConfigDir = File(ideaSandboxDir, "config")
classpath = mainSourceSet.runtimeClasspath
mainClass.set("com.intellij.idea.Main")
workingDir = File(intellijRootDir(), "bin")
jvmArgs(
"-Xmx1250m",
"-XX:ReservedCodeCacheSize=240m",
"-XX:+HeapDumpOnOutOfMemoryError",
"-ea",
"-Didea.debug.mode=true",
"-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()) {
jvmArgs("-Didea.platform.prefix=Idea")
}
if (rootProject.findProperty("versions.androidStudioRelease") != null) {
jvmArgs("-Didea.platform.prefix=AndroidStudio")
}
if (project.hasProperty("noPCE")) {
jvmArgs("-Didea.ProcessCanceledException=disabled")
}
jvmArgs("-Didea.is.internal=${project.findProperty("idea.is.internal") ?: true}")
project.findProperty("idea.args")?.let { arguments ->
jvmArgs(arguments.toString().split(" "))
}
args()
doFirst {
val disabledPluginsFile = File(ideaSandboxConfigDir, "disabled_plugins.txt")
val disabledPluginsContents = disabledPluginsFile.takeIf { it.isFile }?.readLines()
val filteredContents = disabledPluginsContents?.filterNot { it.contains("org.jetbrains.kotlin") }
if (filteredContents != null && filteredContents.size != disabledPluginsContents.size) {
with(disabledPluginsFile.printWriter()) {
filteredContents.forEach(this::println)
}
}
}
body()
}
}

View File

@@ -14,7 +14,6 @@ import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.*
import plugins.KotlinBuildPublishingPlugin
import plugins.configureRepository
import plugins.mainPublicationName
import java.util.*
internal const val PLUGIN_MARKER_SUFFIX = ".gradle.plugin"
@@ -27,7 +26,7 @@ fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
val pluginDevelopment = extensions.getByType<PluginBundleExtension>()
val publishingExtension = extensions.getByType<PublishingExtension>()
val mainPublication = publishingExtension.publications[mainPublicationName] as MavenPublication
val mainPublication = publishingExtension.publications[KotlinBuildPublishingPlugin.PUBLICATION_NAME] as MavenPublication
pluginDevelopment.plugins.forEach { declaration ->
val markerPublication = createMavenMarkerPublication(declaration, mainPublication, publishingExtension.publications)

View File

@@ -68,7 +68,7 @@ class KotlinBuildPublishingPlugin @Inject constructor(
configure<PublishingExtension> {
publications {
create<MavenPublication>(project.mainPublicationName) {
create<MavenPublication>(PUBLICATION_NAME) {
from(kotlinLibraryComponent)
configureKotlinPomAttributes(project)
@@ -79,26 +79,16 @@ class KotlinBuildPublishingPlugin @Inject constructor(
}
companion object {
const val DEFAULT_MAIN_PUBLICATION_NAME = "Main"
const val MAIN_PUBLICATION_NAME_PROPERTY = "MainPublicationName"
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"
}
}
var Project.mainPublicationName: String
get() {
return if (project.extra.has(KotlinBuildPublishingPlugin.MAIN_PUBLICATION_NAME_PROPERTY))
project.extra.get(KotlinBuildPublishingPlugin.MAIN_PUBLICATION_NAME_PROPERTY) as String
else KotlinBuildPublishingPlugin.DEFAULT_MAIN_PUBLICATION_NAME
}
set(value) {
project.extra.set(KotlinBuildPublishingPlugin.MAIN_PUBLICATION_NAME_PROPERTY, value)
}
@OptIn(ExperimentalStdlibApi::class)
private fun humanReadableName(name: String) =
name.split("-").joinToString(separator = " ") { it.capitalize(Locale.ROOT) }
@@ -174,17 +164,7 @@ fun Project.configureDefaultPublishing() {
private fun Project.configureSigning() {
configure<SigningExtension> {
sign(extensions.getByType<PublishingExtension>().publications) // all publications
val signKeyId = project.findProperty("signKeyId") as? String
if (!signKeyId.isNullOrBlank()) {
val signKeyPrivate = project.findProperty("signKeyPrivate") as? String
?: error("Parameter `signKeyPrivate` not found")
val signKeyPassphrase = project.findProperty("signKeyPassphrase") as? String
?: error("Parameter `signKeyPassphrase` not found")
useInMemoryPgpKeys(signKeyId, signKeyPrivate, signKeyPassphrase)
} else {
useGpgCmd()
}
useGpgCmd()
}
}

View File

@@ -0,0 +1,173 @@
@file:Suppress("DEPRECATION")
package plugins
import org.codehaus.groovy.runtime.InvokerHelper
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.maven.Conf2ScopeMappingContainer
import org.gradle.api.artifacts.maven.MavenDeployment
import org.gradle.api.artifacts.maven.MavenResolver
import org.gradle.api.plugins.MavenPluginConvention
import org.gradle.api.plugins.MavenRepositoryHandlerConvention
import org.gradle.api.publication.maven.internal.deployer.MavenRemoteRepository
import org.gradle.api.tasks.Upload
import org.gradle.kotlin.dsl.*
import org.gradle.plugins.signing.Sign
import org.gradle.plugins.signing.SigningExtension
import kotlin.properties.Delegates
/**
* Configures a Kotlin module for publication.
*/
open class PublishedKotlinModule : Plugin<Project> {
private fun String.toBooleanOrNull() = listOf(true, false).firstOrNull { it.toString().equals(this, ignoreCase = true) }
override fun apply(project: Project) {
project.run {
plugins.apply("maven")
configurations.maybeCreate("publishedRuntime").apply {
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")
val signingRequired = project.findProperty("signingRequired")?.toString()?.toBooleanOrNull()
?: project.property("isSonatypeRelease") as Boolean
configure<SigningExtension> {
isRequired = signingRequired
sign(configurations["archives"])
useGpgCmd()
}
tasks.named<Sign>("signArchives").configure {
enabled = signingRequired
}
}
fun MavenResolver.configurePom() {
pom.project {
withGroovyBuilder {
"licenses" {
"license" {
"name"("The Apache Software License, Version 2.0")
"url"("http://www.apache.org/licenses/LICENSE-2.0.txt")
"distribution"("repo")
}
}
"name"("${project.group}:${project.name}")
"packaging"("jar")
// optionally artifactId can be defined here
"description"(project.description)
"url"("https://kotlinlang.org/")
"licenses" {
"license" {
"name"("The Apache License, Version 2.0")
"url"("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
"scm" {
"url"("https://github.com/JetBrains/kotlin")
"connection"("scm:git:https://github.com/JetBrains/kotlin.git")
"developerConnection"("scm:git:https://github.com/JetBrains/kotlin.git")
}
"developers" {
"developer" {
"name"("Kotlin Team")
setProperty("organization", "JetBrains")
"organizationUrl"("https://www.jetbrains.com")
}
}
}
}
pom.whenConfigured {
dependencies.removeIf {
InvokerHelper.getMetaClass(it).getProperty(it, "scope") == "test"
}
dependencies
.find {
InvokerHelper.getMetaClass(it).getProperty(it, "groupId") == "org.jetbrains.kotlin"
&& InvokerHelper.getMetaClass(it).getProperty(it, "artifactId") == "kotlin-stdlib"
}
?.also {
InvokerHelper.getMetaClass(it).setProperty(it, "exclusions", emptyList<Any>())
logger.warn("WARNING! Removed exclusions from kotlin-stdlib dependency of ${this.artifactId} artifact's maven metadata, check kotlin-stdlib dependency of ${project.path} project")
}
}
}
tasks.named<Upload>("uploadArchives").configure {
val preparePublication = project.rootProject.tasks.named("preparePublication").get()
dependsOn(preparePublication)
val username: String? by preparePublication.extra
val password: String? by preparePublication.extra
val repoUrl: String by preparePublication.extra
var repository by Delegates.notNull<MavenRemoteRepository>()
repositories {
withConvention(MavenRepositoryHandlerConvention::class) {
mavenDeployer {
withGroovyBuilder {
"beforeDeployment" {
val signing = project.the<SigningExtension>()
if (signing.isRequired)
signing.signPom(delegate as MavenDeployment)
}
"repository"("url" to repoUrl)!!.also { repository = it as MavenRemoteRepository }.withGroovyBuilder {
if (username != null && password != null) {
"authentication"("userName" to username, "password" to password)
}
}
}
configurePom()
}
}
}
doFirst {
repository.url = repoUrl
}
}
val install = if (tasks.names.contains("install")) tasks.getByName("install") as Upload
else tasks.create("install", Upload::class.java)
install.apply {
configuration = project.configurations.getByName(Dependency.ARCHIVES_CONFIGURATION)
description = "Installs the 'archives' artifacts into the local Maven repository."
repositories {
withConvention(MavenRepositoryHandlerConvention::class) {
mavenInstaller {
configurePom()
}
}
}
}
tasks.register("publish") {
dependsOn(tasks.named("uploadArchives"))
}
}
}
}

View File

@@ -194,7 +194,9 @@ fun Project.projectTest(
systemProperty("kotlin.ni", if (project.rootProject.hasProperty("newInferenceTests")) "true" else "false")
systemProperty("org.jetbrains.kotlin.skip.muted.tests", if (project.rootProject.hasProperty("skipMutedTests")) "true" else "false")
systemProperty("idea.ignore.disabled.plugins", "true")
if (Platform[202].orHigher()) {
systemProperty("idea.ignore.disabled.plugins", "true")
}
var subProjectTempRoot: Path? = null
val projectName = project.name

View File

@@ -9,13 +9,13 @@ import org.gradle.internal.os.OperatingSystem
fun Test.configureTestDistribution(configure: TestDistributionExtension.() -> Unit = {}) {
if (extensions.findByType(TestDistributionExtension::class.java) == null) return
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
val testDistributionEnabled =
project.findProperty("kotlin.build.test.distribution.enabled")?.toString()?.toBoolean() ?: false
useJUnitPlatform()
extensions.configure(TestDistributionExtension::class.java) {
enabled.set(testDistributionEnabled)
enabled.set(true)
maxRemoteExecutors.set(20)
if (isTeamcityBuild) {
requirements.set(setOf("os=${OperatingSystem.current().familyName}"))

View File

@@ -24,18 +24,24 @@ dependencies {
testApi(projectTests(":compiler:tests-compiler-utils"))
testApi(projectTests(":compiler:tests-common-new"))
testCompile(projectTests(":jps-plugin"))
testCompile(commonDep("junit:junit"))
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", rootProject = rootProject) }
testCompile(intellijDep()) { includeJars("groovy", rootProject = rootProject) }
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(intellijPluginDep("java")) { includeJars("jps-builders") }
testCompile(jpsStandalone()) { includeJars("jps-model") }
testCompile(jpsBuildTest())
testRuntimeOnly(compile(intellijCoreDep()) { includeJars("intellij-core") })
testRuntimeOnly(compile(intellijDep()) { includeJars("jna", rootProject = rootProject) })
testCompile("org.junit.platform:junit-platform-launcher:${commonVer("org.junit.platform", "")}")
}

View File

@@ -354,8 +354,8 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
extractor.provideConfigurationKeys()
extractor.configure(keyConfiguration, module.directives)
}
val kind = JvmEnvironmentConfigurator.extractConfigurationKind(module.directives)
val jdkKind = JvmEnvironmentConfigurator.extractJdkKind(module.directives)
val kind = configuratorForFlags.extractConfigurationKind(module.directives)
val jdkKind = configuratorForFlags.extractJdkKind(module.directives)
keyConfiguration.languageVersionSettings = module.languageVersionSettings

Some files were not shown because too many files have changed in this diff Show More