Compare commits

..

3 Commits

Author SHA1 Message Date
Kirill Shmakov
8d407fa264 One more fix 2020-11-06 19:16:07 +03:00
Kirill Shmakov
8318d6a1f4 Undo extra changes 2020-11-06 18:53:38 +03:00
Kirill Shmakov
20aef55012 Make mpp tests gutters aware of different platforms run
Behaviour is similar to the test suite gutters:
- simple triangle when there is no history
- triangle + red circle if some runs failed
- triangle + green circle if all runs passed

#KMM-100 Fixed.
2020-11-06 11:49:59 +03:00
20333 changed files with 327308 additions and 811571 deletions

9
.bunch
View File

@@ -1,4 +1,7 @@
202
201
as41_201
as42
202
203_202
193
as40_193
as41
as42_202

2
.gitignore vendored
View File

@@ -62,5 +62,3 @@ local.properties
buildSrcTmp/
distTmp/
outTmp/
/test.output
/kotlin-native/dist

View File

@@ -1,8 +0,0 @@
<component name="ArtifactManager">
<artifact type="jar" name="kotlinx.cli-jvm-1.5.255-SNAPSHOT">
<output-path>$PROJECT_DIR$/kotlin-native/endorsedLibraries/kotlinx.cli/build/libs</output-path>
<root id="archive" name="kotlinx.cli-jvm-1.5.255-SNAPSHOT.jar">
<element id="module-output" name="kotlin.kotlin-native.endorsedLibraries.kotlinx.cli.jvmMain" />
</root>
</artifact>
</component>

View File

@@ -101,4 +101,4 @@
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
</codeStyleSettings>
</code_scheme>
</component>
</component>

View File

@@ -10,7 +10,6 @@
<w>commonizers</w>
<w>commonizes</w>
<w>commonizing</w>
<w>interop</w>
<w>jetbrains</w>
<w>konan</w>
<w>kotlinx</w>

View File

@@ -1,27 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="svyatoslav.kuzmich">
<words>
<w>anyfunc</w>
<w>copysign</w>
<w>eqref</w>
<w>exnref</w>
<w>externref</w>
<w>funcref</w>
<w>jetbrains</w>
<w>kotlinx</w>
<w>ktor</w>
<w>optref</w>
<w>popcnt</w>
<w>rotl</w>
<w>rotr</w>
<w>simd</w>
<w>sqrt</w>
<w>testsuite</w>
<w>uninstantiable</w>
<w>unlinkable</w>
<w>vtable</w>
<w>wabt</w>
<w>xopt</w>
</words>
</dictionary>
</component>

View File

@@ -453,4 +453,4 @@
<option name="ignoreNonEmtpyLoops" value="false" />
</inspection_tool>
</profile>
</component>
</component>

4
.idea/misc.xml generated
View File

@@ -12,14 +12,10 @@
<item index="2" class="java.lang.String" itemvalue="org.gradle.api.tasks.options.Option" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="IdProvider" IDEtalkID="71A301FF1940049D6D82F12C40F1E1D5" />
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="JavadocGenerationManager">
<option name="OTHER_OPTIONS" value="" />
</component>

View File

@@ -10,7 +10,7 @@
</option>
<option name="taskNames">
<list>
<option value=":compiler:tests-for-compiler-generator:generateTests" />
<option value=":compiler:generateTests" />
<option value=":compiler:tests-java8:generateTests" />
<option value=":compiler:tests-against-klib:generateTests" />
<option value=":js:js.tests:generateTests" />
@@ -22,4 +22,4 @@
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<method />
</configuration>
</component>
</component>

View File

@@ -1,24 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Generate FIR Checker Components and FIR/IDE Diagnostics" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":compiler:fir:checkers:generateCheckersComponents" />
<option value=":idea:idea-frontend-fir:generateCode" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>

10623
ChangeLog.md

File diff suppressed because it is too large Load Diff

View File

@@ -2,14 +2,10 @@
[![TeamCity (simple build status)](https://img.shields.io/teamcity/http/teamcity.jetbrains.com/s/Kotlin_KotlinPublic_Compiler.svg)](https://teamcity.jetbrains.com/buildConfiguration/Kotlin_KotlinPublic_Compiler?branch=%3Cdefault%3E&buildTypeTab=overview&mode=builds)
[![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlin/kotlin-maven-plugin.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.jetbrains.kotlin%22)
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)
[![Revved up by Gradle Enterprise](https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.jetbrains.com/scans?search.rootProjectNames=Kotlin)
# Kotlin Programming Language
Welcome to [Kotlin](https://kotlinlang.org/)!
It is an open-source, statically typed programming language supported and developed by [JetBrains](https://www.jetbrains.com/) and open-source contributors.
Some handy links:
Welcome to [Kotlin](https://kotlinlang.org/)! Some handy links:
* [Kotlin Site](https://kotlinlang.org/)
* [Getting Started Guide](https://kotlinlang.org/docs/tutorials/getting-started.html)
@@ -18,7 +14,6 @@ Some handy links:
* [Issue Tracker](https://youtrack.jetbrains.com/issues/KT)
* [Forum](https://discuss.kotlinlang.org/)
* [Kotlin Blog](https://blog.jetbrains.com/kotlin/)
* [Subscribe to Kotlin YouTube channel](https://www.youtube.com/channel/UCP7uiEZIqci43m22KDl0sNw)
* [Follow Kotlin on Twitter](https://twitter.com/kotlin)
* [Public Slack channel](https://slack.kotlinlang.org/)
* [TeamCity CI build](https://teamcity.jetbrains.com/project.html?tab=projectOverview&projectId=Kotlin)
@@ -59,8 +54,8 @@ You also can use [Gradle properties](https://docs.gradle.org/current/userguide/b
Note: The JDK 6 for MacOS is not available on Oracle's site. You can install it by
```bash
$ brew tap homebrew/cask-versions
$ brew install --cask java6
$ brew tap caskroom/versions
$ brew cask install java6
```
On Windows you might need to add long paths setting to the repo:
@@ -109,13 +104,13 @@ Refer to [libraries/ReadMe.md](libraries/ReadMe.md) for details.
### Building for different versions of IntelliJ IDEA and Android Studio
Kotlin plugin is intended to work with several recent versions of IntelliJ IDEA and Android Studio. Each platform is allowed to have a different set of features and might provide a slightly different API. Instead of using several parallel Git branches, the project stores everything in a single branch, but files may have counterparts with version extensions (\*.as32, \*.172, \*.181). The primary file is expected to be replaced with its counterpart when targeting a non-default platform.
Kotlin plugin is intended to work with several recent versions of IntelliJ IDEA and Android Studio. Each platform is allowed to have a different set of features and might provide a slightly different API. Instead of using several parallel Git branches, project stores everything in a single branch, but files may have counterparts with version extensions (\*.as32, \*.172, \*.181). The primary file is expected to be replaced with its counterpart when targeting non-default platform.
A More detailed description of this scheme can be found at https://github.com/JetBrains/bunches/blob/master/ReadMe.md.
More detailed description of this scheme can be found at https://github.com/JetBrains/bunches/blob/master/ReadMe.md.
Usually, there's no need to care about multiple platforms as all features are enabled everywhere by default. Additional counterparts should be created if there's an expected difference in behavior or an incompatible API usage is required **and** there's no reasonable workaround to save source compatibility. Kotlin plugin contains a pre-commit check that shows a warning if a file has been updated without its counterparts.
Development for some particular platform is possible after 'switching' that can be done with the [Bunch Tool](https://github.com/JetBrains/bunches/releases) from the command line.
Development for some particular platform is possible after 'switching' that can be done with [Bunch Tool](https://github.com/JetBrains/bunches/releases) from the command line.
```sh
cd kotlin-project-dir

View File

@@ -16,24 +16,18 @@
package org.jetbrains.kotlin.ant
import org.apache.tools.ant.BuildException
import org.apache.tools.ant.taskdefs.Execute
import org.apache.tools.ant.taskdefs.Redirector
import org.apache.tools.ant.types.*
import org.apache.tools.ant.types.Path
import org.apache.tools.ant.types.Reference
import java.io.File.pathSeparator
import java.io.File.separator
class Kotlin2JvmTask : KotlinCompilerBaseTask() {
override val compilerFqName = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"
var includeRuntime: Boolean = false
var includeRuntime: Boolean = true
var moduleName: String? = null
var noReflect: Boolean = false
private val cmdl = CommandlineJava()
var fork: Boolean = false
private var compileClasspath: Path? = null
fun setClasspath(classpath: Path) {
@@ -79,47 +73,4 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() {
if (noReflect) args.add("-no-reflect")
if (includeRuntime) args.add("-include-runtime")
}
override fun execute() {
if (!fork)
super.execute()
else {
exec()
}
}
private fun exec() {
val javaHome = System.getProperty("java.home")
val javaBin = javaHome + separator + "bin" + separator + "java"
val redirector = Redirector(this)
fillArguments()
val command = ArrayList<String>()
command.add(javaBin)
command.addAll(cmdl.vmCommand.arguments) // jvm args
command.add("-Dorg.jetbrains.kotlin.cliMessageRenderer=FullPath") // same MessageRenderer as non-forking mode
command.add("-cp")
command.add(KotlinAntTaskUtil.compilerJar.canonicalPath)
command.add(compilerFqName)
command.addAll(args) // compiler args
// streamHandler: used to handle the input and output streams of the subprocess.
// watchdog: a watchdog for the subprocess or <code>null</code> to disable a timeout for the subprocess.
// TODO: support timeout for the subprocess
val exe = Execute(redirector.createHandler(), null)
exe.setAntRun(getProject())
exe.commandline = command.toTypedArray()
log("Executing command: ${command.joinToString(" ")}", LogLevel.DEBUG.level)
log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]")
val exitCode = exe.execute()
redirector.complete()
if (failOnError && exitCode != 0) {
throw BuildException("Compile failed; see the compiler error output for details.")
}
}
fun createJvmarg(): Commandline.Argument {
return cmdl.createVmArgument()
}
}

View File

@@ -80,7 +80,7 @@ abstract class KotlinCompilerBaseTask : Task() {
fillSpecificArguments()
}
override fun execute() {
final override fun execute() {
fillArguments()
val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName)

View File

@@ -40,7 +40,9 @@ dependencies {
compile(project(":compiler:cli"))
compile(intellijCoreDep()) { includeJars("intellij-core") }
compile(jpsStandalone()) { includeJars("jps-model") }
compile(intellijPluginDep("java"))
Platform[192].orHigher {
compile(intellijPluginDep("java"))
}
compile(intellijDep()) { includeIntellijCoreJarDependencies(project) }
compile("org.jetbrains.kotlinx:kotlinx.benchmark.runtime-jvm:$benchmarks_version")
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,9 @@ interface BuildMetaInfo {
val compilerBuildVersion: String
val languageVersionString: String
val apiVersionString: String
val coroutinesEnable: Boolean
val coroutinesWarn: Boolean
val coroutinesError: Boolean
val multiplatformEnable: Boolean
val metadataVersionMajor: Int
val metadataVersionMinor: Int
@@ -32,6 +35,9 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
compilerBuildVersion: String,
languageVersionString: String,
apiVersionString: String,
coroutinesEnable: Boolean,
coroutinesWarn: Boolean,
coroutinesError: Boolean,
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
@@ -47,6 +53,9 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
compilerBuildVersion = KotlinCompilerVersion.VERSION,
languageVersionString = languageVersion.versionString,
apiVersionString = args.apiVersion ?: languageVersion.versionString,
coroutinesEnable = args.coroutinesState == CommonCompilerArguments.ENABLE,
coroutinesWarn = args.coroutinesState == CommonCompilerArguments.WARN,
coroutinesError = args.coroutinesState == CommonCompilerArguments.ERROR,
multiplatformEnable = args.multiPlatform,
ownVersion = OWN_VERSION,
coroutinesVersion = COROUTINES_VERSION,

View File

@@ -15,6 +15,9 @@ data class CommonBuildMetaInfo(
override val compilerBuildVersion: String,
override val languageVersionString: String,
override val apiVersionString: String,
override val coroutinesEnable: Boolean,
override val coroutinesWarn: Boolean,
override val coroutinesError: Boolean,
override val multiplatformEnable: Boolean,
override val metadataVersionMajor: Int,
override val metadataVersionMinor: Int,
@@ -29,6 +32,9 @@ data class CommonBuildMetaInfo(
compilerBuildVersion: String,
languageVersionString: String,
apiVersionString: String,
coroutinesEnable: Boolean,
coroutinesWarn: Boolean,
coroutinesError: Boolean,
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
@@ -41,6 +47,9 @@ data class CommonBuildMetaInfo(
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = metadataVersion.major,
metadataVersionMinor = metadataVersion.minor,

View File

@@ -1,12 +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.build
import java.io.Serializable
enum class ExecutionStrategy : Serializable {
DAEMON, IN_PROCESS, OUT_OF_PROCESS
}

View File

@@ -15,6 +15,9 @@ data class JsBuildMetaInfo(
override val compilerBuildVersion: String,
override val languageVersionString: String,
override val apiVersionString: String,
override val coroutinesEnable: Boolean,
override val coroutinesWarn: Boolean,
override val coroutinesError: Boolean,
override val multiplatformEnable: Boolean,
override val metadataVersionMajor: Int,
override val metadataVersionMinor: Int,
@@ -29,6 +32,9 @@ data class JsBuildMetaInfo(
compilerBuildVersion: String,
languageVersionString: String,
apiVersionString: String,
coroutinesEnable: Boolean,
coroutinesWarn: Boolean,
coroutinesError: Boolean,
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
@@ -41,6 +47,9 @@ data class JsBuildMetaInfo(
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = metadataVersion.major,
metadataVersionMinor = metadataVersion.minor,

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.build
import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
/**
@@ -27,6 +27,9 @@ data class JvmBuildMetaInfo(
override val compilerBuildVersion: String,
override val languageVersionString: String,
override val apiVersionString: String,
override val coroutinesEnable: Boolean,
override val coroutinesWarn: Boolean,
override val coroutinesError: Boolean,
override val multiplatformEnable: Boolean,
override val metadataVersionMajor: Int,
override val metadataVersionMinor: Int,
@@ -44,6 +47,9 @@ data class JvmBuildMetaInfo(
compilerBuildVersion: String,
languageVersionString: String,
apiVersionString: String,
coroutinesEnable: Boolean,
coroutinesWarn: Boolean,
coroutinesError: Boolean,
multiplatformEnable: Boolean,
ownVersion: Int,
coroutinesVersion: Int,
@@ -56,6 +62,9 @@ data class JvmBuildMetaInfo(
compilerBuildVersion = compilerBuildVersion,
languageVersionString = languageVersionString,
apiVersionString = apiVersionString,
coroutinesEnable = coroutinesEnable,
coroutinesWarn = coroutinesWarn,
coroutinesError = coroutinesError,
multiplatformEnable = multiplatformEnable,
metadataVersionMajor = metadataVersion.major,
metadataVersionMinor = metadataVersion.minor,

View File

@@ -1,24 +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.build.report
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.RemoteBuildMetricsReporter
open class BuildReporter(
protected open val icReporter: ICReporter,
protected open val buildMetricsReporter: BuildMetricsReporter
) : ICReporter by icReporter, BuildMetricsReporter by buildMetricsReporter
class RemoteBuildReporter(
override val icReporter: RemoteICReporter,
override val buildMetricsReporter: RemoteBuildMetricsReporter
) : BuildReporter(icReporter, buildMetricsReporter), RemoteReporter {
override fun flush() {
icReporter.flush()
buildMetricsReporter.flush()
}
}

View File

@@ -1,9 +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.build.report
interface RemoteICReporter : ICReporter,
RemoteReporter

View File

@@ -1,11 +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.build.report
interface RemoteReporter {
fun flush()
}

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.build.report.metrics
import java.io.Serializable
enum class BuildAttributeKind : Serializable {
REBUILD_REASON;
companion object {
const val serialVersionUID = 0L
}
}
enum class BuildAttribute(val kind: BuildAttributeKind) : Serializable {
NO_BUILD_HISTORY(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),
JAVA_CHANGE_UNEXPECTED_PSI(BuildAttributeKind.REBUILD_REASON),
JAVA_CHANGE_UNKNOWN_QUALIFIER(BuildAttributeKind.REBUILD_REASON),
DEP_CHANGE_REMOVED_ENTRY(BuildAttributeKind.REBUILD_REASON),
DEP_CHANGE_HISTORY_IS_NOT_FOUND(BuildAttributeKind.REBUILD_REASON),
DEP_CHANGE_HISTORY_CANNOT_BE_READ(BuildAttributeKind.REBUILD_REASON),
DEP_CHANGE_HISTORY_NO_KNOWN_BUILDS(BuildAttributeKind.REBUILD_REASON),
DEP_CHANGE_NON_INCREMENTAL_BUILD_IN_DEP(BuildAttributeKind.REBUILD_REASON),
IN_PROCESS_EXECUTION(BuildAttributeKind.REBUILD_REASON),
OUT_OF_PROCESS_EXECUTION(BuildAttributeKind.REBUILD_REASON),
IC_IS_NOT_ENABLED(BuildAttributeKind.REBUILD_REASON);
companion object {
const val serialVersionUID = 0L
}
}

View File

@@ -1,30 +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.build.report.metrics
import java.io.Serializable
import java.util.*
class BuildAttributes : Serializable {
private val myAttributes =
EnumMap<BuildAttribute, Int>(
BuildAttribute::class.java
)
fun add(attr: BuildAttribute, count: Int = 1) {
myAttributes[attr] = myAttributes.getOrDefault(attr, 0) + count
}
fun addAll(other: BuildAttributes) {
other.myAttributes.forEach { (attr, n) -> add(attr, n) }
}
fun asMap(): Map<BuildAttribute, Int> = myAttributes
companion object {
const val serialVersionUID = 0L
}
}

View File

@@ -1,22 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
data class BuildMetrics(
val buildTimes: BuildTimes = BuildTimes(),
val buildAttributes: BuildAttributes = BuildAttributes()
) : Serializable {
fun addAll(other: BuildMetrics) {
buildTimes.addAll(other.buildTimes)
buildAttributes.addAll(other.buildAttributes)
}
companion object {
const val serialVersionUID = 0L
}
}

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.
*/
package org.jetbrains.kotlin.build.report.metrics
interface BuildMetricsReporter {
fun startMeasure(metric: BuildTime, startNs: Long)
fun endMeasure(metric: BuildTime, endNs: Long)
fun addAttribute(attribute: BuildAttribute)
fun getMetrics(): BuildMetrics
fun addMetrics(metrics: BuildMetrics?)
}
inline fun <T> BuildMetricsReporter.measure(metric: BuildTime, fn: () -> T): T {
val start = System.nanoTime()
startMeasure(metric, start)
try {
return fn()
} finally {
val end = System.nanoTime()
endMeasure(metric, end)
}
}

View File

@@ -1,47 +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.build.report.metrics
import java.util.*
class BuildMetricsReporterImpl : BuildMetricsReporter {
private val myBuildTimeStartNs: EnumMap<BuildTime, Long> =
EnumMap(
BuildTime::class.java
)
private val myBuildTimes = BuildTimes()
private val myBuildAttributes = BuildAttributes()
override fun startMeasure(metric: BuildTime, startNs: Long) {
if (metric in myBuildTimeStartNs) {
error("$metric was restarted before it finished")
}
myBuildTimeStartNs[metric] = startNs
}
override fun endMeasure(metric: BuildTime, endNs: Long) {
val startNs = myBuildTimeStartNs.remove(metric) ?: error("$metric finished before it started")
val durationNs = endNs - startNs
myBuildTimes.add(metric, durationNs)
}
override fun addAttribute(attribute: BuildAttribute) {
myBuildAttributes.add(attribute)
}
override fun getMetrics(): BuildMetrics =
BuildMetrics(
buildTimes = myBuildTimes,
buildAttributes = myBuildAttributes
)
override fun addMetrics(metrics: BuildMetrics?) {
if (metrics == null) return
myBuildAttributes.addAll(metrics.buildAttributes)
myBuildTimes.addAll(metrics.buildTimes)
}
}

View File

@@ -1,43 +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.build.report.metrics
import java.io.Serializable
@Suppress("Reformat")
enum class BuildTime(val parent: BuildTime? = null) : Serializable {
GRADLE_TASK,
CLEAR_OUTPUT(GRADLE_TASK),
BACKUP_OUTPUT(GRADLE_TASK),
RESTORE_OUTPUT_FROM_BACKUP(GRADLE_TASK),
CONNECT_TO_DAEMON(GRADLE_TASK),
CLEAR_JAR_CACHE(GRADLE_TASK),
RUN_COMPILER(GRADLE_TASK),
NON_INCREMENTAL_COMPILATION_IN_PROCESS(RUN_COMPILER),
NON_INCREMENTAL_COMPILATION_OUT_OF_PROCESS(RUN_COMPILER),
NON_INCREMENTAL_COMPILATION_DAEMON(RUN_COMPILER),
INCREMENTAL_COMPILATION(RUN_COMPILER),
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),
IC_ANALYZE_HISTORY_FILES(IC_ANALYZE_CHANGES_IN_DEPENDENCIES),
IC_ANALYZE_CHANGES_IN_JAVA_SOURCES(IC_CALCULATE_INITIAL_DIRTY_SET),
IC_ANALYZE_CHANGES_IN_ANDROID_LAYOUTS(IC_CALCULATE_INITIAL_DIRTY_SET),
IC_DETECT_REMOVED_CLASSES(IC_CALCULATE_INITIAL_DIRTY_SET),
CLEAR_OUTPUT_ON_REBUILD(INCREMENTAL_COMPILATION),
IC_UPDATE_CACHES(INCREMENTAL_COMPILATION),
INCREMENTAL_ITERATION(INCREMENTAL_COMPILATION),
NON_INCREMENTAL_ITERATION(INCREMENTAL_COMPILATION),
IC_WRITE_HISTORY_FILE(INCREMENTAL_COMPILATION);
companion object {
const val serialVersionUID = 0L
val children by lazy {
values().filter { it.parent != null }.groupBy { it.parent }
}
}
}

View File

@@ -1,29 +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.build.report.metrics
import java.io.Serializable
import java.util.*
class BuildTimes : Serializable {
private val myBuildTimes = EnumMap<BuildTime, Long>(BuildTime::class.java)
fun addAll(other: BuildTimes) {
for ((bt, timeNs) in other.myBuildTimes) {
add(bt, timeNs)
}
}
fun add(buildTime: BuildTime, timeNs: Long) {
myBuildTimes[buildTime] = myBuildTimes.getOrDefault(buildTime, 0) + timeNs
}
fun asMap(): Map<BuildTime, Long> = myBuildTimes
companion object {
const val serialVersionUID = 0L
}
}

View File

@@ -1,25 +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.build.report.metrics
object DoNothingBuildMetricsReporter : BuildMetricsReporter {
override fun startMeasure(metric: BuildTime, startNs: Long) {
}
override fun endMeasure(metric: BuildTime, endNs: Long) {
}
override fun addAttribute(attribute: BuildAttribute) {
}
override fun getMetrics(): BuildMetrics =
BuildMetrics(
BuildTimes(),
BuildAttributes()
)
override fun addMetrics(metrics: BuildMetrics?) {}
}

View File

@@ -1,11 +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.build.report.metrics
import org.jetbrains.kotlin.build.report.RemoteReporter
interface RemoteBuildMetricsReporter : BuildMetricsReporter,
RemoteReporter

View File

@@ -29,43 +29,21 @@ import org.jetbrains.kotlin.cli.common.arguments.Argument;
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
import org.jetbrains.kotlin.cli.common.arguments.InternalArgument;
import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt;
import org.jetbrains.kotlin.idea.ExplicitDefaultSubstitutor;
import org.jetbrains.kotlin.idea.ExplicitDefaultSubstitutorsKt;
import org.jetbrains.kotlin.utils.StringsKt;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class ArgumentUtils {
private ArgumentUtils() {
}
private ArgumentUtils() {}
@NotNull
public static List<String> convertArgumentsToStringList(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
List<String> convertedArguments = convertArgumentsToStringListInternal(arguments);
Map<KClass<? extends CommonToolArguments>, Collection<ExplicitDefaultSubstitutor>> defaultSubstitutorsMap =
ExplicitDefaultSubstitutorsKt.getDefaultSubstitutors();
KClass<? extends CommonToolArguments> argumentsKClass = JvmClassMappingKt.getKotlinClass(arguments.getClass());
Collection<ExplicitDefaultSubstitutor> defaultSubstitutors = defaultSubstitutorsMap.get(argumentsKClass);
if (defaultSubstitutors != null) {
for (ExplicitDefaultSubstitutor substitutor : defaultSubstitutors) {
if (substitutor.isSubstitutable(convertedArguments)) convertedArguments.addAll(substitutor.getNewSubstitution());
}
}
return convertedArguments;
}
@NotNull
public static List<String> convertArgumentsToStringListNoDefaults(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
return convertArgumentsToStringListInternal(arguments);
}
private static List<String> convertArgumentsToStringListInternal(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
List<String> result = new ArrayList<>();
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);

View File

@@ -1,46 +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.idea
import org.jetbrains.kotlin.cli.common.arguments.Argument
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.JvmTarget
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.findAnnotation
val defaultSubstitutors: Map<KClass<out CommonToolArguments>, Collection<ExplicitDefaultSubstitutor>> =
mapOf(K2JVMCompilerArguments::class to listOf(JvmTargetDefaultSubstitutor))
sealed class ExplicitDefaultSubstitutor {
abstract val substitutedProperty: KProperty1<out CommonToolArguments, String?>
abstract val oldSubstitution: List<String>
abstract val newSubstitution: List<String>
abstract fun isSubstitutable(args: List<String>): Boolean
protected val argument: Argument by lazy {
substitutedProperty.findAnnotation() ?: error("Property \"${substitutedProperty.name}\" has no Argument annotation")
}
}
object JvmTargetDefaultSubstitutor : ExplicitDefaultSubstitutor() {
override val substitutedProperty
get() = K2JVMCompilerArguments::jvmTarget
private val oldDefault: String
get() = JvmTarget.JVM_1_6.description
private val newDefault: String
get() = JvmTarget.JVM_1_8.description
private fun prepareSubstitution(default: String): List<String> = listOf(argument.value, default)
override val oldSubstitution: List<String>
get() = prepareSubstitution(oldDefault)
override val newSubstitution: List<String>
get() = prepareSubstitution(newDefault)
override fun isSubstitutable(args: List<String>): Boolean = argument.value !in args
}

View File

@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.incremental
import com.intellij.util.io.EnumeratorStringDescriptor
import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
import org.jetbrains.kotlin.metadata.deserialization.supertypes
@@ -35,15 +34,12 @@ interface IncrementalCacheCommon {
val thisWithDependentCaches: Iterable<AbstractIncrementalCache<*>>
fun classesFqNamesBySources(files: Iterable<File>): Collection<FqName>
fun getSubtypesOf(className: FqName): Sequence<FqName>
fun getSupertypesOf(className: FqName): Sequence<FqName>
fun getSourceFileIfClass(fqName: FqName): File?
fun markDirty(removedAndCompiledSources: Collection<File>)
fun clearCacheForRemovedClasses(changesCollector: ChangesCollector)
fun getComplementaryFilesRecursive(dirtyFiles: Collection<File>): Collection<File>
fun updateComplementaryFiles(dirtyFiles: Collection<File>, expectActualTracker: ExpectActualTrackerImpl)
fun dump(): String
fun isSealed(className: FqName): Boolean?
}
/**
@@ -54,7 +50,6 @@ abstract class AbstractIncrementalCache<ClassName>(
protected val pathConverter: FileToPathConverter
) : BasicMapsOwner(workingDir), IncrementalCacheCommon {
companion object {
private val CLASS_ATTRIBUTES = "class-attributes"
private val SUBTYPES = "subtypes"
private val SUPERTYPES = "supertypes"
private val CLASS_FQ_NAME_TO_SOURCE = "class-fq-name-to-source"
@@ -76,7 +71,6 @@ abstract class AbstractIncrementalCache<ClassName>(
result
}
internal val classAttributesMap = registerMap(ClassAttributesMap(CLASS_ATTRIBUTES.storageFile))
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
protected val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile, pathConverter))
@@ -96,14 +90,6 @@ abstract class AbstractIncrementalCache<ClassName>(
override fun getSubtypesOf(className: FqName): Sequence<FqName> =
subtypesMap[className].asSequence()
override fun getSupertypesOf(className: FqName): Sequence<FqName> {
return supertypesMap[className].asSequence()
}
override fun isSealed(className: FqName): Boolean? {
return classAttributesMap[className]?.isSealed
}
override fun getSourceFileIfClass(fqName: FqName): File? =
classFqNameToSourceMap[fqName]
@@ -132,7 +118,6 @@ abstract class AbstractIncrementalCache<ClassName>(
supertypesMap[child] = parents
classFqNameToSourceMap[child] = srcFile
classAttributesMap[child] = ICClassesAttributes(ProtoBuf.Modality.SEALED == Flags.MODALITY.get(proto.flags))
}
protected fun removeAllFromClassStorage(removedClasses: Collection<FqName>, changesCollector: ChangesCollector) {
@@ -167,17 +152,14 @@ abstract class AbstractIncrementalCache<ClassName>(
}
}
removedFqNames.forEach {
classFqNameToSourceMap.remove(it)
classAttributesMap.remove(it)
}
removedFqNames.forEach { classFqNameToSourceMap.remove(it) }
}
protected class ClassFqNameToSourceMap(
storageFile: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
) :
BasicStringMap<String>(storageFile, EnumeratorStringDescriptor(), PathStringDescriptor) {
operator fun set(fqName: FqName, sourceFile: File) {
storage[fqName.asString()] = pathConverter.toPath(sourceFile)
}

View File

@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.supertypes
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.serialization.deserialization.getClassId
class ChangesCollector {
private val removedMembers = hashMapOf<FqName, MutableSet<String>>()
private val changedParents = hashMapOf<FqName, MutableSet<FqName>>()
private val changedMembers = hashMapOf<FqName, MutableSet<String>>()
private val areSubclassesAffected = hashMapOf<FqName, Boolean>()
@@ -49,10 +47,6 @@ class ChangesCollector {
changes.add(ChangeInfo.SignatureChanged(fqName, areSubclassesAffected))
}
for ((fqName, changedParents) in changedParents) {
changes.add(ChangeInfo.ParentsChanged(fqName, changedParents))
}
return changes
}
@@ -85,12 +79,12 @@ class ChangesCollector {
}
if (oldData == null) {
newData!!.collectAll(isRemoved = false, isAdded = true, collectAllMembersForNewClass = collectAllMembersForNewClass)
newData!!.collectAll(isRemoved = false, collectAllMembersForNewClass = collectAllMembersForNewClass)
return
}
if (newData == null) {
oldData.collectAll(isRemoved = true, isAdded = false)
oldData.collectAll(isRemoved = true)
return
}
@@ -104,7 +98,6 @@ class ChangesCollector {
collectSignature(oldData, diff.areSubclassesAffected)
}
collectChangedMembers(fqName, diff.changedMembersNames)
addChangedParents(fqName, diff.changedSupertypes)
}
is PackagePartProtoData -> {
collectSignature(oldData, areSubclassesAffected = true)
@@ -128,11 +121,10 @@ class ChangesCollector {
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) =
private fun ProtoData.collectAll(isRemoved: Boolean, collectAllMembersForNewClass: Boolean = false) =
when (this) {
is PackagePartProtoData -> collectAllFromPackage(isRemoved)
is ClassProtoData -> collectAllFromClass(isRemoved, isAdded, collectAllMembersForNewClass)
is ClassProtoData -> collectAllFromClass(isRemoved, collectAllMembersForNewClass)
}
private fun PackagePartProtoData.collectAllFromPackage(isRemoved: Boolean) {
@@ -151,7 +143,7 @@ class ChangesCollector {
}
}
private fun ClassProtoData.collectAllFromClass(isRemoved: Boolean, isAdded: Boolean, collectAllMembersForNewClass: Boolean = false) {
private fun ClassProtoData.collectAllFromClass(isRemoved: Boolean, collectAllMembersForNewClass: Boolean = false) {
val classFqName = nameResolver.getClassId(proto.fqName).asSingleFqName()
val kind = Flags.CLASS_KIND.get(proto.flags)
@@ -170,23 +162,6 @@ class ChangesCollector {
collectSignature(classFqName, areSubclassesAffected = true)
}
if (isRemoved || isAdded) {
collectChangedParents(classFqName, proto.supertypeList)
}
}
private fun addChangedParents(fqName: FqName, parents: Collection<FqName>) {
if (parents.isNotEmpty()) {
changedParents.getOrPut(fqName) { HashSet() }.addAll(parents)
}
}
private fun ClassProtoData.collectChangedParents(fqName: FqName, parents: Collection<ProtoBuf.Type>) {
val changedParentsFqNames = parents.map { type ->
nameResolver.getClassId(type.className).asSingleFqName()
}
addChangedParents(fqName, changedParentsFqNames)
}
private fun ClassProtoData.getNonPrivateMemberNames(): Set<String> {

View File

@@ -3,7 +3,7 @@
* 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.build.report
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.cli.common.ExitCode
import java.io.File
@@ -17,5 +17,3 @@ interface ICReporter {
fun reportMarkDirtyMember(affectedFiles: Iterable<File>, scope: String, name: String)
fun reportMarkDirty(affectedFiles: Iterable<File>, reason: String)
}

View File

@@ -1,9 +1,9 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2019 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.build.report
package org.jetbrains.kotlin.incremental
import java.io.File

View File

@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import java.io.DataInput
import java.io.DataOutput
import java.io.File
@@ -327,7 +326,7 @@ private class ProtoDataProvider(private val serializerProtocol: SerializerExtens
proto.`package`.apply {
val packageNameId = getExtensionOrNull(serializerProtocol.packageFqName)
val packageFqName = packageNameId?.let { FqName(nameResolver.getPackageFqName(it)) } ?: FqName.ROOT
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalizeAsciiOnly() + "Kt"))
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt"))
classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName)
}
@@ -348,7 +347,7 @@ fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData>
proto.`package`.apply {
val packageFqName = getExtensionOrNull(JsProtoBuf.packageFqName)?.let(nameResolver::getPackageFqName)?.let(::FqName) ?: FqName.ROOT
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalizeAsciiOnly() + "Kt"))
val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt"))
classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName)
}
@@ -413,4 +412,4 @@ private class PackageMetadataMap(storageFile: File) : BasicStringMap<ByteArray>(
operator fun get(packageName: String) = storage[packageName]
override fun dumpValue(value: ByteArray): String = "Package metadata: ${value.md5()}"
}
}

View File

@@ -94,10 +94,6 @@ open class IncrementalJvmCache(
fun sourcesByInternalName(internalName: String): Collection<File> =
internalNameToSource[internalName]
fun getAllPartsOfMultifileFacade(facade: JvmClassName): Collection<String>? {
return multifileFacadeToParts[facade]
}
fun isMultifileFacade(className: JvmClassName): Boolean =
className in multifileFacadeToParts
@@ -149,7 +145,6 @@ open class IncrementalJvmCache(
}
protoMap.remove(className, changesCollector)
classFqNameToSourceMap.remove(className.fqNameForClassNameWithoutDollars)
classAttributesMap.remove(className.fqNameForClassNameWithoutDollars)
internalNameToSource.remove(className.internalName)
// TODO NO_CHANGES? (delegates only)
@@ -276,7 +271,6 @@ open class IncrementalJvmCache(
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
@Synchronized
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
return put(kotlinClass, changesCollector)
}
@@ -288,12 +282,10 @@ open class IncrementalJvmCache(
// from files compiled during last round.
// However there is no need to compare old and new data in this case
// (also that would fail with exception).
@Synchronized
fun storeModuleMapping(className: JvmClassName, bytes: ByteArray) {
storage[className.internalName] = ProtoMapValue(isPackageFacade = false, bytes = bytes, strings = emptyArray())
}
@Synchronized
private fun put(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val header = kotlinClass.classHeader
@@ -316,7 +308,6 @@ open class IncrementalJvmCache(
operator fun get(className: JvmClassName): ProtoMapValue? =
storage[className.internalName]
@Synchronized
fun remove(className: JvmClassName, changesCollector: ChangesCollector) {
val key = className.internalName
val oldValue = storage[key] ?: return
@@ -333,8 +324,6 @@ open class IncrementalJvmCache(
private inner class JavaSourcesProtoMap(storageFile: File) :
BasicStringMap<SerializedJavaClass>(storageFile, JavaClassProtoMapValueExternalizer) {
@Synchronized
fun process(jvmClassName: JvmClassName, newData: SerializedJavaClass, changesCollector: ChangesCollector) {
val key = jvmClassName.internalName
val oldData = storage[key]
@@ -346,7 +335,6 @@ open class IncrementalJvmCache(
)
}
@Synchronized
fun remove(className: JvmClassName, changesCollector: ChangesCollector) {
val key = className.internalName
val oldValue = storage[key] ?: return
@@ -386,7 +374,6 @@ open class IncrementalJvmCache(
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
@Synchronized
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
val oldMap = storage[key] ?: emptyMap()
@@ -403,7 +390,6 @@ open class IncrementalJvmCache(
}
}
@Synchronized
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
}
@@ -429,8 +415,6 @@ open class IncrementalJvmCache(
private inner class MultifileClassFacadeMap(storageFile: File) :
BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
@Synchronized
operator fun set(className: JvmClassName, partNames: Collection<String>) {
storage[className.internalName] = partNames
}
@@ -441,7 +425,6 @@ open class IncrementalJvmCache(
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
@Synchronized
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
}
@@ -451,8 +434,6 @@ open class IncrementalJvmCache(
private inner class MultifileClassPartMap(storageFile: File) :
BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
@Synchronized
fun set(partName: String, facadeName: String) {
storage[partName] = facadeName
}
@@ -460,7 +441,6 @@ open class IncrementalJvmCache(
fun get(partName: JvmClassName): String? =
storage[partName.internalName]
@Synchronized
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
}
@@ -542,7 +522,6 @@ open class IncrementalJvmCache(
return result
}
@Synchronized
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
val oldMap = storage[key] ?: emptyMap()
@@ -568,7 +547,6 @@ open class IncrementalJvmCache(
private fun functionNameBySignature(signature: String): String =
signature.substringBefore("(")
@Synchronized
fun remove(className: JvmClassName) {
storage.remove(className.internalName)
}
@@ -590,7 +568,6 @@ sealed class ChangeInfo(val fqName: FqName) {
class SignatureChanged(fqName: FqName, val areSubclassesAffected: Boolean) : ChangeInfo(fqName)
class ParentsChanged(fqName: FqName, val parentsChanged: Collection<FqName>) : ChangeInfo(fqName)
protected open fun toStringProperties(): String = "fqName = $fqName"

View File

@@ -21,7 +21,6 @@ data class IncrementalModuleEntry(
class IncrementalModuleInfo(
val projectRoot: File,
val rootProjectBuildDir: File,
val dirToModule: Map<File, IncrementalModuleEntry>,
val nameToModules: Map<String, Set<IncrementalModuleEntry>>,
val jarToClassListFile: Map<File, File>,
@@ -29,6 +28,6 @@ class IncrementalModuleInfo(
val jarToModule: Map<File, IncrementalModuleEntry>
) : Serializable {
companion object {
private const val serialVersionUID = 1L
private const val serialVersionUID = 0L
}
}

View File

@@ -17,18 +17,19 @@
package org.jetbrains.kotlin.incremental
import com.intellij.util.containers.MultiMap
import com.intellij.util.containers.StringInterner
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.Position
import org.jetbrains.kotlin.incremental.components.ScopeKind
import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.createStringInterner
import org.jetbrains.kotlin.utils.keysToMap
import java.io.File
import java.io.IOException
import java.util.*
open class LookupStorage(
targetDataDir: File,
pathConverter: FileToPathConverter
@@ -211,8 +212,8 @@ open class LookupStorage(
class LookupTrackerImpl(private val delegate: LookupTracker) : LookupTracker {
val lookups = MultiMap.createSet<LookupSymbol, String>()
val pathInterner = createStringInterner()
private val interner = createStringInterner()
val pathInterner = StringInterner()
private val interner = StringInterner()
override val requiresPosition: Boolean
get() = delegate.requiresPosition

View File

@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.build.isModuleMappingFile
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
@@ -32,7 +31,6 @@ import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
import java.io.File
import java.nio.file.Files
import java.util.*
import kotlin.collections.HashSet
import kotlin.collections.LinkedHashSet
@@ -68,7 +66,7 @@ fun makeModuleFile(
friendDirs
)
val scriptFile = Files.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml").toFile()
val scriptFile = File.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml")
scriptFile.writeText(builder.asText().toString())
return scriptFile
}
@@ -136,8 +134,7 @@ fun LookupStorage.update(
data class DirtyData(
val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(),
val dirtyClassesFqNames: Collection<FqName> = emptyList(),
val dirtyClassesFqNamesForceRecompile: Collection<FqName> = emptyList()
val dirtyClassesFqNames: Collection<FqName> = emptyList()
)
fun ChangesCollector.getDirtyData(
@@ -147,9 +144,6 @@ fun ChangesCollector.getDirtyData(
val dirtyLookupSymbols = HashSet<LookupSymbol>()
val dirtyClassesFqNames = HashSet<FqName>()
val sealedParents = HashMap<FqName, MutableSet<FqName>>()
val notSealedParents = HashSet<FqName>()
for (change in changes()) {
reporter.reportVerbose { "Process $change" }
@@ -174,35 +168,10 @@ fun ChangesCollector.getDirtyData(
}
fqNames.mapTo(dirtyLookupSymbols) { LookupSymbol(SAM_LOOKUP_NAME.asString(), it.asString()) }
} else if (change is ChangeInfo.ParentsChanged) {
fun FqName.isSealed(): Boolean {
if (notSealedParents.contains(this)) return false
if (sealedParents.containsKey(this)) return true
return isSealed(this, caches).also { sealed ->
if (sealed) {
sealedParents[this] = HashSet()
} else {
notSealedParents.add(this)
}
}
}
change.parentsChanged.forEach { parent ->
if (parent.isSealed()) {
sealedParents.getOrPut(parent) { HashSet() }.add(change.fqName)
}
}
}
}
val forceRecompile = HashSet<FqName>().apply {
addAll(sealedParents.keys)
//we should recompile all inheritors with parent sealed class: add known subtypes
addAll(sealedParents.keys.flatMap { withSubtypes(it, caches) })
//we should recompile all inheritors with parent sealed class: add new subtypes
addAll(sealedParents.values.flatten())
}
return DirtyData(dirtyLookupSymbols, dirtyClassesFqNames, forceRecompile)
return DirtyData(dirtyLookupSymbols, dirtyClassesFqNames)
}
fun mapLookupSymbolsToFiles(
@@ -246,11 +215,6 @@ fun mapClassesFqNamesToFiles(
return fqNameToAffectedFiles.values.flattenTo(HashSet())
}
fun isSealed(
fqName: FqName,
caches: Iterable<IncrementalCacheCommon>
): Boolean = caches.any { it.isSealed(fqName) ?: false }
fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>

View File

@@ -28,14 +28,12 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
import org.jetbrains.kotlin.serialization.deserialization.descriptorVisibility
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import java.util.*
data class Difference(
val isClassAffected: Boolean = false,
val areSubclassesAffected: Boolean = false,
val changedMembersNames: Set<String> = emptySet(),
val changedSupertypes: Set<FqName> = emptySet()
val changedMembersNames: Set<String> = emptySet()
)
sealed class ProtoData
@@ -189,7 +187,6 @@ class DifferenceCalculatorForClass(
var isClassAffected = false
var areSubclassesAffected = false
val changedSupertypes = HashSet<FqName>()
val names = hashSetOf<String>()
val classIsSealed = newProto.isSealed && oldProto.isSealed
@@ -250,21 +247,12 @@ class DifferenceCalculatorForClass(
ProtoBufClassKind.FLAGS,
ProtoBufClassKind.FQ_NAME,
ProtoBufClassKind.TYPE_PARAMETER_LIST,
ProtoBufClassKind.SUPERTYPE_LIST,
ProtoBufClassKind.SUPERTYPE_ID_LIST,
ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST -> {
isClassAffected = true
areSubclassesAffected = true
}
ProtoBufClassKind.SUPERTYPE_LIST,
ProtoBufClassKind.SUPERTYPE_ID_LIST -> {
isClassAffected = true
areSubclassesAffected = true
val oldSupertypes = oldProto.supertypeList.map { oldNameResolver.getClassId(it.className).asSingleFqName() }
val newSupertypes = newProto.supertypeList.map { newNameResolver.getClassId(it.className).asSingleFqName() }
val changed = (oldSupertypes union newSupertypes) subtract (oldSupertypes intersect newSupertypes)
changedSupertypes.addAll(changed)
}
ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME,
ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID -> {
// TODO
@@ -293,7 +281,7 @@ class DifferenceCalculatorForClass(
}
}
return Difference(isClassAffected, areSubclassesAffected, names, changedSupertypes)
return Difference(isClassAffected, areSubclassesAffected, names)
}
}

View File

@@ -30,7 +30,6 @@ open class BasicMapsOwner(val cachesDir: File) {
protected val String.storageFile: File
get() = File(cachesDir, this + "." + CACHE_EXTENSION)
@Synchronized
protected fun <K, V, M : BasicMap<K, V>> registerMap(map: M): M {
maps.add(map)
return map
@@ -48,7 +47,6 @@ open class BasicMapsOwner(val cachesDir: File) {
forEachMapSafe("flush") { it.flush(memoryCachesOnly) }
}
@Synchronized
private fun forEachMapSafe(actionName: String, action: (BasicMap<*, *>) -> Unit) {
val actionExceptions = LinkedHashMap<String, Exception>()
maps.forEach {
@@ -68,6 +66,5 @@ open class BasicMapsOwner(val cachesDir: File) {
}
@TestOnly
@Synchronized
fun dump(): String = maps.joinToString("\n\n") { it.dump() }
}

View File

@@ -17,11 +17,9 @@
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.PersistentHashMap
import java.io.File
import java.io.IOException
/**
@@ -32,6 +30,7 @@ class CachingLazyStorage<K, V>(
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
@@ -81,10 +80,8 @@ class CachingLazyStorage<K, V>(
try {
storage?.close()
} finally {
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
if (!IOUtil.deleteAllFilesStartingWith(storageFile)) {
throw IOException("Could not delete internal storage: ${storageFile.absolutePath}")
}
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import org.jetbrains.kotlin.name.FqName
import java.io.DataInput
import java.io.DataOutput
import java.io.File
internal data class ICClassesAttributes(val isSealed: Boolean)
internal object ICClassesAttributesExternalizer : DataExternalizer<ICClassesAttributes> {
override fun read(input: DataInput): ICClassesAttributes {
return ICClassesAttributes(input.readBoolean())
}
override fun save(output: DataOutput, value: ICClassesAttributes) {
output.writeBoolean(value.isSealed)
}
}
internal open class ClassAttributesMap(
storageFile: File
) : BasicStringMap<ICClassesAttributes>(storageFile, ICClassesAttributesExternalizer) {
override fun dumpValue(value: ICClassesAttributes): String = value.toString()
operator fun set(key: FqName, value: ICClassesAttributes) {
storage[key.asString()] = value
}
operator fun get(key: FqName): ICClassesAttributes? = storage[key.asString()]
fun remove(key: FqName) {
storage.remove(key.asString())
}
}

View File

@@ -20,18 +20,18 @@ import org.jetbrains.kotlin.incremental.dumpCollection
import org.jetbrains.kotlin.name.FqName
import java.io.File
internal open class ClassOneToManyMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
internal open class ClassOneToManyMap(
storageFile: File
) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
@Synchronized
fun add(key: FqName, value: FqName) {
storage.append(key.asString(), listOf(value.asString()))
}
operator fun get(key: FqName): Collection<FqName> =
storage[key.asString()]?.map(::FqName) ?: setOf()
storage[key.asString()]?.map(::FqName) ?: setOf()
@Synchronized
operator fun set(key: FqName, values: Collection<FqName>) {
if (values.isEmpty()) {
remove(key)
@@ -41,14 +41,10 @@ internal open class ClassOneToManyMap(storageFile: File) : BasicStringMap<Collec
storage[key.asString()] = values.map(FqName::asString)
}
@Synchronized
fun remove(key: FqName) {
storage.remove(key.asString())
}
// Access to caches could be done from multiple threads (e.g. JPS worker and RMI). The underlying collection is already synchronized,
// thus we need synchronization of this method and all modification methods.
@Synchronized
fun removeValues(key: FqName, removed: Set<FqName>) {
val notRemoved = this[key].filter { it !in removed }
this[key] = notRemoved

View File

@@ -25,7 +25,8 @@ internal class DirtyClassesJvmNameMap(storageFile: File) : AbstractDirtyClassesM
internal class DirtyClassesFqNameMap(storageFile: File) : AbstractDirtyClassesMap<FqName>(FqNameTransformer, storageFile)
internal abstract class AbstractDirtyClassesMap<Name>(
private val nameTransformer: NameTransformer<Name>, storageFile: File
private val nameTransformer: NameTransformer<Name>,
storageFile: File
) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
fun markDirty(className: Name) {
storage[nameTransformer.asString(className)] = true
@@ -36,10 +37,10 @@ internal abstract class AbstractDirtyClassesMap<Name>(
}
fun getDirtyOutputClasses(): Collection<Name> =
storage.keys.map { nameTransformer.asName(it) }
storage.keys.map { nameTransformer.asName(it) }
fun isDirty(className: Name): Boolean =
storage.contains(nameTransformer.asString(className))
storage.contains(nameTransformer.asString(className))
override fun dumpValue(value: Boolean) = ""
}

View File

@@ -17,11 +17,9 @@
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.PersistentHashMap
import java.io.File
import java.io.IOException
class NonCachingLazyStorage<K, V>(
@@ -29,6 +27,7 @@ class NonCachingLazyStorage<K, V>(
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
@@ -77,12 +76,11 @@ class NonCachingLazyStorage<K, V>(
override fun clean() {
try {
storage?.close()
} finally {
storage = null
if (!IOUtil.deleteAllFilesStartingWith(storageFile)) {
throw IOException("Could not delete internal storage: ${storageFile.absolutePath}")
}
} catch (ignored: Throwable) {
}
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.JpsPersistentHashMap
import java.io.File
class NonCachingLazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: JpsPersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendDataWithoutCache(key, value)
}
@Synchronized
override fun clean() {
try {
storage?.close()
} catch (ignored: Throwable) {
}
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
} else {
existingStorage.force()
}
}
@Synchronized
override fun close() {
storage?.close()
}
private fun createMap(): JpsPersistentHashMap<K, V> =
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.build
import junit.framework.TestCase
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.junit.Assert.assertNotEquals
import org.junit.Test
@@ -33,7 +34,10 @@ class BuildMetaInfoTest : TestCase() {
"bytecodeVersionMinor",
"bytecodeVersionPatch",
"compilerBuildVersion",
"coroutinesEnable",
"coroutinesError",
"coroutinesVersion",
"coroutinesWarn",
"isEAP",
"languageVersionString",
"metadataVersionMajor",
@@ -67,12 +71,14 @@ class BuildMetaInfoTest : TestCase() {
@Test
fun testJvmEquals() {
val args1 = K2JVMCompilerArguments()
args1.coroutinesState = CommonCompilerArguments.ENABLE
val info1 = JvmBuildMetaInfo.create(args1)
val args2 = K2JVMCompilerArguments()
args2.coroutinesState = CommonCompilerArguments.WARN
val info2 = JvmBuildMetaInfo.create(args2)
assertEquals(info1, info2)
assertEquals(info1, info2.copy())
assertNotEquals(info1, info2)
assertEquals(info1, info2.copy(coroutinesEnable = true, coroutinesWarn = false))
}
}

View File

@@ -22,12 +22,12 @@ data class BuildLogFinder(
private val isDataContainerBuildLogEnabled: Boolean = false,
private val isGradleEnabled: Boolean = false,
private val isJsEnabled: Boolean = false,
private val isScopeExpansionEnabled: Boolean = false,
private val isKlibEnabled: Boolean = false
private val isJsIrEnabled: Boolean = false, // TODO rename as it is used for metadata-only test
private val isScopeExpansionEnabled: Boolean = false
) {
companion object {
private const val JS_LOG = "js-build.log"
private const val KLIB_LOG = "klib-build.log"
private const val JS_IR_LOG = "js-ir-build.log"
private const val SCOPE_EXPANDING_LOG = "build-with-scope-expansion.log"
private const val GRADLE_LOG = "gradle-build.log"
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
@@ -43,7 +43,7 @@ data class BuildLogFinder(
val files = names.filter { File(dir, it).isFile }.toSet()
val matchedName = when {
isScopeExpansionEnabled && SCOPE_EXPANDING_LOG in files -> SCOPE_EXPANDING_LOG
isKlibEnabled && KLIB_LOG in files -> KLIB_LOG
isJsIrEnabled && JS_IR_LOG in files -> JS_IR_LOG
isJsEnabled && JS_LOG in files -> JS_LOG
isGradleEnabled && GRADLE_LOG in files -> GRADLE_LOG
isJsEnabled && JS_JPS_LOG in files -> JS_JPS_LOG

View File

@@ -151,35 +151,29 @@ private fun classFileToString(classFile: File): String {
val traceVisitor = TraceClassVisitor(PrintWriter(out))
ClassReader(classFile.readBytes()).accept(traceVisitor, 0)
val classHeader = LocalFileKotlinClass.create(classFile)?.classHeader ?: return ""
if (!classHeader.metadataVersion.isCompatible()) {
error("Incompatible class ($classHeader): $classFile")
}
val classHeader = LocalFileKotlinClass.create(classFile)?.classHeader
when (classHeader.kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
ByteArrayInputStream(BitEncoding.decodeBytes(classHeader.data!!)).use { input ->
out.write("\n------ string table types proto -----\n${DebugJvmProtoBuf.StringTableTypes.parseDelimitedFrom(input)}")
val annotationDataEncoded = classHeader?.data
if (annotationDataEncoded != null) {
ByteArrayInputStream(BitEncoding.decodeBytes(annotationDataEncoded)).use {
input ->
when (classHeader.kind) {
KotlinClassHeader.Kind.FILE_FACADE ->
out.write("\n------ file facade proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
KotlinClassHeader.Kind.CLASS ->
out.write("\n------ class proto -----\n${DebugProtoBuf.Class.parseFrom(input, getExtensionRegistry())}")
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ->
out.write("\n------ multi-file part proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
else -> error(classHeader.kind)
}
out.write("\n------ string table types proto -----\n${DebugJvmProtoBuf.StringTableTypes.parseDelimitedFrom(input)}")
if (!classHeader.metadataVersion.isCompatible()) {
error("Incompatible class ($classHeader): $classFile")
}
when (classHeader.kind) {
KotlinClassHeader.Kind.FILE_FACADE ->
out.write("\n------ file facade proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
KotlinClassHeader.Kind.CLASS ->
out.write("\n------ class proto -----\n${DebugProtoBuf.Class.parseFrom(input, getExtensionRegistry())}")
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ->
out.write("\n------ multi-file part proto -----\n${DebugProtoBuf.Package.parseFrom(input, getExtensionRegistry())}")
else -> throw IllegalStateException()
}
}
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
out.write("\n------ multi-file facade data -----\n")
out.write(classHeader.data!!.joinToString("\n"))
}
KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
// Synthetic class has no metadata, thus there can be no differences in it.
}
KotlinClassHeader.Kind.UNKNOWN -> error("Should not meet unknown classes here: $classFile")
}
return out.toString()

View File

@@ -27,9 +27,8 @@ buildscript {
dependencies {
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
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")
}
@@ -52,6 +51,7 @@ pill {
excludedDirs(
"out",
"buildSrc/build",
"buildSrc/prepare-deps/android-dx/build",
"buildSrc/prepare-deps/intellij-sdk/build"
)
}
@@ -73,7 +73,7 @@ val kotlinVersion by extra(
} ?: buildNumber
)
val kotlinLanguageVersion by extra("1.5")
val kotlinLanguageVersion by extra("1.4")
allprojects {
group = "org.jetbrains.kotlin"
@@ -115,10 +115,6 @@ 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"
@@ -134,7 +130,6 @@ 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) {
@@ -170,12 +165,14 @@ extra["versions.jansi"] = "1.16"
extra["versions.jline"] = "3.3.1"
extra["versions.junit"] = "4.12"
extra["versions.javaslang"] = "2.0.6"
extra["versions.ant"] = "1.10.7"
extra["versions.ant"] = "1.8.2"
extra["versions.android"] = "2.3.1"
extra["versions.kotlinx-coroutines-core"] = "1.3.8"
extra["versions.kotlinx-coroutines-jdk8"] = "1.3.8"
val coroutinesVersion = if (Platform[192].orHigher()) "1.3.7" else "1.1.1"
extra["versions.kotlinx-coroutines-core"] = coroutinesVersion
extra["versions.kotlinx-coroutines-jdk8"] = coroutinesVersion
extra["versions.json"] = "20160807"
extra["versions.native-platform"] = "0.14"
extra["versions.ant-launcher"] = "1.8.0"
extra["versions.robolectric"] = "4.0"
extra["versions.org.springframework"] = "4.2.0.RELEASE"
extra["versions.jflex"] = "1.7.0"
@@ -191,14 +188,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.5-dev-17775"
extra["versions.kotlin-native"] = "1.4.30-dev-16766"
}
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 useJvmIrBackend by extra(project.getBooleanProperty("kotlin.build.useIR") ?: false)
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
@@ -234,7 +230,6 @@ extra["compilerModules"] = arrayOf(
":compiler:frontend",
":compiler:frontend.common",
":compiler:frontend.java",
":compiler:frontend:cfg",
":compiler:cli-common",
":compiler:ir.tree",
":compiler:ir.tree.impl",
@@ -242,7 +237,6 @@ extra["compilerModules"] = arrayOf(
":compiler:ir.psi2ir",
":compiler:ir.backend.common",
":compiler:backend.jvm",
":compiler:backend.jvm:backend.jvm.entrypoint",
":compiler:backend.js",
":compiler:backend.wasm",
":compiler:ir.serialization.common",
@@ -298,9 +292,7 @@ extra["compilerModules"] = arrayOf(
":compiler:fir:jvm",
":compiler:fir:checkers",
":compiler:fir:entrypoint",
":compiler:fir:analysis-tests",
":compiler:fir:analysis-tests:legacy-fir-tests",
":wasm:wasm.ir"
":compiler:fir:analysis-tests"
)
extra["compilerModulesForJps"] = listOf(
@@ -326,24 +318,12 @@ extra["compilerModulesForJps"] = listOf(
":compiler:compiler.version"
)
// 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:compileKotlin",
":plugins:uast-kotlin:compileTestKotlin"
)
val tasksWithWarnings: List<String> by extra
val coreLibProjects = listOfNotNull(
":kotlin-stdlib",
":kotlin-stdlib-common",
":kotlin-stdlib-js",
":kotlin-stdlib-jdk7",
":kotlin-stdlib-jdk8",
":kotlin-test",
":kotlin-test:kotlin-test-annotations-common",
":kotlin-test:kotlin-test-common",
":kotlin-test:kotlin-test-jvm",
@@ -351,7 +331,8 @@ val coreLibProjects = listOfNotNull(
":kotlin-test:kotlin-test-junit5",
":kotlin-test:kotlin-test-testng",
":kotlin-test:kotlin-test-js".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
":kotlin-reflect"
":kotlin-reflect",
":kotlin-coroutines-experimental-compat"
)
val gradlePluginProjects = listOf(
@@ -425,7 +406,8 @@ allprojects {
jcenter()
maven(protobufRepo)
maven(intellijRepo)
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
maven("https://dl.bintray.com/kotlin/ktor")
maven("https://kotlin.bintray.com/kotlin-dependencies")
maven("https://jetbrains.bintray.com/intellij-third-party-dependencies")
maven("https://dl.google.com/dl/android/maven2")
bootstrapKotlinRepo?.let(::maven)
@@ -461,26 +443,7 @@ allprojects {
if (useJvmIrBackend) {
useIR = true
}
if (useJvmFir) {
freeCompilerArgs += "-Xuse-fir"
freeCompilerArgs += "-Xabi-stability=stable"
}
}
}
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 }
if (projectsWithWarningsAsErrors.any(projectDir::startsWith)) {
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
if (path !in tasksWithWarnings) {
kotlinOptions {
allWarningsAsErrors = true
}
}
freeCompilerArgs += "-Xir-binary-with-stable-abi"
}
}
}
@@ -503,7 +466,7 @@ allprojects {
}
tasks.withType<Test> {
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KTI-112") { true }
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KT-37089") { true }
}
normalization {
@@ -587,11 +550,10 @@ gradle.taskGraph.whenReady {
val proguardMessage = "proguard is ${kotlinBuildProperties.proguard.toOnOff()}"
val jarCompressionMessage = "jar compression is ${kotlinBuildProperties.jarCompression.toOnOff()}"
val profileMessage = "$profile build profile is active ($proguardMessage, $jarCompressionMessage). " +
"Use -Pteamcity=<true|false> to reproduce CI/local build"
logger.warn(
"$profile build profile is active ($proguardMessage, $jarCompressionMessage). " +
"Use -Pteamcity=<true|false> to reproduce CI/local build"
)
logger.warn("\n\n$profileMessage")
allTasks.filterIsInstance<org.gradle.jvm.tasks.Jar>().forEach { task ->
task.entryCompression = if (kotlinBuildProperties.jarCompression)
@@ -606,7 +568,7 @@ val dist = tasks.register("dist") {
}
val syncMutedTests = tasks.register("syncMutedTests") {
dependsOn(":compiler:tests-mutes:tc-integration:run")
dependsOn(":compiler:tests-mutes:run")
}
val copyCompilerToIdeaPlugin by task<Copy> {
@@ -636,10 +598,7 @@ tasks {
listOf("clean", "assemble", "install").forEach { taskName ->
register("coreLibs${taskName.capitalize()}") {
for (projectName in coreLibProjects) {
if (projectName.startsWith(":kotlin-test:") && taskName == "install") continue
dependsOn("$projectName:$taskName")
}
coreLibProjects.forEach { projectName -> dependsOn("$projectName:$taskName") }
}
}
@@ -670,7 +629,6 @@ tasks {
dependsOn("dist")
dependsOn(
":compiler:test",
":compiler:tests-common-new:test",
":compiler:container:test",
":compiler:tests-java8:test",
":compiler:tests-spec:test",
@@ -692,11 +650,8 @@ tasks {
}
register("wasmCompilerTest") {
dependsOn(":js:js.tests:wasmTest")
// Windows WABT release requires Visual C++ Redistributable
if (!kotlinBuildProperties.isTeamcityBuild || !org.gradle.internal.os.OperatingSystem.current().isWindows) {
dependsOn(":wasm:wasm.ir:test")
}
// TODO: fix once
// dependsOn(":js:js.tests:wasmTest")
}
register("nativeCompilerTest") {
@@ -707,7 +662,6 @@ tasks {
dependsOn(":compiler:fir:raw-fir:psi2fir:test")
dependsOn(":compiler:fir:raw-fir:light-tree2fir:test")
dependsOn(":compiler:fir:analysis-tests:test")
dependsOn(":compiler:fir:analysis-tests:legacy-fir-tests:test")
dependsOn(":compiler:fir:fir2ir:test")
}
@@ -717,7 +671,6 @@ tasks {
":compiler:fir:raw-fir:psi2fir:test",
":compiler:fir:raw-fir:light-tree2fir:test",
":compiler:fir:analysis-tests:test",
":compiler:fir:analysis-tests:legacy-fir-tests:test",
":compiler:fir:fir2ir:test",
":plugins:fir:fir-plugin-prototype:test"
)
@@ -753,6 +706,7 @@ tasks {
}
register("miscCompilerTest") {
dependsOn("wasmCompilerTest")
dependsOn("nativeCompilerTest")
dependsOn("firCompilerTest")
@@ -771,7 +725,6 @@ tasks {
register("toolsTest") {
dependsOn(":tools:kotlinp:test")
dependsOn(":native:kotlin-klib-commonizer:test")
dependsOn(":native:kotlin-klib-commonizer-api:test")
}
register("examplesTest") {
@@ -818,6 +771,7 @@ tasks {
if (Ide.IJ()) {
register("idea-new-project-wizard-tests") {
dependsOn("dist")
dependsOn(
":libraries:tools:new-project-wizard:test",
":libraries:tools:new-project-wizard:new-project-wizard-cli:test",
@@ -890,24 +844,12 @@ tasks {
":generators:test"
)
if (Ide.IJ()) {
dependsOn(
":libraries:tools:new-project-wizard:test",
":libraries:tools:new-project-wizard:new-project-wizard-cli:test",
":idea:idea-new-project-wizard:test" // Temporary here. Remove after enabling builds for ideaIntegrationsTests
)
}
}
register("ideaIntegrationsTests") {
if (Ide.IJ()) {
dependsOn(":idea:idea-new-project-wizard:test")
dependsOn("idea-new-project-wizard-tests")
}
}
register("kaptIdeTest") {
dependsOn(":kotlin-annotation-processing:test")
dependsOn(":kotlin-annotation-processing-base:test")
dependsOn(":kotlin-annotation-processing-cli:test")
}
register("gradleIdeTest") {
@@ -922,11 +864,10 @@ tasks {
":idea:idea-gradle:test",
":idea:test",
":compiler:test",
":compiler:container:test",
":js:js.tests:test"
)
dependsOn(":kotlin-gradle-plugin-integration-tests:test")
if (Ide.IJ193.orHigher())
dependsOn(":kotlin-gradle-plugin-integration-tests:test")
if (Ide.AS40.orHigher())
dependsOn(":kotlin-ultimate:ide:android-studio-native:test")
@@ -951,20 +892,16 @@ tasks {
}
}
register("publishGradlePluginArtifacts") {
idePluginDependency {
dependsOnKotlinGradlePluginPublish()
}
}
register("publishIdeArtifacts") {
idePluginDependency {
dependsOn(
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-tests-for-ide:publish",
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-dist-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide:publish",
@@ -983,7 +920,9 @@ tasks {
":kotlin-stdlib-jdk7:publish",
":kotlin-stdlib-jdk8:publish",
":kotlin-reflect:publish",
":kotlin-main-kts:publish"
":kotlin-main-kts:publish",
":kotlin-stdlib-js:publish",
":kotlin-test:kotlin-test-js:publish"
)
}
}

View File

@@ -1,5 +1,3 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
extra["versions.native-platform"] = "0.14"
buildscript {
@@ -12,10 +10,10 @@ buildscript {
repositories {
if (cacheRedirectorEnabled) {
maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com")
maven("https://cache-redirector.jetbrains.com/maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
maven("https://cache-redirector.jetbrains.com/kotlin.bintray.com/kotlin-dependencies")
} else {
jcenter()
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
maven("https://kotlin.bintray.com/kotlin-dependencies")
}
project.bootstrapKotlinRepo?.let {
@@ -24,12 +22,14 @@ buildscript {
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
}
}
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
logger.info("buildSrcKotlinVersion: " + extra["bootstrapKotlinVersion"])
logger.info("buildSrc kotlin compiler version: " + org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)
logger.info("buildSrc stdlib version: " + KotlinVersion.CURRENT)
@@ -37,7 +37,6 @@ logger.info("buildSrc stdlib version: " + KotlinVersion.CURRENT)
apply {
plugin("kotlin")
plugin("kotlin-sam-with-receiver")
plugin("groovy")
from("../gradle/checkCacheability.gradle.kts")
}
@@ -81,13 +80,13 @@ extra["intellijReleaseType"] = when {
}
extra["versions.androidDxSources"] = "5.0.0_r2"
extra["customDepsOrg"] = "kotlin.build"
repositories {
jcenter()
maven("https://jetbrains.bintray.com/intellij-third-party-dependencies/")
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
maven("https://kotlin.bintray.com/kotlinx")
maven("https://kotlin.bintray.com/kotlin-dependencies")
gradlePluginPortal()
extra["bootstrapKotlinRepo"]?.let {
@@ -95,59 +94,10 @@ repositories {
}
}
val generateCompilerVersion by tasks.registering(VersionGenerator::class) {
kotlinNativeVersionInResources=true
defaultVersionFileLocation()
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
dependsOn(generateCompilerVersion)
}
tasks.clean {
doFirst {
val versionSourceDirectory = project.konanVersionGeneratedSrc()
if (versionSourceDirectory.exists()) {
versionSourceDirectory.delete()
}
}
}
sourceSets["main"].withConvention(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::class) {
kotlin.srcDir("src/main/kotlin")
if (!kotlinBuildProperties.isInJpsBuildIdeaSync) {
kotlin.srcDir("../kotlin-native/shared/src/library/kotlin")
kotlin.srcDir("../kotlin-native/shared/src/main/kotlin")
kotlin.srcDir("../kotlin-native/build-tools/src/main/kotlin")
kotlin.srcDir("../kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin")
kotlin.srcDir("../compiler/util-klib/src")
kotlin.srcDir("../native/utils/src")
}
kotlin.srcDir(project.kotlinNativeVersionSrc())
/**
* TODO: mentioned bellow and Co it'd be better to move to :kotlin-native:performance:buildSrc,
* because all this relates to benchmarking.
*/
kotlin.exclude("**/benchmark/*.kt")
kotlin.exclude("**/kotlin/MPPTools.kt")
kotlin.exclude("**/kotlin/RegressionsReporter.kt")
kotlin.exclude("**/kotlin/RunJvmTask.kt")
kotlin.exclude("**/kotlin/RunKotlinNativeTask.kt")
kotlin.exclude("**/kotlin/BuildRegister.kt")
kotlin.exclude("**/kotlin/benchmarkUtils.kt")
}
tasks.validatePlugins.configure {
enabled = false
}
java {
disableAutoTargetJvm()
}
dependencies {
implementation(kotlin("stdlib", embeddedKotlinVersion))
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
implementation("com.gradle.publish:plugin-publish-plugin:0.12.0")
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
@@ -162,28 +112,6 @@ dependencies {
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
implementation("org.gradle:test-retry-gradle-plugin:1.1.9")
implementation("com.gradle.enterprise:test-distribution-gradle-plugin:1.2.1")
compileOnly(gradleApi())
val kotlinVersion = project.bootstrapKotlinVersion
val ktorVersion = "1.2.1"
val slackApiVersion = "1.2.0"
val metadataVersion = "0.0.1-dev-10"
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
implementation("com.ullink.slack:simpleslackapi:$slackApiVersion")
implementation("io.ktor:ktor-client-auth:$ktorVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-metadata-klib:$metadataVersion")
if (kotlinBuildProperties.isInJpsBuildIdeaSync) {
implementation("org.jetbrains.kotlin:kotlin-native-utils:${project.bootstrapKotlinVersion}")
}
}
samWithReceiver {
@@ -198,26 +126,7 @@ java {
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += listOf(
"-Xopt-in=kotlin.RequiresOptIn",
"-Xskip-runtime-version-check",
"-Xsuppress-version-warnings",
"-Xopt-in=kotlin.ExperimentalStdlibApi"
)
}
tasks["build"].dependsOn(":prepare-deps:build")
sourceSets["main"].withConvention(org.gradle.api.tasks.GroovySourceSet::class) {
if (!kotlinBuildProperties.isInJpsBuildIdeaSync) {
groovy.srcDir("../kotlin-native/build-tools/src/main/groovy")
}
}
tasks.named("compileGroovy", GroovyCompile::class.java) {
classpath += project.files(tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java))
dependsOn(tasks.named("compileKotlin"))
}
allprojects {
tasks.register("checkBuild")
@@ -226,40 +135,3 @@ allprojects {
apply(from = "$rootDir/../gradle/cacheRedirector.gradle.kts")
}
}
gradlePlugin {
plugins {
create("compileToBitcode") {
id = "compile-to-bitcode"
implementationClass = "org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin"
}
create("runtimeTesting") {
id = "runtime-testing"
implementationClass = "org.jetbrains.kotlin.testing.native.RuntimeTestingPlugin"
}
create("konan") {
id = "konan"
implementationClass = "org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin"
}
// We bundle a shaded version of kotlinx-serialization plugin
create("kotlinx-serialization-native") {
id = "kotlinx-serialization-native"
implementationClass = "shadow.org.jetbrains.kotlinx.serialization.gradle.SerializationGradleSubplugin"
}
create("org.jetbrains.kotlin.konan") {
id = "org.jetbrains.kotlin.konan"
implementationClass = "org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin"
}
create("native") {
id = "native"
implementationClass = "org.jetbrains.gradle.plugins.tools.NativePlugin"
}
create("native-interop-plugin") {
id = "native-interop-plugin"
implementationClass = "org.jetbrains.kotlin.NativeInteropPlugin"
}
}
}

View File

@@ -14,13 +14,13 @@ pluginManagement {
buildscript {
repositories {
if (cacheRedirectorEnabled == 'true') {
maven { url "https://cache-redirector.jetbrains.com/maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies" }
maven { url "https://cache-redirector.jetbrains.com/kotlin.bintray.com/kotlin-dependencies" }
} else {
maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies" }
maven { url "https://kotlin.bintray.com/kotlin-dependencies" }
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.25")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.20")
}
}

View File

@@ -1,17 +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.konan
import java.io.*
val VERSION_PATH = "/META-INF/kotlin-native.compiler.version"
val CompilerVersion.Companion.CURRENT: CompilerVersion
get() {
return InputStreamReader(this::class.java.getResourceAsStream(VERSION_PATH)).use {
it.readLines().single().parseCompilerVersion()
}
}
val currentCompilerVersion = CompilerVersion.CURRENT

View File

@@ -18,5 +18,3 @@ val KotlinBuildProperties.proguard: Boolean get() = postProcessing && getBoolean
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", false)

View File

@@ -54,12 +54,11 @@ var Project.javaHome: String?
extra["javaHome"] = v
}
fun Project.generator(fqName: String, sourceSet: SourceSet? = null, configure: JavaExec.() -> Unit = {}) = smartJavaExec {
fun Project.generator(fqName: String, sourceSet: SourceSet? = null) = smartJavaExec {
classpath = (sourceSet ?: testSourceSet).runtimeClasspath
mainClass.set(fqName)
workingDir = rootDir
systemProperty("line.separator", "\n")
configure()
}
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {

View File

@@ -9,13 +9,10 @@
import org.gradle.api.GradleException
import org.gradle.api.Project
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.kotlin.dsl.accessors.runtime.addDependencyTo
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.project
import java.io.File
@@ -115,50 +112,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")
fun Project.testApiJUnit5(
vintageEngine: Boolean = false,
runner: Boolean = false,
suiteApi: Boolean = false
) {
with(dependencies) {
val platformVersion = commonVer("org.junit", "junit-bom")
testApi(platform("org.junit:junit-bom:$platformVersion"))
testApi("org.junit.jupiter:junit-jupiter")
if (vintageEngine) {
testApi("org.junit.vintage:junit-vintage-engine:$platformVersion")
}
val componentsVersion = commonVer("org.junit.platform", "")
val components = mutableListOf(
"org.junit.platform:junit-platform-commons",
"org.junit.platform:junit-platform-launcher"
)
if (runner) {
components += "org.junit.platform:junit-platform-runner"
}
if (suiteApi) {
components += "org.junit.platform:junit-platform-suite-api"
}
for (component in components) {
testApi("$component:$componentsVersion")
}
addDependencyTo<ExternalModuleDependency>(this, "testImplementation", intellijDep()) {
// This dependency is needed only for FileComparisonFailure
includeJars("idea_rt", rootProject = rootProject)
isTransitive = false
}
// This is needed only for using FileComparisonFailure, which relies on JUnit 3 classes
add("testRuntimeOnly", commonDep("junit:junit"))
}
}
private fun DependencyHandler.testApi(dependencyNotation: Any) {
add("testApi", dependencyNotation)
}
val Project.protobufVersion: String get() = findProperty("versions.protobuf") as String
val Project.protobufRepo: String

View File

@@ -5,13 +5,10 @@ import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.project
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.*
import java.io.File
const val kotlinEmbeddableRootPackage = "org.jetbrains.kotlin"
val kotlinEmbeddableRootPackage = "org.jetbrains.kotlin"
val packagesToRelocate =
listOf(
@@ -25,7 +22,6 @@ val packagesToRelocate =
"org.fusesource",
"net.jpountz",
"one.util.streamex",
"it.unimi.dsi.fastutil",
"kotlinx.collections.immutable"
)
@@ -35,23 +31,21 @@ val packagesToRelocate =
// But due to the shadow plugin bug (https://github.com/johnrengelman/shadow/issues/262) it is not possible to use
// packagesToRelocate list to for the include list. Therefore the exclude list has to be created.
val packagesToExcludeFromDummy =
listOf(
"org/jetbrains/kotlin/**",
"org/intellij/lang/annotations/**",
"org/jetbrains/jps/**",
"META-INF/**",
"com/sun/jna/**",
"com/thoughtworks/xstream/**",
"javaslang/**",
"*.proto",
"messages/**",
"net/sf/cglib/**",
"one/util/streamex/**",
"org/iq80/snappy/**",
"org/jline/**",
"org/xmlpull/**",
"*.txt"
)
listOf("org/jetbrains/kotlin/**",
"org/intellij/lang/annotations/**",
"org/jetbrains/jps/**",
"META-INF/**",
"com/sun/jna/**",
"com/thoughtworks/xstream/**",
"javaslang/**",
"*.proto",
"messages/**",
"net/sf/cglib/**",
"one/util/streamex/**",
"org/iq80/snappy/**",
"org/jline/**",
"org/xmlpull/**",
"*.txt")
private fun ShadowJar.configureEmbeddableCompilerRelocation(withJavaxInject: Boolean = true) {
relocate("com.google.protobuf", "org.jetbrains.kotlin.protobuf")
@@ -73,8 +67,8 @@ private fun Project.compilerShadowJar(taskName: String, body: ShadowJar.() -> Un
dependencies.add(compilerJar.name, dependencies.project(":kotlin-compiler", configuration = "runtimeJar"))
return tasks.register<ShadowJar>(taskName) {
destinationDirectory.set(project.file(File(buildDir, "libs")))
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
destinationDir = File(buildDir, "libs")
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
from(compilerJar)
body()
}
@@ -113,8 +107,8 @@ fun Project.embeddableCompilerDummyForDependenciesRewriting(
)
return tasks.register<ShadowJar>(taskName) {
destinationDirectory.set(project.file(File(buildDir, "libs")))
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
destinationDir = File(buildDir, "libs")
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
from(compilerDummyJar)
configureEmbeddableCompilerRelocation(withJavaxInject = false)
body()
@@ -125,7 +119,7 @@ fun Project.rewriteDepsToShadedJar(
originalJarTask: TaskProvider<out Jar>, shadowJarTask: TaskProvider<out Jar>, body: Jar.() -> Unit = {}
): TaskProvider<out Jar> {
originalJarTask.configure {
archiveClassifier.set("original")
classifier = "original"
}
val compilerDummyJarFile by lazy { configurations.getAt("compilerDummyJar").singleFile }
@@ -138,7 +132,7 @@ fun Project.rewriteDepsToShadedJar(
// which leads to the content of that JAR being excluded as well:
exclude { it.file == compilerDummyJarFile }
archiveClassifier.set("original")
classifier = ""
body()
}
return shadowJarTask

View File

@@ -10,12 +10,12 @@ 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);
JDK_16, JDK_17, JDK_18, JDK_9, JDK_10(false), JDK_11(false);
fun isMandatory(): Boolean = mandatory
}
val jdkAlternativeVarNames = mapOf(JdkMajorVersion.JDK_9 to listOf("JDK_19"), JdkMajorVersion.JDK_15 to listOf("JDK_15_0"))
val jdkAlternativeVarNames = mapOf(JdkMajorVersion.JDK_9 to listOf("JDK_19"))
data class JdkId(val explicit: Boolean, val majorVersion: JdkMajorVersion, var version: String, var homeDir: File)
@@ -101,12 +101,8 @@ fun MutableCollection<JdkId>.discoverJdks(project: 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+(.+)"""))
private val macOsJavaHomeOutRegexes = listOf(Regex("""\s+(\S+),\s+(\S+):\s+".*?"\s+(.+)"""),
Regex("""\s+(\S+)\s+\((.*?)\):\s+(.+)"""))
fun MutableCollection<JdkId>.discoverJdksOnMacOS(project: Project) {
val procBuilder = ProcessBuilder("/usr/libexec/java_home", "-V").redirectErrorStream(true)

View File

@@ -76,6 +76,8 @@ fun Project.jpsStandalone() = "kotlin.build:jps-standalone:${rootProject.extra["
fun Project.nodeJSPlugin() = "kotlin.build:NodeJS:${rootProject.extra["versions.idea.NodeJS"]}"
fun Project.androidDxJar() = "org.jetbrains.kotlin:android-dx:${rootProject.extra["versions.androidBuildTools"]}"
fun Project.jpsBuildTest() = "com.jetbrains.intellij.idea:jps-build-test:${rootProject.extra["versions.intellijSdk"]}"
fun Project.kotlinxCollectionsImmutable() = "org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:${rootProject.extra["versions.kotlinx-collections-immutable"]}"
@@ -130,10 +132,12 @@ object IntellijRootUtils {
}
}
@Suppress("UNCHECKED_CAST")
fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project, jarsFilterPredicate: (String) -> Boolean = { true }): Unit =
fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project) =
includeJars(*(project.rootProject.extra["IntellijCoreDependencies"] as List<String>).toTypedArray(), rootProject = project.rootProject)
fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project, jarsFilterPredicate: (String) -> Boolean) =
includeJars(
*(project.rootProject.extra["IntellijCoreDependencies"] as List<String>).filter(jarsFilterPredicate).toTypedArray(),
*(project.rootProject.extra["IntellijCoreDependencies"] as List<String>).filter { jarsFilterPredicate(it) }.toTypedArray(),
rootProject = project.rootProject
)

View File

@@ -1,228 +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.gradle.plugins.tools
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.withType
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.jetbrains.kotlin.konan.target.HostManager.Companion.hostIsMac
import org.jetbrains.kotlin.konan.target.HostManager.Companion.hostIsMingw
import java.io.File
import kotlin.collections.List
import kotlin.collections.MutableMap
import kotlin.collections.addAll
import kotlin.collections.drop
import kotlin.collections.first
import kotlin.collections.flatMap
import kotlin.collections.forEach
import kotlin.collections.listOf
import kotlin.collections.map
import kotlin.collections.mutableListOf
import kotlin.collections.mutableMapOf
import kotlin.collections.plusAssign
import kotlin.collections.set
import kotlin.collections.toTypedArray
open class NativePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.apply<BasePlugin>()
project.extensions.create("native", NativeToolsExtension::class.java, project)
}
}
abstract class ToolExecutionTask : DefaultTask() {
@get:OutputFile
abstract var output: File
@get:InputFiles
abstract var input: List<File>
@get:Input
abstract var cmd: String
@get:Input
abstract var args: List<String>
@TaskAction
fun action() {
project.exec {
executable(cmd)
args(*this@ToolExecutionTask.args.toTypedArray())
}
}
}
class ToolPatternImpl(val extension: NativeToolsExtension, val output:String, vararg val input: String):ToolPattern {
val tool = mutableListOf<String>()
val args = mutableListOf<String>()
override fun ruleOut(): String = output
override fun ruleInFirst(): String = input.first()
override fun ruleInAll(): Array<String> = arrayOf(*input)
override fun flags(vararg args: String) {
this.args.addAll(args)
}
override fun tool(vararg arg: String) {
tool.addAll(arg)
}
override fun env(name: String) = emptyArray<String>()
fun configure(task: ToolExecutionTask, configureDepencies:Boolean) {
extension.cleanupfiles += output
task.input = input.map {
extension.project.file(it)
}
task.dependsOn(":kotlin-native:dependencies:update")
if (configureDepencies)
task.input.forEach { task.dependsOn(it.name) }
val file = extension.project.file(output)
file.parentFile.mkdirs()
task.output = file
task.cmd = tool.first()
task.args = listOf(*tool.drop(1).toTypedArray(), *args.toTypedArray())
}
}
open class SourceSet(
val sourceSets: SourceSets,
val name: String,
val initialDirectory: File = sourceSets.project.projectDir,
val initialSourceSet: SourceSet? = null,
val rule: Pair<String, String>? = null
) {
var collection = sourceSets.project.objects.fileCollection() as FileCollection
fun file(path: String) {
collection = collection.plus(sourceSets.project.files("${initialDirectory.absolutePath}/$path"))
}
fun dir(path: String) {
sourceSets.project.fileTree("${initialDirectory.absolutePath}/$path").files.forEach {
collection = collection.plus(sourceSets.project.files(it))
}
}
fun transform(suffixes: Pair<String, String>): SourceSet {
return SourceSet(
sourceSets,
name,
sourceSets.project.file("${sourceSets.project.buildDir}/$name/${suffixes.first}_${suffixes.second}/"),
this,
suffixes
)
}
fun implicitTasks(): Array<TaskProvider<*>> {
rule ?: return emptyArray()
initialSourceSet?.implicitTasks()
return initialSourceSet!!.collection
.filter { !it.isDirectory() }
.filter { it.name.endsWith(rule.first) }
.map { it.relativeTo(initialSourceSet.initialDirectory) }
.map { it.path }
.map { it to (it.substring(0, it.lastIndexOf(rule.first)) + rule.second) }
.map {
file(it.second)
sourceSets.project.file("${initialSourceSet.initialDirectory.path}/${it.first}") to sourceSets.project.file("${initialDirectory.path}/${it.second}")
}.map {
sourceSets.project.tasks.register<ToolExecutionTask>(it.second.name, ToolExecutionTask::class.java) {
val toolConfiguration = ToolPatternImpl(sourceSets.extension, it.second.path, it.first.path)
sourceSets.extension.toolPatterns[rule]!!.invoke(toolConfiguration)
toolConfiguration.configure(this, initialSourceSet.rule != null)
}
}.toTypedArray()
}
}
class SourceSets(val project: Project, val extension: NativeToolsExtension, val sources: MutableMap<String, SourceSet>) :
MutableMap<String, SourceSet> by sources {
operator fun String.invoke(initialDirectory: File = project.projectDir, configuration: SourceSet.() -> Unit) {
sources[this] = SourceSet(this@SourceSets, this, initialDirectory).also {
configuration(it)
}
}
}
interface Environment {
operator fun String.invoke(vararg values: String)
}
interface ToolPattern {
fun ruleOut(): String
fun ruleInFirst(): String
fun ruleInAll(): Array<String>
fun flags(vararg args: String): Unit
fun tool(vararg arg: String): Unit
fun env(name: String): Array<String>
}
typealias ToolPatternConfiguration = ToolPattern.() -> Unit
typealias EnvironmentConfiguration = Environment.() -> Unit
class ToolConfigurationPatterns(
val extension: NativeToolsExtension,
val patterns: MutableMap<Pair<String, String>, ToolPatternConfiguration>
) : MutableMap<Pair<String, String>, ToolPatternConfiguration> by patterns {
operator fun Pair<String, String>.invoke(configuration: ToolPatternConfiguration) {
patterns[this] = configuration
}
}
open class NativeToolsExtension(val project: Project) {
val sourceSets = SourceSets(project, this, mutableMapOf<String, SourceSet>())
val toolPatterns = ToolConfigurationPatterns(this, mutableMapOf<Pair<String, String>, ToolPatternConfiguration>())
val cleanupfiles = mutableListOf<String>()
fun sourceSet(configuration: SourceSets.() -> Unit) {
sourceSets.configuration()
}
var environmentConfiguration: EnvironmentConfiguration? = null
fun environment(configuration: EnvironmentConfiguration) {
environmentConfiguration = configuration
}
fun suffixes(configuration: ToolConfigurationPatterns.() -> Unit) = toolPatterns.configuration()
fun target(name: String, vararg objSet: SourceSet, configuration: ToolPatternConfiguration) {
project.tasks.withType<Delete>().named(LifecycleBasePlugin.CLEAN_TASK_NAME).configure {
doLast {
delete(*this@NativeToolsExtension.cleanupfiles.toTypedArray())
}
}
sourceSets.project.tasks.create<ToolExecutionTask>(name, ToolExecutionTask::class.java) {
objSet.forEach {
dependsOn(it.implicitTasks())
}
val deps = objSet.flatMap { it.collection.files }.map { it.path }
val toolConfiguration = ToolPatternImpl(sourceSets.extension, "${project.buildDir.path}/$name", *deps.toTypedArray())
toolConfiguration.configuration()
toolConfiguration.configure(this, false )
}
}
}
fun solib(name: String) = when {
hostIsMingw -> "$name.dll"
hostIsMac -> "lib$name.dylib"
else -> "lib$name.so"
}
fun lib(name:String) = when {
hostIsMingw -> "$name.lib"
else -> "lib$name.a"
}

View File

@@ -18,12 +18,8 @@ import java.util.*
internal const val PLUGIN_MARKER_SUFFIX = ".gradle.plugin"
@OptIn(ExperimentalStdlibApi::class)
@UseExperimental(ExperimentalStdlibApi::class)
fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
fun Project.isSonatypePublish(): Boolean =
hasProperty("isSonatypePublish") && property("isSonatypePublish") as Boolean
val pluginDevelopment = extensions.getByType<PluginBundleExtension>()
val publishingExtension = extensions.getByType<PublishingExtension>()
val mainPublication = publishingExtension.publications[KotlinBuildPublishingPlugin.PUBLICATION_NAME] as MavenPublication
@@ -36,12 +32,7 @@ fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
tasks.named<PublishToMavenRepository>(
"publish${markerPublication.name.capitalize(Locale.ROOT)}PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository"
).apply {
configureRepository()
configure {
onlyIf { !isSonatypePublish() }
}
}
).configureRepository()
}
}

View File

@@ -41,7 +41,7 @@ open class DexMethodCount : DefaultTask() {
dependsOn(jar)
}
@Internal // plain output properties are not supported, mark as internal to suppress warning from validatePlugins
@Internal // plain output properties are not supported, mark as internal to suppress warning from validateTaskProperties
lateinit var counts: Counts
@get:OutputFile

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -8,6 +8,7 @@ package plugins
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Usage
import org.gradle.api.component.AdhocComponentWithVariants
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.publish.PublishingExtension
@@ -22,6 +23,7 @@ import org.gradle.plugins.signing.SigningPlugin
import java.util.*
import javax.inject.Inject
class KotlinBuildPublishingPlugin @Inject constructor(
private val componentFactory: SoftwareComponentFactory
) : Plugin<Project> {
@@ -45,7 +47,7 @@ class KotlinBuildPublishingPlugin @Inject constructor(
}
}
val kotlinLibraryComponent = componentFactory.adhoc(ADHOC_COMPONENT_NAME)
val kotlinLibraryComponent = componentFactory.adhoc(ADHOC_COMPONENT_NAME) as AdhocComponentWithVariants
components.add(kotlinLibraryComponent)
kotlinLibraryComponent.addVariantsFromConfiguration(publishedCompile) { mapToMavenScope("compile") }
kotlinLibraryComponent.addVariantsFromConfiguration(publishedRuntime) { mapToMavenScope("runtime") }
@@ -71,11 +73,62 @@ class KotlinBuildPublishingPlugin @Inject constructor(
create<MavenPublication>(PUBLICATION_NAME) {
from(kotlinLibraryComponent)
configureKotlinPomAttributes(project)
pom {
packaging = "jar"
name.set(humanReadableName(project))
description.set(project.description ?: humanReadableName(project))
url.set("https://kotlinlang.org/")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
scm {
url.set("https://github.com/JetBrains/kotlin")
connection.set("scm:git:https://github.com/JetBrains/kotlin.git")
developerConnection.set("scm:git:https://github.com/JetBrains/kotlin.git")
}
developers {
developer {
name.set("Kotlin Team")
organization.set("JetBrains")
organizationUrl.set("https://www.jetbrains.com")
}
}
}
}
}
repositories {
maven {
name = REPOSITORY_NAME
url = file("${project.rootDir}/build/repo").toURI()
}
}
}
configureDefaultPublishing()
val signingRequired = provider {
project.findProperty("signingRequired")?.toString()?.toBoolean()
?: project.property("isSonatypeRelease") as Boolean
}
configure<SigningExtension> {
setRequired(signingRequired)
sign(extensions.getByType<PublishingExtension>().publications[PUBLICATION_NAME])
useGpgCmd()
}
tasks.withType<Sign>().configureEach {
setOnlyIf { signingRequired.get() }
}
tasks.register("install") {
dependsOn(tasks.named("publishToMavenLocal"))
}
tasks.named<PublishToMavenRepository>("publish${PUBLICATION_NAME}PublicationTo${REPOSITORY_NAME}Repository")
.configureRepository()
}
companion object {
@@ -86,84 +139,13 @@ class KotlinBuildPublishingPlugin @Inject constructor(
const val COMPILE_CONFIGURATION = "publishedCompile"
const val RUNTIME_CONFIGURATION = "publishedRuntime"
@UseExperimental(ExperimentalStdlibApi::class)
fun humanReadableName(project: Project) =
project.name.split("-").joinToString(separator = " ") { it.capitalize(Locale.ROOT) }
}
}
@OptIn(ExperimentalStdlibApi::class)
private fun humanReadableName(name: String) =
name.split("-").joinToString(separator = " ") { it.capitalize(Locale.ROOT) }
fun MavenPublication.configureKotlinPomAttributes(project: Project, explicitDescription: String? = null) {
val publication = this
pom {
packaging = "jar"
name.set(humanReadableName(publication.artifactId))
description.set(explicitDescription ?: project.description ?: humanReadableName(publication.artifactId))
url.set("https://kotlinlang.org/")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
scm {
url.set("https://github.com/JetBrains/kotlin")
connection.set("scm:git:https://github.com/JetBrains/kotlin.git")
developerConnection.set("scm:git:https://github.com/JetBrains/kotlin.git")
}
developers {
developer {
name.set("Kotlin Team")
organization.set("JetBrains")
organizationUrl.set("https://www.jetbrains.com")
}
}
}
}
fun Project.configureDefaultPublishing() {
configure<PublishingExtension> {
repositories {
maven {
name = KotlinBuildPublishingPlugin.REPOSITORY_NAME
url = file("${project.rootDir}/build/repo").toURI()
}
}
}
configureSigning()
tasks.register("install") {
dependsOn(tasks.named("publishToMavenLocal"))
}
tasks.withType<PublishToMavenRepository>()
.matching { it.name.endsWith("PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository") }
.all { configureRepository() }
}
private fun Project.configureSigning() {
val signingRequired = provider {
project.findProperty("signingRequired")?.toString()?.toBoolean()
?: project.property("isSonatypeRelease") as Boolean
}
configure<SigningExtension> {
setRequired(signingRequired)
sign(extensions.getByType<PublishingExtension>().publications) // all publications
useGpgCmd()
}
tasks.withType<Sign>().configureEach {
setOnlyIf { signingRequired.get() }
}
}
fun TaskProvider<PublishToMavenRepository>.configureRepository() =
configure { configureRepository() }
private fun PublishToMavenRepository.configureRepository() {
fun TaskProvider<PublishToMavenRepository>.configureRepository() = configure {
dependsOn(project.rootProject.tasks.named("preparePublication"))
doFirst {
val preparePublication = project.rootProject.tasks.named("preparePublication").get()
@@ -181,4 +163,4 @@ private fun PublishToMavenRepository.configureRepository() {
}
}
}
}
}

View File

@@ -1,4 +1,3 @@
@file:Suppress("DEPRECATION")
package plugins
import org.codehaus.groovy.runtime.InvokerHelper
@@ -17,8 +16,10 @@ 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> {

View File

@@ -30,7 +30,6 @@ val SourceSet.projectDefault: Project.() -> Unit
}
"test" -> {
java.srcDirs("test", "tests")
this@projectDefault.resources.srcDir("testResources")
}
}
}

View File

@@ -1,6 +1,17 @@
/*
* 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.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -20,65 +31,51 @@ import java.lang.Character.isUpperCase
import java.nio.file.Files
import java.nio.file.Path
val kotlinGradlePluginAndItsRequired = arrayOf(
":kotlin-allopen",
":kotlin-noarg",
":kotlin-sam-with-receiver",
":kotlin-android-extensions",
":kotlin-parcelize-compiler",
":kotlin-build-common",
":kotlin-compiler-embeddable",
":native:kotlin-native-utils",
":kotlin-util-klib",
":kotlin-util-io",
":kotlin-compiler-runner",
":kotlin-daemon-embeddable",
":kotlin-daemon-client",
":kotlin-gradle-plugin-api",
":kotlin-gradle-plugin",
":kotlin-gradle-plugin-model",
":kotlin-reflect",
":kotlin-annotation-processing-gradle",
":kotlin-test",
":kotlin-gradle-subplugin-example",
":kotlin-stdlib-common",
":kotlin-stdlib",
":kotlin-stdlib-jdk8",
":kotlin-stdlib-js",
":examples:annotation-processor-example",
":kotlin-script-runtime",
":kotlin-scripting-common",
":kotlin-scripting-jvm",
":kotlin-scripting-compiler-embeddable",
":kotlin-scripting-compiler-impl-embeddable",
":kotlin-test-js-runner",
":native:kotlin-klib-commonizer-embeddable",
":native:kotlin-klib-commonizer-api"
)
fun Task.dependsOnKotlinGradlePluginInstall() {
kotlinGradlePluginAndItsRequired.forEach {
dependsOn("${it}:install")
}
fun Task.dependsOnKotlinPluginInstall() {
dependsOn(
":kotlin-allopen:install",
":kotlin-noarg:install",
":kotlin-sam-with-receiver:install",
":kotlin-android-extensions:install",
":kotlin-parcelize-compiler:install",
":kotlin-build-common:install",
":kotlin-compiler-embeddable:install",
":native:kotlin-native-utils:install",
":kotlin-util-klib:install",
":kotlin-util-io:install",
":kotlin-compiler-runner:install",
":kotlin-daemon-embeddable:install",
":kotlin-daemon-client:install",
":kotlin-gradle-plugin-api:install",
":kotlin-gradle-plugin:install",
":kotlin-gradle-plugin-model:install",
":kotlin-reflect:install",
":kotlin-annotation-processing-gradle:install",
":kotlin-test:kotlin-test-common:install",
":kotlin-test:kotlin-test-annotations-common:install",
":kotlin-test:kotlin-test-jvm:install",
":kotlin-test:kotlin-test-js:install",
":kotlin-test:kotlin-test-junit:install",
":kotlin-gradle-subplugin-example:install",
":kotlin-stdlib-common:install",
":kotlin-stdlib:install",
":kotlin-stdlib-jdk8:install",
":kotlin-stdlib-js:install",
":examples:annotation-processor-example:install",
":kotlin-script-runtime:install",
":kotlin-scripting-common:install",
":kotlin-scripting-jvm:install",
":kotlin-scripting-compiler-embeddable:install",
":kotlin-scripting-compiler-impl-embeddable:install",
":kotlin-test-js-runner:install",
":native:kotlin-klib-commonizer-embeddable:install"
)
}
fun Task.dependsOnKotlinGradlePluginPublish() {
kotlinGradlePluginAndItsRequired.forEach {
project.rootProject.tasks.findByPath("${it}:publish")?.let { task ->
dependsOn(task)
}
}
}
/**
* @param parallel is redundant if @param jUnit5Enabled is true, because
* JUnit5 supports parallel test execution by itself, without gradle help
*/
fun Project.projectTest(
taskName: String = "test",
parallel: Boolean = false,
shortenTempRootName: Boolean = false,
jUnit5Enabled: Boolean = false,
body: Test.() -> Unit = {}
): TaskProvider<Test> = getOrCreateTask(taskName) {
doFirst {
@@ -112,29 +109,12 @@ fun Project.projectTest(
}
}
val parentNames = if (jUnit5Enabled) {
/*
* If we run test from inner test class with junit 5 we need
* to include all containing classes of our class
*/
val nestedNames = classFileNameWithoutExtension.split("$")
mutableListOf(nestedNames.first()).also {
for (s in nestedNames.subList(1, nestedNames.size)) {
it += "${it.last()}\$$s"
}
}
} else emptyList()
include { treeElement ->
val path = treeElement.path
if (treeElement.isDirectory) {
include {
val path = it.path
if (it.isDirectory) {
classFileNameWithoutExtension.startsWith(path)
} else {
if (jUnit5Enabled) {
path == classFileName || (path.endsWith(".class") && parentNames.any { path.startsWith(it) })
} else {
path == classFileName || (path.endsWith(".class") && path.startsWith("$classFileNameWithoutExtension$"))
}
path == classFileName || (path.endsWith(".class") && path.startsWith("$classFileNameWithoutExtension$"))
}
}
}
@@ -174,7 +154,7 @@ fun Project.projectTest(
var subProjectTempRoot: Path? = null
doFirst {
val teamcity = rootProject.findProperty("teamcity") as? Map<*, *>
val teamcity = rootProject.findProperty("teamcity") as? Map<Any?, *>
val systemTempRoot =
// TC by default doesn't switch `teamcity.build.tempDir` to 'java.io.tmpdir' so it could cause to wasted disk space
// Should be fixed soon on Teamcity side
@@ -197,10 +177,10 @@ fun Project.projectTest(
}
}
if (parallel && !jUnit5Enabled) {
if (parallel) {
maxParallelForks =
project.findProperty("kotlin.test.maxParallelForks")?.toString()?.toInt()
?: (Runtime.getRuntime().availableProcessors() / if (kotlinBuildProperties.isTeamcityBuild) 2 else 4).coerceAtLeast(1)
?: Math.max(Runtime.getRuntime().availableProcessors() / if (kotlinBuildProperties.isTeamcityBuild) 2 else 4, 1)
}
body()
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
import com.gradle.enterprise.gradleplugin.testdistribution.TestDistributionExtension
import org.gradle.api.tasks.testing.Test
import org.gradle.internal.os.OperatingSystem
fun Test.configureTestDistribution(configure: TestDistributionExtension.() -> Unit = {}) {
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
val testDistributionEnabled = project.findProperty("kotlin.build.test.distribution.enabled")?.toString()?.toBoolean()
?: isTeamcityBuild
useJUnitPlatform()
extensions.configure(TestDistributionExtension::class.java) {
enabled.set(testDistributionEnabled)
maxRemoteExecutors.set(20)
if (isTeamcityBuild) {
requirements.set(setOf("os=${OperatingSystem.current().familyName}"))
} else {
maxLocalExecutors.set(0)
}
configure()
}
}
fun Test.isTestDistributionEnabled(): Boolean =
extensions.findByType(TestDistributionExtension::class.java)?.enabled?.orNull ?: false

View File

@@ -1,11 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
ext {
isD8Enabled = project.findProperty('android.enableD8').toBoolean()
}
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.android.tools.build:gradle:3.5.3'
}
}
apply plugin: 'com.android.application'
@@ -17,7 +20,7 @@ repositories {
android {
compileSdkVersion 26
buildToolsVersion "29.0.3"
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "org.jetbrains.kotlin.android.tests"
@@ -37,6 +40,14 @@ android {
packagingOptions { exclude 'META-INF/build.txt' }
//TODO run under java 6, cause there is error on implicit 'stream' import in 'asWithMutable' test
lintOptions {
abortOnError false
}
compileOptions {
incremental = false
}
dexOptions {
dexInProcess false
@@ -49,9 +60,11 @@ android {
resultsDir = "build/test/results"
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
if (isD8Enabled) {
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
flavorDimensions "box"
@@ -73,20 +86,15 @@ android {
dimension "box"
}
common_ir0 {
dimension "box"
}
common_ir1 {
dimension "box"
}
if (isD8Enabled) {
jvm80 {
dimension "box"
}
common_ir2 {
dimension "box"
}
reflect_ir0 {
dimension "box"
reflectjvm80 {
dimension "box"
}
}
}

View File

@@ -1,2 +1,3 @@
#don't try to download android specific tools within gradle: licence acceptance will be required
android.builder.sdkDownload=false
android.builder.sdkDownload=false
android.enableD8=true

View File

@@ -19,10 +19,6 @@ dependencies {
testCompile(project(":kotlin-reflect"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(commonDep("junit:junit"))
testApi(projectTests(":compiler:test-infrastructure"))
testApi(projectTests(":compiler:test-infrastructure-utils"))
testApi(projectTests(":compiler:tests-compiler-utils"))
testApi(projectTests(":compiler:tests-common-new"))
testCompile(projectTests(":jps-plugin"))
testCompile(commonDep("junit:junit"))
@@ -38,11 +34,11 @@ dependencies {
Platform[201].orLower {
testCompile(intellijDep()) { includeJars("groovy-all", rootProject = rootProject) }
}
testCompile(intellijPluginDep("java")) { includeJars("jps-builders") }
Platform[192].orHigher {
testCompile(intellijPluginDep("java")) { includeJars("jps-builders") }
}
testCompile(jpsStandalone()) { includeJars("jps-model") }
testCompile(jpsBuildTest())
testCompile("org.junit.platform:junit-platform-launcher:${commonVer("org.junit.platform", "")}")
}
sourceSets {

View File

@@ -0,0 +1,62 @@
/*
* 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.android.tests;
import org.jetbrains.kotlin.jps.build.BaseKotlinJpsBuildTestCase;
import org.junit.Ignore;
import java.io.File;
import java.io.IOException;
@Ignore
public class AndroidJpsBuildTestCase extends BaseKotlinJpsBuildTestCase {
private static final String PROJECT_NAME = "android-module";
private static final String SDK_NAME = "Android_SDK";
private final File workDir = new File(AndroidRunner.getPathManager().getTmpFolder());
public void doTest() {
initProject();
rebuildAllModules();
buildAllModules().assertSuccessful();
}
@Override
protected String getProjectName() {
return "android-module";
}
@Override
protected void runTest() {
doTest();
}
@Override
public String getName() {
return "AndroidJpsTest";
}
@Override
protected File doGetProjectDir() throws IOException {
return workDir;
}
private void initProject() {
addJdk(SDK_NAME, AndroidRunner.getPathManager().getPlatformFolderInAndroidSdk() + "/android.jar");
loadProject(workDir.getAbsolutePath() + File.separator + PROJECT_NAME + ".ipr");
}
}

View File

@@ -25,7 +25,7 @@ import org.junit.runners.AllTests;
import java.io.File;
@RunWith(AllTests.class)
//@RunWith(AllTests.class)
public class AndroidRunner {
private static PathManager pathManager;
@@ -46,8 +46,12 @@ public class AndroidRunner {
CodegenTestsOnAndroidGenerator.generate(pathManager);
System.out.println("Run tests on Android...");
return CodegenTestsOnAndroidRunner.runTestsInEmulator(pathManager);
System.out.println("Run tests on android...");
TestSuite suite = CodegenTestsOnAndroidRunner.runTestsInEmulator(pathManager);
//AndroidJpsBuildTestCase indirectly depends on UsefulTestCase which compiled against java 8
//TODO: Need add separate run configuration for AndroidJpsBuildTestCase
//suite.addTest(new AndroidJpsBuildTestCase());
return suite;
}
public void tearDown() throws Exception {

View File

@@ -20,9 +20,7 @@ import com.intellij.openapi.util.Ref
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.sourceFileProvider
import org.jetbrains.kotlin.test.KotlinBaseTest
import java.io.File
import java.util.regex.Pattern
@@ -36,24 +34,28 @@ private data class OldPackageAndNew(val oldFqName: FqName, val newFqName: FqName
internal fun patchFilesAndAddTest(
testFile: File,
module: TestModule,
services: TestServices,
testFiles: List<KotlinBaseTest.TestFile>,
filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter
): FqName {
): FqName? {
if (testFiles.any { it.name.endsWith(".java") }) {
//TODO support java files
return null
}
val ktFiles = testFiles.filter { it.name.endsWith(".kt") }
if (ktFiles.isEmpty()) return null
val newPackagePrefix = testFile.path.replace("\\\\|-|\\.|/".toRegex(), "_")
val oldPackage = Ref<FqName>()
val isJvmName = Ref<Boolean>(false)
val testFiles = module.files
val isSingle = testFiles.size == 1
val resultFiles = testFiles.map {
val fileName = if (isSingle) it.name else testFile.name.substringBeforeLast(".kt") + "/" + it.name
val content = services.sourceFileProvider.getContentOfSourceFile(it)
TestClassInfo(
fileName,
changePackage(newPackagePrefix, content, oldPackage, isJvmName),
changePackage(newPackagePrefix, it.content, oldPackage, isJvmName),
oldPackage.get(),
isJvmName.get(),
getGeneratedClassName(File(fileName), content, newPackagePrefix, oldPackage.get())
getGeneratedClassName(File(fileName), it.content, newPackagePrefix, oldPackage.get())
)
}
val packages =

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.android.tests
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.io.FileUtil
@@ -12,34 +13,20 @@ import com.intellij.openapi.util.io.FileUtilRt
import org.jetbrains.kotlin.cli.common.output.writeAllTo
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.codegen.CodegenTestFiles
import org.jetbrains.kotlin.codegen.GenerationUtils
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.impl.BackendKindExtractorImpl
import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.junit.Assert
import java.io.File
import java.io.FileWriter
import java.io.IOException
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.Path
import kotlin.io.path.createTempDirectory
import kotlin.test.assertTrue
data class ConfigurationKey(val kind: ConfigurationKind, val jdkKind: TestJdkKind, val configuration: String)
@@ -54,18 +41,17 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
//keep it globally to avoid test grouping on TC
private val generatedTestNames = hashSetOf<String>()
private val COMMON = FlavorConfig(TargetBackend.ANDROID,"common", 3)
private val REFLECT = FlavorConfig(TargetBackend.ANDROID, "reflect", 1)
private val COMMON = FlavorConfig("common", 3);
private val REFLECT = FlavorConfig("reflect", 1);
private val JVM8 = FlavorConfig("jvm8", 1);
private val JVM8REFLECT = FlavorConfig("reflectjvm8", 1);
private val COMMON_IR = FlavorConfig(TargetBackend.ANDROID_IR, "common_ir", 3)
private val REFLECT_IR = FlavorConfig(TargetBackend.ANDROID_IR,"reflect_ir", 1)
class FlavorConfig(private val backend: TargetBackend, private val prefix: String, val limit: Int) {
class FlavorConfig(private val prefix: String, val limit: Int) {
private var writtenFilesCount = 0
fun printStatistics() {
println("FlavorTestCompiler for $backend: $prefix, generated file count: $writtenFilesCount")
println("FlavorTestCompiler: $prefix, generated file count: $writtenFilesCount")
}
fun getFlavorForNewFiles(newFilesCount: Int): String {
@@ -111,7 +97,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
it.setExecutable(true)
}
}
File("./gradlew.bat").copyTo(File(projectRoot, "gradlew.bat"))
File("./gradlew.bat").copyTo(File(projectRoot, "gradlew.bat"));
val file = File(target, "gradle-wrapper.properties")
file.readLines().map {
when {
@@ -148,47 +134,27 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
private fun generateTestsAndFlavourSuites() {
println("Generating test files...")
val folders = arrayOf(
File("compiler/testData/codegen/box"),
File("compiler/testData/codegen/boxInline")
)
generateTestMethodsForDirectories(
TargetBackend.ANDROID,
COMMON,
REFLECT,
*folders
)
generateTestMethodsForDirectories(
TargetBackend.ANDROID_IR,
COMMON_IR,
REFLECT_IR,
*folders
)
generateTestMethodsForDirectories(File("compiler/testData/codegen/box"), File("compiler/testData/codegen/boxInline"))
pendingUnitTestGenerators.values.forEach { it.generate() }
}
private fun generateTestMethodsForDirectories(
backend: TargetBackend,
commonFlavor: FlavorConfig,
reflectionFlavor: FlavorConfig,
vararg dirs: File
) {
private fun generateTestMethodsForDirectories(vararg dirs: File) {
val holders = mutableMapOf<ConfigurationKey, FilesWriter>()
for (dir in dirs) {
val files = dir.listFiles() ?: error("Folder with testData is empty: ${dir.absolutePath}")
processFiles(files, holders, backend, commonFlavor, reflectionFlavor)
processFiles(files, holders)
}
holders.values.forEach {
it.writeFilesOnDisk()
}
commonFlavor.printStatistics()
reflectionFlavor.printStatistics()
COMMON.printStatistics()
REFLECT.printStatistics()
JVM8.printStatistics()
JVM8REFLECT.printStatistics()
}
internal inner class FilesWriter(
@@ -272,14 +238,10 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
}
}
@OptIn(TestInfrastructureInternals::class)
@Throws(IOException::class)
private fun processFiles(
files: Array<File>,
holders: MutableMap<ConfigurationKey, FilesWriter>,
backend: TargetBackend,
commmonFlavor: FlavorConfig,
reflectionFlavor: FlavorConfig
holders: MutableMap<ConfigurationKey, FilesWriter>
) {
holders.values.forEach {
it.writeFilesOnDiskIfNeeded()
@@ -289,7 +251,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
if (file.isDirectory) {
val listFiles = file.listFiles()
if (listFiles != null) {
processFiles(listFiles, holders, backend, commmonFlavor, reflectionFlavor)
processFiles(listFiles, holders)
}
} else if (FileUtilRt.getExtension(file.name) != KotlinFileType.EXTENSION) {
// skip non kotlin files
@@ -298,13 +260,14 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
continue
}
if (!InTextDirectivesUtils.isPassingTarget(backend.compatibleWith, file) ||
if (!InTextDirectivesUtils.isPassingTarget(TargetBackend.JVM, file) ||
InTextDirectivesUtils.isIgnoredTarget(TargetBackend.ANDROID, file)
) {
continue
}
val fullFileText = FileUtil.loadFile(file, true)
val fullFileText =
FileUtil.loadFile(file, true).replace("COROUTINES_PACKAGE", "kotlin.coroutines")
if (fullFileText.contains("// WITH_COROUTINES")) {
if (fullFileText.contains("kotlin.coroutines.experimental")) continue
@@ -314,106 +277,48 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
//TODO support JvmPackageName
if (fullFileText.contains("@file:JvmPackageName(")) continue
// TODO: Support jvm assertions
if (fullFileText.contains("// ASSERTIONS_MODE: jvm")) continue
if (fullFileText.contains("// MODULE: ")) continue
if (fullFileText.contains("// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm")) continue
val targets = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fullFileText, "// JVM_TARGET:")
.also { it.remove(JvmTarget.JVM_1_6.description) }
val isAtLeastJvm8Target = !targets.contains(JvmTarget.JVM_1_6.description)
if (isAtLeastJvm8Target && fullFileText.contains("@Target(AnnotationTarget.TYPE)")) {
//TODO: type annotations supported on sdk 26 emulator
continue
}
val isJvm8Target =
if (targets.isEmpty()) false
else if (targets.contains(JvmTarget.JVM_1_8.description) && targets.size == 1) true
else continue //TODO: support other targets on Android
// TODO: support SKIP_JDK6 on new platforms
if (fullFileText.contains("// SKIP_JDK6")) continue
if (hasBoxMethod(fullFileText)) {
val testConfiguration = createTestConfiguration(file, backend)
val services = testConfiguration.testServices
val moduleStructure = try {
testConfiguration.moduleStructureExtractor.splitTestDataByModules(
file.path,
testConfiguration.directives,
).also {
services.register(TestModuleStructure::class, it)
}
} catch (e: ExceptionFromModuleStructureTransformer) {
continue
}
val module = moduleStructure.modules.singleOrNull() ?: continue
if (module.files.any { it.isJavaFile || it.isKtsFile }) continue
if (module.files.isEmpty()) continue
services.registerDependencyProvider(DependencyProviderImpl(services, moduleStructure.modules))
val testFiles = createTestFiles(file, fullFileText)
val kind = KotlinBaseTest.extractConfigurationKind(testFiles)
val jdkKind = KotlinBaseTest.getTestJdkKind(testFiles)
val keyConfiguration = CompilerConfiguration()
val configuratorForFlags = JvmEnvironmentConfigurator(services)
with(configuratorForFlags) {
val extractor = DirectiveToConfigurationKeyExtractor()
extractor.provideConfigurationKeys()
extractor.configure(keyConfiguration, module.directives)
}
val kind = configuratorForFlags.extractConfigurationKind(module.directives)
val jdkKind = configuratorForFlags.extractJdkKind(module.directives)
keyConfiguration.languageVersionSettings = module.languageVersionSettings
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
val compiler = if (kind.withReflection) reflectionFlavor else commmonFlavor
val compilerConfigurationProvider = services.compilerConfigurationProvider as CompilerConfigurationProviderImpl
val compiler = if (isJvm8Target) {
if (kind.withReflection) JVM8REFLECT else JVM8
} else if (kind.withReflection) REFLECT else COMMON
val filesHolder = holders.getOrPut(key) {
FilesWriter(compiler, compilerConfigurationProvider.createCompilerConfiguration(module)).also {
FilesWriter(compiler, KotlinTestUtils.newConfiguration(kind, jdkKind, KotlinTestUtils.getAnnotationsJar()).apply {
println("Creating new configuration by $key")
}
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, this)
})
}
patchFilesAndAddTest(file, module, services, filesHolder)
patchFilesAndAddTest(file, testFiles, filesHolder)
}
}
}
}
private fun createTestConfiguration(testDataFile: File, backend: TargetBackend): TestConfiguration {
return TestConfigurationBuilder().apply {
configure(backend)
testInfo = KotlinTestInfo(
"org.jetbrains.kotlin.android.tests.AndroidRunner",
"test${testDataFile.nameWithoutExtension.capitalize()}",
emptySet()
)
}.build(testDataFile.path)
}
private fun TestConfigurationBuilder.configure(backend: TargetBackend) {
globalDefaults {
frontend = FrontendKinds.ClassicFrontend
targetBackend = backend
targetPlatform = JvmPlatforms.defaultJvmPlatform
dependencyKind = DependencyKind.Binary
}
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator
)
useAdditionalSourceProviders(
::AdditionalDiagnosticsSourceFilesProvider,
::CoroutineHelpersSourceFilesProvider,
::CodegenHelpersSourceFilesProvider,
)
assertions = JUnit5Assertions
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
useSourcePreprocessor(*AbstractKotlinCompilerTest.defaultPreprocessors.toTypedArray())
useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray())
}
private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> =
CodegenTestCase.createTestFilesFromFile(file, expectedText, "kotlin.coroutines", false, TargetBackend.JVM)
companion object {
const val GRADLE_VERSION = "6.8.1" // update GRADLE_SHA_256 on change
const val GRADLE_SHA_256 = "fd591a34af7385730970399f473afabdb8b28d57fd97d6625c388d090039d6fd"
const val GRADLE_VERSION = "5.6.4" // update GRADLE_SHA_256 on change
const val GRADLE_SHA_256 = "1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d"
const val testClassPackage = "org.jetbrains.kotlin.android.tests"
const val testClassName = "CodegenTestCaseOnAndroid"
const val baseTestClassPackage = "org.jetbrains.kotlin.android.tests"
@@ -434,21 +339,20 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
@Throws(IOException::class)
internal fun writeAndroidSkdToLocalProperties(pathManager: PathManager) {
val sdkRoot = KtTestUtil.getAndroidSdkSystemIndependentPath()
val sdkRoot = KotlinTestUtils.getAndroidSdkSystemIndependentPath()
println("Writing android sdk to local.properties: $sdkRoot")
val file = File(pathManager.tmpFolder + "/local.properties")
FileWriter(file).use { fw -> fw.write("sdk.dir=$sdkRoot") }
}
@OptIn(ExperimentalPathApi::class)
@JvmStatic
fun main(args: Array<String>) {
val tmpFolder = createTempDirectory().toAbsolutePath().toString()
println("Created temporary folder for android tests: $tmpFolder")
val rootFolder = Path("").toAbsolutePath().toString()
val pathManager = PathManager(rootFolder, tmpFolder)
val tmpFolder = createTempDir()
println("Created temporary folder for android tests: " + tmpFolder.absolutePath)
val rootFolder = File("")
val pathManager = PathManager(rootFolder.absolutePath, tmpFolder.absolutePath)
generate(pathManager, true)
println("Android test project is generated into $tmpFolder folder")
println("Android test project is generated into " + tmpFolder.absolutePath + " folder")
}
}
}

View File

@@ -55,6 +55,16 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
runTestsOnEmulator(gradleRunner, TestSuite("D8")).apply {
rootSuite.addTest(this)
}
renameFlavorFolder()
enableD8(false)
runTestsOnEmulator(gradleRunner, TestSuite("DX")).apply {
(0 until this.countTestCases()).forEach {
val testCase = testAt(it) as TestCase
testCase.name += "_DX"
}
rootSuite.addTest(this)
}
} catch (e: RuntimeException) {
e.printStackTrace()
throw e
@@ -71,20 +81,25 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
return rootSuite
}
private fun processReport(rootSuite: TestSuite, resultOutput: String) {
private fun enableD8(enable: Boolean) {
val file = File(pathManager.androidTmpFolder, "gradle.properties")
val lines = file.readLines().map {
if (it.startsWith("android.enableD8=")) {
"android.enableD8=$enable"
} else it
}
file.writeText(lines.joinToString("\n"))
}
private fun processReport(suite: TestSuite, resultOutput: String) {
val reportFolder = File(flavorFolder())
try {
val folders = reportFolder.listFiles()
assertTrue(folders != null && folders.isNotEmpty(), "No folders in ${reportFolder.path}")
folders.forEach {
assertTrue("${it.path} is not directory") { it.isDirectory }
val isIr = it.name.contains("_ir")
val testCases = parseSingleReportInFolder(it)
testCases.forEach { aCase ->
if (isIr) aCase.name += "_ir"
rootSuite.addTest(aCase)
}
testCases.forEach { aCase -> suite.addTest(aCase) }
Assert.assertNotEquals("There is no test results in report", 0, testCases.size.toLong())
}
} catch (e: Throwable) {
@@ -92,6 +107,10 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
}
}
private fun renameFlavorFolder() {
val reportFolder = File(flavorFolder())
reportFolder.renameTo(File(reportFolder.parentFile, reportFolder.name + "_d8"))
}
private fun flavorFolder() = pathManager.tmpFolder + "/build/test/results/connected/flavors"
@@ -120,7 +139,7 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
private fun cleanAndBuildProject(gradleRunner: GradleRunner) {
gradleRunner.clean()
gradleRunner.assembleAndroidTest()
gradleRunner.build()
}
@Throws(IOException::class, SAXException::class, ParserConfigurationException::class)
@@ -139,14 +158,22 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
return (0 until testCases.length).map { i ->
val item = testCases.item(i) as Element
val failure = item.getElementsByTagName("failure").takeIf { it.length != 0 }?.item(0)
val failure = item.getElementsByTagName("failure")
val name = item.getAttribute("name")
val clazz = item.getAttribute("classname")
object : TestCase(name) {
@Throws(Throwable::class)
override fun runTest() {
if (failure != null) {
Assert.fail(failure.textContent)
if (failure.length == 0) {
object : TestCase(name) {
@Throws(Throwable::class)
override fun runTest() {
}
}
} else {
object : TestCase(name) {
@Throws(Throwable::class)
override fun runTest() {
Assert.fail(failure.item(0).textContent)
}
}
}

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.android.tests;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import java.io.File;
@@ -69,7 +69,7 @@ public class PathManager {
}
public String getAndroidSdkRoot() {
return KtTestUtil.getAndroidSdkSystemIndependentPath();
return KotlinTestUtils.getAndroidSdkSystemIndependentPath();
}
public String getAndroidModuleRoot() {

View File

@@ -121,11 +121,8 @@ public class Emulator {
public void startEmulator() {
startServer();
System.out.println("Starting emulator with ANDROID_HOME/ANDROID_SDK_ROOT: " + pathManager.getAndroidSdkRoot());
GeneralCommandLine startCommand = getStartCommand();
startCommand.withEnvironment("ANDROID_SDK_ROOT", pathManager.getAndroidSdkRoot());
startCommand.withEnvironment("ANDROID_HOME", pathManager.getAndroidSdkRoot());
RunUtils.executeOnSeparateThread(new RunUtils.RunSettings(startCommand, null, false, "START: ", true));
System.out.println("Starting emulator...");
RunUtils.executeOnSeparateThread(new RunUtils.RunSettings(getStartCommand(), null, false, "START: ", true));
printLog();
}
@@ -147,7 +144,6 @@ public class Emulator {
bootCheckCommand.addParameter("shell");
bootCheckCommand.addParameter("getprop");
bootCheckCommand.addParameter("sys.boot_completed");
int counter = 0;
RunResult execute = RunUtils.execute(bootCheckCommand);
while (counter < 20) {

View File

@@ -45,9 +45,9 @@ public class GradleRunner {
OutputUtils.checkResult(result);
}
public void assembleAndroidTest() {
public void build() {
System.out.println("Building gradle project...");
GeneralCommandLine build = generateCommandLine("assembleAndroidTest");
GeneralCommandLine build = generateCommandLine("build");
build.addParameter("--stacktrace");
build.addParameter("--warn");
RunResult result = RunUtils.execute(build);

View File

@@ -1,8 +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.backend.common
class BackendException(message: String, cause: Throwable?) : IllegalStateException(message, cause)

View File

@@ -232,13 +232,12 @@ object CodegenUtil {
}
@JvmStatic
fun reportBackendException(exception: Throwable, phase: String, location: String?, additionalMessage: String? = null): Nothing {
fun reportBackendException(exception: Throwable, phase: String, fileUrl: String?): Nothing {
// CompilationException (the only KotlinExceptionWithAttachments possible here) is already supposed
// to have all information about the context.
if (exception is KotlinExceptionWithAttachments) throw exception
throw BackendException(
getExceptionMessage("Backend", "Exception during $phase", exception, location) +
additionalMessage?.let { "\n" + it }.orEmpty(),
throw IllegalStateException(
getExceptionMessage("Backend", "Exception during $phase", exception, fileUrl),
exception
)
}

View File

@@ -1,13 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.org.objectweb.asm.Opcodes
// This object should help compiling against different ASM versions in different bunch versions
object VersionIndependentOpcodes {
const val ACC_RECORD = Opcodes.ACC_RECORD
}

View File

@@ -1,13 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.org.objectweb.asm.Opcodes
// This object should help compiling against different ASM versions from different bunch versions
object VersionIndependentOpcodes {
const val ACC_RECORD = 0
}

View File

@@ -14,6 +14,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class AsmTypes {
private static final Map<Class<?>, Type> TYPES_MAP = new HashMap<>();

View File

@@ -26,13 +26,13 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.*;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
public abstract class AbstractClassBuilder implements ClassBuilder {
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
public static final RecordComponentVisitor EMPTY_RECORD_VISITOR = new RecordComponentVisitor(Opcodes.API_VERSION) {};
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
private String thisName;
@@ -91,16 +91,6 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
return visitor;
}
@NotNull
@Override
public RecordComponentVisitor newRecordComponent(@NotNull String name, @NotNull String desc, @Nullable String signature) {
RecordComponentVisitor visitor = getVisitor().visitRecordComponent(name, desc, signature);
if (visitor == null) {
return EMPTY_RECORD_VISITOR;
}
return visitor;
}
@Override
@NotNull
public JvmSerializationBindings getSerializationBindings() {

View File

@@ -1,158 +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.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.inline.FileMapping;
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.*;
import java.util.List;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
public abstract class AbstractClassBuilder implements ClassBuilder {
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
private String thisName;
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
private String sourceName;
private String debugInfo;
public static class Concrete extends AbstractClassBuilder {
private final ClassVisitor v;
public Concrete(@NotNull ClassVisitor v) {
this.v = v;
}
@Override
@NotNull
public ClassVisitor getVisitor() {
return v;
}
}
@Override
@NotNull
public FieldVisitor newField(
@NotNull JvmDeclarationOrigin origin,
int access,
@NotNull String name,
@NotNull String desc,
@Nullable String signature,
@Nullable Object value
) {
FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
if (visitor == null) {
return EMPTY_FIELD_VISITOR;
}
return visitor;
}
@Override
@NotNull
public MethodVisitor newMethod(
@NotNull JvmDeclarationOrigin origin,
int access,
@NotNull String name,
@NotNull String desc,
@Nullable String signature,
@Nullable String[] exceptions
) {
MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
if (visitor == null) {
return EMPTY_METHOD_VISITOR;
}
return visitor;
}
@Override
@NotNull
public JvmSerializationBindings getSerializationBindings() {
return serializationBindings;
}
@Override
@NotNull
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
return getVisitor().visitAnnotation(desc, visible);
}
@Override
public void done() {
getVisitor().visitSource(sourceName, debugInfo);
getVisitor().visitEnd();
}
@Override
public void defineClass(
@Nullable PsiElement origin,
int version,
int access,
@NotNull String name,
@Nullable String signature,
@NotNull String superName,
@NotNull String[] interfaces
) {
thisName = name;
getVisitor().visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitSource(@NotNull String name, @Nullable String debug) {
assert sourceName == null || sourceName.equals(name) : "inconsistent file name: " + sourceName + " vs " + name;
sourceName = name;
debugInfo = debug;
}
@Override
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
if (!GENERATE_SMAP) return;
List<FileMapping> fileMappings = smap.getResultMappings();
if (fileMappings.isEmpty()) return;
visitSource(fileMappings.get(0).getName(), SMAPBuilder.INSTANCE.build(fileMappings, backwardsCompatibleSyntax));
}
@Override
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
getVisitor().visitOuterClass(owner, name, desc);
}
@Override
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
getVisitor().visitInnerClass(name, outerName, innerName, access);
}
@Override
@NotNull
public String getThisName() {
assert thisName != null : "This name isn't set";
return thisName;
}
}

View File

@@ -50,7 +50,7 @@ class AccessorForFunctionDescriptor(
if (calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) != null) {
userDataMap = LinkedHashMap<CallableDescriptor.UserDataKey<*>, Any>()
userDataMap[INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION] =
calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)
calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)
}
}

View File

@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -498,9 +497,6 @@ public abstract class AnnotationCodegen {
public Void visitKClassValue(KClassValue value, Void data) {
KotlinType classType = value.getArgumentType(module);
innerClassConsumer.addInnerClassInfoFromAnnotation(DescriptorUtils.getClassDescriptorForType(classType));
if (InlineClassesUtilsKt.isInlineClassType(classType)) {
classType = TypeUtils.makeNullable(classType);
}
annotationVisitor.visit(name, typeMapper.mapType(classType));
return null;
}

View File

@@ -20,9 +20,11 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.mapToIndex
class ArgumentAndDeclIndex(val arg: ResolvedValueArgument, val declIndex: Int)
@@ -68,8 +70,12 @@ abstract class ArgumentGenerator {
generateExpression(declIndex, argument)
}
is DefaultValueArgument -> {
defaultArgs.mark(declIndex)
generateDefault(declIndex, argument)
if (calleeDescriptor?.defaultValueFromJava(declIndex) == true) {
generateDefaultJava(declIndex, argument)
} else {
defaultArgs.mark(declIndex)
generateDefault(declIndex, argument)
}
}
is VarargValueArgument -> {
generateVararg(declIndex, argument)
@@ -97,6 +103,10 @@ abstract class ArgumentGenerator {
throw UnsupportedOperationException("Unsupported vararg value argument #$i: $argument")
}
protected open fun generateDefaultJava(i: Int, argument: DefaultValueArgument) {
throw UnsupportedOperationException("Unsupported default java argument #$i: $argument")
}
protected open fun generateOther(i: Int, argument: ResolvedValueArgument) {
throw UnsupportedOperationException("Unsupported value argument #$i: $argument")
}
@@ -106,6 +116,28 @@ abstract class ArgumentGenerator {
}
}
private fun CallableDescriptor.defaultValueFromJava(index: Int): Boolean = DFS.ifAny(
listOf(this),
{ current -> current.original.overriddenDescriptors.map { it.original } },
{ descriptor ->
descriptor.original.overriddenDescriptors.isEmpty() &&
descriptor is JavaCallableMemberDescriptor &&
descriptor.valueParameters[index].declaresDefaultValue()
}
)
fun shouldInvokeDefaultArgumentsStub(resolvedCall: ResolvedCall<*>): Boolean {
val descriptor = resolvedCall.resultingDescriptor
val valueArgumentsByIndex = resolvedCall.valueArgumentsByIndex ?: return false
for (index in valueArgumentsByIndex.indices) {
val resolvedValueArgument = valueArgumentsByIndex[index]
if (resolvedValueArgument is DefaultValueArgument && !descriptor.defaultValueFromJava(index)) {
return true
}
}
return false
}
fun getFunctionWithDefaultArguments(functionDescriptor: FunctionDescriptor): FunctionDescriptor {
if (functionDescriptor.containingDeclaration !is ClassDescriptor) return functionDescriptor
if (functionDescriptor.overriddenDescriptors.isEmpty()) return functionDescriptor
@@ -123,4 +155,4 @@ fun getFunctionWithDefaultArguments(functionDescriptor: FunctionDescriptor): Fun
function.valueParameters.any { valueParameter -> valueParameter.hasDefaultValue() }
}
?: functionDescriptor
}
}

View File

@@ -72,6 +72,12 @@ class CallBasedArgumentGenerator(
callGenerator.putValueIfNeeded(getJvmKotlinType(i), lazyVararg, ValueKind.GENERAL_VARARG, i)
}
override fun generateDefaultJava(i: Int, argument: DefaultValueArgument) {
val argumentValue = valueParameters[i].findJavaDefaultArgumentValue(valueParameterTypes[i], codegen.typeMapper)
callGenerator.putValueIfNeeded(getJvmKotlinType(i), argumentValue)
}
override fun reorderArgumentsIfNeeded(args: List<ArgumentAndDeclIndex>) {
callGenerator.reorderArgumentsIfNeeded(args, valueParameterTypes)
}

View File

@@ -29,8 +29,7 @@ class CallableMethod(
override val generateCalleeType: Type?,
override val returnKotlinType: KotlinType?,
val isInterfaceMethod: Boolean,
private val isDefaultMethodInInterface: Boolean,
private val boxInlineClassBeforeInvoke: Boolean
private val isDefaultMethodInInterface: Boolean
) : Callable {
private val defaultImplMethod: Method by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethod)
@@ -50,9 +49,6 @@ class CallableMethod(
get() = getAsmMethod().argumentTypes
override fun genInvokeInstruction(v: InstructionAdapter) {
if (boxInlineClassBeforeInvoke) {
StackValue.boxInlineClass(dispatchReceiverKotlinType!!, v)
}
v.visitMethodInsn(
invokeOpcode,
owner.internalName,

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