Compare commits

..

18 Commits

Author SHA1 Message Date
Vyacheslav Gerasimov
2c211f74fe Build: Use sourceMapBaseDirs in :kotlin-stdlib-js:compileKotlin2Js
instead of freeCompiler args to avoid snapshotting absolute paths
and fix caching
2020-02-28 18:02:51 +03:00
Vyacheslav Gerasimov
0480ab4e4f Advance bootstrap to 1.4.0-dev-1818 2020-02-28 18:02:51 +03:00
Vyacheslav Gerasimov
7810634b6a Build: Use configurations property for shadowJar in :kotlin-main-kts
It marked as classpath and improves cache reuse between different builds
2020-02-28 18:02:51 +03:00
Vyacheslav Gerasimov
bc31f6d415 Build: Make toolsJarApi() helper for JPS build 2020-02-28 16:54:15 +03:00
Vyacheslav Gerasimov
1432dcf32f Build: Remove all code from tools-jar-api leaving only declarations
Since method bodies are not required for compilation
strip them out to remove noise between different versions.
2020-02-28 16:54:15 +03:00
Vyacheslav Gerasimov
713da2fd08 Build: Use preprocessed tools.jar for compilation
tools.jar from JDK has different public api on different platforms which
makes impossible to reuse caches for tasks which depend on it. Since we
can't compile against those classes & stay cross-platform anyway, we
may just exclude them from compile classpath. This should make tools.jar
compatible at least within one build of JDK for different platforms
2020-02-28 16:54:15 +03:00
Vyacheslav Gerasimov
5325d9d74a Build: Make all compile dependencies on toolsJar compileOnly
tools.jar differs between different versions of JDK reducing cache reuse
so better to not leak it to other modules
2020-02-28 16:54:15 +03:00
Vyacheslav Gerasimov
7f2fd8907a Build: Make DexMethodCount task cacheable, extract TC stats to task 2020-02-28 16:54:15 +03:00
Vyacheslav Gerasimov
de0617daee Build: Don't disable incremental compilation for CI
Using different incremental setting for KotlinCompile makes impossible
using caches built on CI since it is marked as @Input. Same property for
JavaCompile marked as @Internal.
We do clean checkout now so it shouldn't matter but we want to build
incrementally in some cases for Dev builds on CI.
2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
e123961151 Build: normalize inputs of :kotlin-reflect:stripMetadata as classpath 2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
1c068f4e1c Build: Make :kotlin-reflect:relocateCoreSources task cacheable 2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
78fb1c9d31 Build: Use same com.eclipsesource.j2v8 artifact for compilation
We can't reuse caches from different platform when we compile against
different jar on each platform. Since they have same api we may use
platform specific jars only for runtime.
2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
1262938c89 Build: Remove duplicated manifestAttributes call from reflectShadowJar
manifestAttributes call done in the result jar
2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
ddcc629ba2 Build: Disable caching for Test tasks until we are sure it is safe
#KT-37089
2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
d974e795bf Build: Add buildserver.labs.intellij.net to valid hosts in caching check 2020-02-28 16:54:14 +03:00
Vyacheslav Gerasimov
c0f9ca7d20 Build: Use Jar task for :kotlin-compiler:packCompiler
Right now can't be cached between builds because of compiler version.
We may move module containing compiler version directly to the final jar
2020-02-28 16:54:13 +03:00
Vyacheslav Gerasimov
7fb6605dce Build: Use Jar task instead ShadowJar task in :kotlin-daemon-client-new 2020-02-28 16:54:13 +03:00
Vyacheslav Gerasimov
7eaba6309c Build: Use Jar task instead ShadowJar task in :kotlin-daemon 2020-02-28 16:54:13 +03:00
23564 changed files with 238476 additions and 663748 deletions

13
.bunch
View File

@@ -1,8 +1,7 @@
201
202
203_202
193
192_193
as36_192_193
as40_193
as41
201
192
191_192
as35_191_192
as36_192
as40

4
.gitattributes vendored
View File

@@ -1,8 +1,4 @@
**/testData/** linguist-vendored
*Generated.java linguist-generated=true
* text=auto
* eol=lf
*.png binary
*.jar binary
compiler/cli/bin/* eol=lf
compiler/cli/bin/*.bat eol=crlf

4
.gitignore vendored
View File

@@ -50,12 +50,10 @@ build/
.idea/artifacts/kotlin_main_kts_jar.xml
.idea/artifacts/kotlin_compiler_client_embeddable_jar.xml
.idea/artifacts/kotlin_reflect_jar.xml
.idea/artifacts/kotlin_stdlib_js_ir_*
.idea/artifacts/kotlin_test_js_ir_*
.idea/artifacts/kotlin_stdlib_wasm_*
.idea/jarRepositories.xml
kotlin-ultimate/
node_modules/
.rpt2_cache/
libraries/tools/kotlin-test-js-runner/lib/
libraries/tools/kotlin-source-map-loader/lib/
local.properties

View File

@@ -1,8 +0,0 @@
<component name="ArtifactManager">
<artifact build-on-make="true" name="dist_root">
<output-path>$PROJECT_DIR$/dist</output-path>
<root id="root">
<element id="artifact" artifact-name="dist" />
</root>
</artifact>
</component>

View File

@@ -2,8 +2,6 @@
<dictionary name="4u7">
<words>
<w>bintray</w>
<w>cacheability</w>
<w>cacheable</w>
<w>cidr</w>
<w>foldable</w>
<w>instrumentator</w>
@@ -11,7 +9,6 @@
<w>protobuf</w>
<w>redirector</w>
<w>remapper</w>
<w>sonatype</w>
<w>unpresent</w>
</words>
</dictionary>

View File

@@ -1,19 +1,12 @@
<component name="ProjectDictionaryState">
<dictionary name="dmitriy.dolovov">
<words>
<w>cinterop</w>
<w>commonizable</w>
<w>commonization</w>
<w>commonize</w>
<w>commonized</w>
<w>commonizer</w>
<w>commonizers</w>
<w>commonizes</w>
<w>commonizing</w>
<w>jetbrains</w>
<w>konan</w>
<w>kotlinx</w>
<w>macos</w>
</words>
</dictionary>
</component>

BIN
.idea/icon.png generated

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

12
.idea/misc.xml generated
View File

@@ -24,7 +24,7 @@
<option name="myDefaultNotNull" value="org.jetbrains.annotations.NotNull" />
<option name="myNullables">
<value>
<list size="14">
<list size="11">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
@@ -36,15 +36,12 @@
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="9" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="14">
<list size="11">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="javax.validation.constraints.NotNull" />
@@ -56,9 +53,6 @@
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="9" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
</list>
</value>
</option>
@@ -66,7 +60,7 @@
<component name="ProjectResources">
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="PsiViewerSettings">

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: KMM" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="kmmTest" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method v="2" />
</configuration>
</component>

View File

@@ -1,22 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: stdlib-js public kotlin api test, overwrite results" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--tests &quot;org.jetbrains.kotlin.js.test.ApiTest&quot; -Poverwrite.output=true --parallel" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":js:js.tests:cleanTest" />
<option value=":js:js.tests:test" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>false</GradleScriptDebugEnabled>
<method v="2" />
</configuration>
</component>

View File

@@ -1,3 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Apply copyright" pattern="!file[*]:*//testData//*&amp;&amp;!file[*]:testData//*&amp;&amp;!file[*]:*.gradle.kts&amp;&amp;!file[*]:*.gradle&amp;&amp;!file[group:kotlin-ultimate]:*/&amp;&amp;!file[kotlin.libraries]:stdlib/api//*" />
<scope name="Apply copyright" pattern="!file[*]:*//testData//*&amp;&amp;!file[*]:testData//*&amp;&amp;!file[*]:*.gradle.kts&amp;&amp;!file[*]:*.gradle" />
</component>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
[![official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![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)
[![TeamCity (simple build status)](https://img.shields.io/teamcity/http/teamcity.jetbrains.com/s/Kotlin_dev_Compiler.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=Kotlin_dev_Compiler&branch_Kotlin_dev=%3Cdefault%3E&tab=buildTypeStatusDiv)
[![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)
@@ -37,16 +37,11 @@ In order to build Kotlin distribution you need to have:
JDK_18="path to JDK 1.8"
JDK_9="path to JDK 9"
For local development, if you're not working on bytecode generation or the standard library, it's OK to have only JDK 1.8 and JDK 9 installed, and to point `JDK_16` and `JDK_17` environment variables to your JDK 1.8 installation.
For local development, if you're not working on bytecode generation or the standard library, it's OK to have only JDK 1.8 and JDK 9 installed, and to point JDK_16 and JDK_17 environment variables to your JDK 1.8 installation.
You also can use [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties) to setup `JDK_*` variables.
You also can use [Gradle properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties) to setup JDK_* variables.
Note: The JDK 6 for MacOS is not available on Oracle's site. You can install it by
```bash
$ brew tap caskroom/versions
$ brew cask install java6
```
> Note: The JDK 6 for MacOS is not available on Oracle's site. You can [download it here](https://support.apple.com/kb/DL1572).
On Windows you might need to add long paths setting to the repo:
@@ -78,7 +73,7 @@ command line parameters on the first run:
- `clean` - clean build results
- `dist` - assembles the compiler distribution into `dist/kotlinc/` folder
- `ideaPlugin` - assembles the Kotlin IDEA plugin distribution into `dist/artifacts/ideaPlugin/Kotlin/` folder
- `ideaPlugin` - assembles the Kotlin IDEA plugin distribution into `dist/artifacts/Kotlin` folder
- `install` - build and install all public artifacts into local maven repository
- `runIde` - build IDEA plugin and run IDEA with it
- `coreLibsTest` - build and run stdlib, reflect and kotlin-test tests
@@ -86,8 +81,6 @@ command line parameters on the first run:
- `compilerTest` - build and run all compiler tests
- `ideaPluginTest` - build and run all IDEA plugin tests
To reproduce TeamCity build use `-Pteamcity=true` flag. Local builds don't run proguard and have jar compression disabled by default.
**OPTIONAL:** Some artifacts, mainly Maven plugin ones, are built separately with Maven.
Refer to [libraries/ReadMe.md](libraries/ReadMe.md) for details.
@@ -113,39 +106,28 @@ bunch switch 191
Working with the Kotlin project requires at least IntelliJ IDEA 2019.1. You can download IntelliJ IDEA 2019.1 [here](https://www.jetbrains.com/idea/download).
After cloning the project, to import the project in IntelliJ choose the project directory in the Open project dialog. Then, after project opened, select
`File` -> `New` -> `Module from Existing Sources...` in the menu, and select `build.gradle.kts` file in the project's root folder.
After cloning the project, to import the project in Intellij choose the project directory in the Open project dialog. Then, after project opened, Select
`File` -> `New...` -> `Module from Existing Sources` in the menu, and select `build.gradle.kts` file in the project's root folder.
In the import dialog, select `use default gradle wrapper`.
To be able to run tests from IntelliJ easily, check `Delegate IDE build/run actions to Gradle` and choose `Gradle Test Runner` in the Gradle runner settings after importing the project.
At this time, you can use the latest released `1.3.x` version of the Kotlin plugin for working with the code. To make sure you have the latest version installed, use `Tools` -> `Kotlin` -> `Configure Kotlin Plugin Updates`.
At this time, you can use the latest released 1.3.x version of the Kotlin plugin for working with the code. To make sure you have the latest version installed, use Tools | Kotlin | Configure Kotlin Plugin Updates and press "Check for updates now".
### Compiling and running
From this root project there are Run/Debug Configurations for running `IDEA` or the `Generate Compiler Tests` for example; so if you want to try out the latest and greatest IDEA plugin
From this root project there are Run/Debug Configurations for running IDEA or the Compiler Tests for example; so if you want to try out the latest and greatest IDEA plugin
* `VCS` -> `Git` -> `Pull`
* Run the `IDEA` run configuration in the project
* A child IntelliJ IDEA with the Kotlin plugin will then startup
* VCS -> Git -> Pull
* Run the "IDEA" run configuration in the project
* a child IntelliJ IDEA with the Kotlin plugin will then startup
### Including into composite build
To include kotlin compiler into [composite build](https://docs.gradle.org/current/userguide/composite_builds.html) you need to define `dependencySubstitution` for `kotlin-compiler` module in `settings.gradle.kts`
To include kotlin compiler into [composite build](https://docs.gradle.org/current/userguide/composite_builds.html) you need to define `dependencySubstitution` for `kotlin-compiler` module in `settings.gradle`
```Kotlin
includeBuild("/path/to/kotlin") {
dependencySubstitution {
substitute(module("org.jetbrains.kotlin:kotlin-compiler"))
.with(project(":include:kotlin-compiler"))
}
}
```
or in `settings.gradle`
```Groovy
includeBuild('/path/to/kotlin') {
dependencySubstitution {
substitute module('org.jetbrains.kotlin:kotlin-compiler') with project(':include:kotlin-compiler')

View File

@@ -40,7 +40,6 @@ repositories {
dependencies {
compile(kotlinStdlib())
compile(project(":compiler:frontend"))
compile(projectTests(":compiler:tests-common"))
compile(project(":compiler:cli"))
compile(intellijCoreDep()) { includeJars("intellij-core") }
compile(jpsStandalone()) { includeJars("jps-model") }
@@ -76,72 +75,8 @@ benchmark {
include("CommonCallsBenchmark")
//include("InferenceBaselineCallsBenchmark")
}
register("ni") {
warmups = 10
iterations = 10
iterationTime = 1
iterationTimeUnit = "sec"
param("useNI", true)
param("isIR", false)
param("size", 1000)
include("InferenceBaselineCallsBenchmark")
include("InferenceExplicitArgumentsCallsBenchmark")
include("InferenceForInApplicableCandidate")
include("InferenceFromArgumentCallsBenchmark")
include("InferenceFromReturnTypeCallsBenchmark")
}
}
targets {
register("main")
}
}
tasks.named("classes") {
doLast {
tasks.named("mainBenchmarkJar", Zip::class.java) {
isZip64 = true
archiveName = "benchmarks.jar"
}
listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark").forEach {
tasks.named(it, JavaExec::class.java) {
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
}
}
}
}
/*tasks.register<JavaExec>("runBenchmark") {
val jmhArgs: String by project // example: -PjmhArgs='CommonCalls -p size=500 -p isIR=true -p useNI=true -f 1'
val resultFilePath = "$buildDir/benchmarks/jmh-result.json"
val ideaHome = intellijRootDir().canonicalPath
val benchmarkJarPath = "$buildDir/benchmarks/main/jars/benchmarks.jar"
args = mutableListOf("-Didea.home.path=$ideaHome", benchmarkJarPath, "-rf", "json", "-rff", resultFilePath) + jmhArgs.split("\\s".toRegex())
main = "-jar"
doLast {
if (project.kotlinBuildProperties.isTeamcityBuild) {
val jsonArray = com.google.gson.JsonParser.parseString(File(resultFilePath).readText()).asJsonArray
jsonArray.forEach {
val benchmark = it.asJsonObject
// remove unnecessary name parts from string like this "org.jetbrains.kotlin.benchmarks.CommonCallsBenchmark.benchmark"
val name = benchmark["benchmark"].asString.removeSuffix(".benchmark").let {
val indexOfLastDot = it.indexOfLast { it == '.' }
it.removeRange(0..indexOfLastDot)
}
val params = benchmark["params"].asJsonObject
val isIR = if (params.has("isIR")) params["isIR"].asString else "false"
val useNI = if (params.has("useNI")) params["useNI"].asString else "false"
val size = params["size"].asString
val score = "%.3f".format(benchmark["primaryMetric"].asJsonObject["score"].asString.toFloat())
val irPostfix = if (isIR.toBoolean()) " isIR=true" else ""
val niPostfix = if (useNI.toBoolean() && !isIR.toBoolean()) " isNI=true" else ""
println("""##teamcity[buildStatisticValue key='$name size=$size${irPostfix}$niPostfix' value='$score']""")
}
}
}
}*/

View File

@@ -13,6 +13,7 @@ import com.intellij.psi.PsiFileFactory
import com.intellij.psi.impl.PsiFileFactoryImpl
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
@@ -25,15 +26,21 @@ import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
import org.jetbrains.kotlin.fir.java.FirLibrarySession
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.storage.ExceptionTracker
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
@@ -59,25 +66,25 @@ private val JDK_PATH = File("${System.getProperty("java.home")!!}/lib/rt.jar")
private val RUNTIME_JAR = File(System.getProperty("kotlin.runtime.path") ?: "dist/kotlinc/lib/kotlin-runtime.jar")
private val LANGUAGE_FEATURE_SETTINGS =
LanguageVersionSettingsImpl(
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
specificFeatures = mapOf(LanguageFeature.NewInference to LanguageFeature.State.ENABLED)
)
LanguageVersionSettingsImpl(
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
specificFeatures = mapOf(LanguageFeature.NewInference to LanguageFeature.State.ENABLED)
)
private fun newConfiguration(useNewInference: Boolean): CompilerConfiguration {
val configuration = CompilerConfiguration()
configuration.put(CommonConfigurationKeys.MODULE_NAME, "benchmark")
configuration.put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, "../compiler/cli/cli-common/resources")
configuration.put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, "../idea/resources")
configuration.addJvmClasspathRoot(JDK_PATH)
configuration.addJvmClasspathRoot(RUNTIME_JAR)
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
val newInferenceState = if (useNewInference) LanguageFeature.State.ENABLED else LanguageFeature.State.DISABLED
configuration.languageVersionSettings = LanguageVersionSettingsImpl(
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
specificFeatures = mapOf(
LanguageFeature.NewInference to newInferenceState
)
LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3,
specificFeatures = mapOf(
LanguageFeature.NewInference to newInferenceState
)
)
return configuration
}
@@ -98,21 +105,21 @@ abstract class AbstractSimpleFileBenchmark {
fun setUp() {
if (isIR && !useNewInference) error("Invalid configuration")
env = KotlinCoreEnvironment.createForTests(
myDisposable,
newConfiguration(useNewInference),
EnvironmentConfigFiles.JVM_CONFIG_FILES
myDisposable,
newConfiguration(useNewInference),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
if (isIR) {
Extensions.getArea(env.project)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(JavaElementFinder::class.java)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(JavaElementFinder::class.java)
}
file = createFile(
"test.kt",
buildText(),
env.project
"test.kt",
buildText(),
env.project
)
}
@@ -127,22 +134,22 @@ abstract class AbstractSimpleFileBenchmark {
private fun analyzeGreenFileFrontend(bh: Blackhole) {
val tracker = ExceptionTracker()
val storageManager: StorageManager =
LockBasedStorageManager.createWithExceptionHandling("benchmarks", tracker)
LockBasedStorageManager.createWithExceptionHandling("benchmarks", tracker)
val context = SimpleGlobalContext(storageManager, tracker)
val module =
ModuleDescriptorImpl(
Name.special("<benchmark>"), storageManager,
JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
)
ModuleDescriptorImpl(
Name.special("<benchmark>"), storageManager,
JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
)
val moduleContext = context.withProject(env.project).withModule(module)
val result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
moduleContext.project,
listOf(file),
NoScopeRecordCliBindingTrace(),
env.configuration,
{ scope -> JvmPackagePartProvider(LANGUAGE_FEATURE_SETTINGS, scope) }
moduleContext.project,
listOf(file),
NoScopeRecordCliBindingTrace(),
env.configuration,
{ scope -> JvmPackagePartProvider(LANGUAGE_FEATURE_SETTINGS, scope) }
)
assert(result.bindingContext.diagnostics.none { it.severity == Severity.ERROR })
@@ -152,21 +159,56 @@ abstract class AbstractSimpleFileBenchmark {
private fun analyzeGreenFileIr(bh: Blackhole) {
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
val session = createSession(env, scope)
val firProvider = session.firProvider as FirProviderImpl
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, stubMode = false)
val totalTransformer = FirTotalResolveProcessor(session)
val totalTransformer = FirTotalResolveTransformer()
val firFile = builder.buildFirFile(file).also(firProvider::recordFile)
totalTransformer.process(listOf(firFile))
for (transformer in totalTransformer.transformers) {
transformer.transformFile(firFile, null)
}
bh.consume(firFile.hashCode())
Extensions.getArea(env.project)
.getExtensionPoint(PsiElementFinder.EP_NAME)
.unregisterExtension(FirJavaElementFinder::class.java)
}
protected abstract fun buildText(): String
}
fun createSession(
environment: KotlinCoreEnvironment,
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope)
): FirSession {
val moduleInfo = FirTestModuleInfo()
val project = environment.project
val provider = FirProjectSessionProvider(project)
return FirJavaModuleBasedSession(moduleInfo, provider, sourceScope).also {
createSessionForDependencies(provider, moduleInfo, librariesScope, environment)
}
}
private fun createSessionForDependencies(
provider: FirProjectSessionProvider,
moduleInfo: FirTestModuleInfo,
librariesScope: GlobalSearchScope,
environment: KotlinCoreEnvironment
) {
val dependenciesInfo = FirTestModuleInfo()
moduleInfo.dependencies.add(dependenciesInfo)
FirLibrarySession.create(
dependenciesInfo, provider, librariesScope, environment.project,
environment.createPackagePartProvider(librariesScope)
)
}
class FirTestModuleInfo(
override val name: Name = Name.identifier("TestModule"),
val dependencies: MutableList<ModuleInfo> = mutableListOf(),
override val platform: TargetPlatform = JvmPlatforms.unspecifiedJvmPlatform,
override val analyzerServices: PlatformDependentAnalyzerServices = JvmPlatformAnalyzerServices
) : ModuleInfo {
override fun dependencies(): List<ModuleInfo> = dependencies
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class ManyImplicitReceiversBenchmark : AbstractSimpleFileBenchmark() {
@Param("1", "10", "50")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText(): String {
return buildString {
appendLine("inline fun <T, R> with(receiver: T, block: T.() -> R): R = block()")
for (i in 1..size) {
appendLine("interface A$i {")
appendLine(" fun foo$i()")
appendLine("}")
appendLine()
}
appendLine()
append("fun test(")
append((1..size).joinToString(", ") { "a$it: A$it" })
appendLine(" {")
for (i in 1..size) {
appendLine("with(a$i) {")
}
for (i in 1..size) {
appendLine("foo$i()")
}
for (i in 1..size) {
appendLine("}")
}
appendLine("}")
}
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.benchmarks
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
open class PlusAssignOperatorDesugaringBenchmark : AbstractInferenceBenchmark() {
@Param("9", "10", "11", "12", "13", "14")
private var size: Int = 0
@Benchmark
fun benchmark(bh: Blackhole) {
analyzeGreenFile(bh)
}
override fun buildText(): String = buildString {
appendLine(
"""
class A {
operator fun <T : Number> plus(other: (Int) -> T): A = this
operator fun <T : CharSequence> plusAssign(other: (String) -> T) {}
}
""".trimIndent()
)
appendLine("fun test() {")
appendLine("var a = A()")
for (i in 1..size) {
appendLine("a += {")
}
for (i in 1..size) {
appendLine(
"""
it.inc()
1
}
""".trimIndent()
)
}
appendLine()
}
}

View File

@@ -1,3 +1,4 @@
description = "Kotlin Build Common"
plugins {
@@ -11,7 +12,7 @@ dependencies {
compileOnly(project(":compiler:cli-common"))
compileOnly(project(":compiler:frontend.java"))
compileOnly(project(":js:js.serializer"))
compileOnly(project(":js:js.config"))
compileOnly(project(":js:js.frontend"))
compileOnly(project(":kotlin-util-klib-metadata"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("asm-all", "trove4j", "util", rootProject = rootProject) }

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.compilerRunner
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
@@ -25,7 +25,7 @@ class MessageCollectorToOutputItemsCollectorAdapter(
private val delegate: MessageCollector,
private val outputCollector: OutputItemsCollector
) : MessageCollector by delegate {
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
// TODO: consider adding some other way of passing input -> output mapping from compiler, e.g. dedicated service
OutputMessageUtil.parseOutputMessage(message)?.let {
outputCollector.add(it.sourceFiles, it.outputFile)

View File

@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.*
import java.io.File
@@ -477,21 +476,8 @@ open class IncrementalJvmCache(
if (inlineFunctions.isEmpty()) return emptyMap()
val result = HashMap<String, Long>()
var dummyVersion: Int = -1
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
dummyVersion = version
}
override fun visitMethod(
access: Int,
name: String,
@@ -499,8 +485,7 @@ open class IncrementalJvmCache(
signature: String?,
exceptions: Array<out String>?
): MethodVisitor? {
val dummyClassWriter = ClassWriter(0)
dummyClassWriter.visit(dummyVersion, 0, "dummy", null, AsmTypes.OBJECT_TYPE.internalName, null)
val dummyClassWriter = ClassWriter(Opcodes.API_VERSION)
return object : MethodVisitor(Opcodes.API_VERSION, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
override fun visitEnd() {
@@ -508,7 +493,6 @@ open class IncrementalJvmCache(
if (jvmName !in inlineFunctions) return
val dummyBytes = dummyClassWriter.toByteArray()!!
val hash = dummyBytes.md5()
result[jvmName] = hash
}

View File

@@ -1,6 +1,17 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental

View File

@@ -206,11 +206,6 @@ open class ProtoCompareGenerated(
if (!checkStringEquals(old.getExtension(JvmProtoBuf.anonymousObjectOriginName), new.getExtension(JvmProtoBuf.anonymousObjectOriginName))) return false
}
if (old.hasExtension(JvmProtoBuf.jvmClassFlags) != new.hasExtension(JvmProtoBuf.jvmClassFlags)) return false
if (old.hasExtension(JvmProtoBuf.jvmClassFlags)) {
if (old.getExtension(JvmProtoBuf.jvmClassFlags) != new.getExtension(JvmProtoBuf.jvmClassFlags)) return false
}
if (old.getExtensionCount(JsProtoBuf.classAnnotation) != new.getExtensionCount(JsProtoBuf.classAnnotation)) {
return false
}
@@ -269,7 +264,6 @@ open class ProtoCompareGenerated(
JVM_EXT_CLASS_MODULE_NAME,
JVM_EXT_CLASS_LOCAL_VARIABLE_LIST,
JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME,
JVM_EXT_JVM_CLASS_FLAGS,
JS_EXT_CLASS_ANNOTATION_LIST,
JS_EXT_CLASS_CONTAINING_FILE_ID,
JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS,
@@ -338,11 +332,6 @@ open class ProtoCompareGenerated(
if (!checkStringEquals(old.getExtension(JvmProtoBuf.anonymousObjectOriginName), new.getExtension(JvmProtoBuf.anonymousObjectOriginName))) result.add(ProtoBufClassKind.JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME)
}
if (old.hasExtension(JvmProtoBuf.jvmClassFlags) != new.hasExtension(JvmProtoBuf.jvmClassFlags)) result.add(ProtoBufClassKind.JVM_EXT_JVM_CLASS_FLAGS)
if (old.hasExtension(JvmProtoBuf.jvmClassFlags)) {
if (old.getExtension(JvmProtoBuf.jvmClassFlags) != new.getExtension(JvmProtoBuf.jvmClassFlags)) result.add(ProtoBufClassKind.JVM_EXT_JVM_CLASS_FLAGS)
}
if (old.getExtensionCount(JsProtoBuf.classAnnotation) != new.getExtensionCount(JsProtoBuf.classAnnotation)) {
result.add(ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST)
}
@@ -1746,10 +1735,6 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.anonymousObjectOriginName))
}
if (hasExtension(JvmProtoBuf.jvmClassFlags)) {
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.jvmClassFlags)
}
for(i in 0..getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
hashCode = 31 * hashCode + getExtension(JsProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
}

View File

@@ -33,37 +33,36 @@ import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
import java.io.File
import java.util.*
import kotlin.collections.HashSet
import kotlin.collections.LinkedHashSet
const val DELETE_MODULE_FILE_PROPERTY = "kotlin.delete.module.file.after.build"
fun makeModuleFile(
name: String,
isTest: Boolean,
outputDir: File,
sourcesToCompile: Iterable<File>,
commonSources: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpath: Iterable<File>,
friendDirs: Iterable<File>
name: String,
isTest: Boolean,
outputDir: File,
sourcesToCompile: Iterable<File>,
commonSources: Iterable<File>,
javaSourceRoots: Iterable<JvmSourceRoot>,
classpath: Iterable<File>,
friendDirs: Iterable<File>
): File {
val builder = KotlinModuleXmlBuilder()
builder.addModule(
name,
outputDir.absolutePath,
// important to transform file to absolute paths,
// otherwise compiler will use module file's parent as base path (a temporary file; see below)
// (see org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.getAbsolutePaths)
sourcesToCompile.map { it.absoluteFile },
javaSourceRoots,
classpath,
commonSources.map { it.absoluteFile },
null,
"java-production",
isTest,
// this excludes the output directories from the class path, to be removed for true incremental compilation
setOf(outputDir),
friendDirs
name,
outputDir.absolutePath,
// important to transform file to absolute paths,
// otherwise compiler will use module file's parent as base path (a temporary file; see below)
// (see org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.getAbsolutePaths)
sourcesToCompile.map { it.absoluteFile },
javaSourceRoots,
classpath,
commonSources.map { it.absoluteFile },
null,
"java-production",
isTest,
// this excludes the output directories from the class path, to be removed for true incremental compilation
setOf(outputDir),
friendDirs
)
val scriptFile = File.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml")
@@ -84,9 +83,9 @@ private fun sanitizeJavaIdentifier(string: String) =
}
fun makeCompileServices(
incrementalCaches: Map<TargetId, IncrementalCache>,
lookupTracker: LookupTracker,
compilationCanceledStatus: CompilationCanceledStatus?
incrementalCaches: Map<TargetId, IncrementalCache>,
lookupTracker: LookupTracker,
compilationCanceledStatus: CompilationCanceledStatus?
): Services =
with(Services.Builder()) {
register(LookupTracker::class.java, lookupTracker)
@@ -106,14 +105,12 @@ fun updateIncrementalCache(
for (generatedFile in generatedFiles) {
when {
generatedFile is GeneratedJvmClass -> cache.saveFileToCache(generatedFile, changesCollector)
generatedFile.outputFile.isModuleMappingFile() -> cache.saveModuleMappingToCache(
generatedFile.sourceFiles,
generatedFile.outputFile
)
generatedFile.outputFile.isModuleMappingFile() -> cache.saveModuleMappingToCache(generatedFile.sourceFiles, generatedFile.outputFile)
}
}
javaChangesTracker?.javaClassesUpdates?.forEach { (source, serializedJavaClass) ->
javaChangesTracker?.javaClassesUpdates?.forEach {
(source, serializedJavaClass) ->
cache.saveJavaClassProto(source, serializedJavaClass, changesCollector)
}
@@ -121,9 +118,9 @@ fun updateIncrementalCache(
}
fun LookupStorage.update(
lookupTracker: LookupTracker,
filesToCompile: Iterable<File>,
removedFiles: Iterable<File>
lookupTracker: LookupTracker,
filesToCompile: Iterable<File>,
removedFiles: Iterable<File>
) {
if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
@@ -133,8 +130,8 @@ fun LookupStorage.update(
}
data class DirtyData(
val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(),
val dirtyClassesFqNames: Collection<FqName> = emptyList()
val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(),
val dirtyClassesFqNames: Collection<FqName> = emptyList()
)
fun ChangesCollector.getDirtyData(
@@ -216,21 +213,19 @@ fun mapClassesFqNamesToFiles(
}
fun withSubtypes(
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon>
): Set<FqName> {
val types = LinkedHashSet(listOf(typeFqName))
val types = LinkedList(listOf(typeFqName))
val subtypes = hashSetOf<FqName>()
while (types.isNotEmpty()) {
val iterator = types.iterator()
val unprocessedType = iterator.next()
iterator.remove()
val unprocessedType = types.pollFirst()
caches.asSequence()
.flatMap { it.getSubtypesOf(unprocessedType) }
.filter { it !in subtypes }
.forEach { types.add(it) }
.flatMap { it.getSubtypesOf(unprocessedType) }
.filter { it !in subtypes }
.forEach { types.addLast(it) }
subtypes.add(unprocessedType)
}

View File

@@ -273,10 +273,6 @@ class DifferenceCalculatorForClass(
isClassAffected = true
areSubclassesAffected = true
}
ProtoBufClassKind.JVM_EXT_JVM_CLASS_FLAGS -> {
isClassAffected = true
areSubclassesAffected = true
}
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.EnumeratorStringDescriptor
import com.intellij.util.io.KeyDescriptor
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.utils.Printer
import java.io.File
abstract class BasicMap<K : Comparable<K>, V>(
internal val storageFile: File,
keyDescriptor: KeyDescriptor<K>,
valueExternalizer: DataExternalizer<V>
) {
protected val storage = LazyStorage(storageFile, keyDescriptor, valueExternalizer)
fun clean() {
storage.clean()
}
fun flush(memoryCachesOnly: Boolean) {
storage.flush(memoryCachesOnly)
}
fun close() {
storage.close()
}
@TestOnly
fun dump(): String {
return with(StringBuilder()) {
with(Printer(this)) {
println(this@BasicMap::class.java.simpleName)
pushIndent()
for (key in storage.keys.sorted()) {
println("${dumpKey(key)} -> ${dumpValue(storage[key]!!)}")
}
popIndent()
}
this
}.toString()
}
@TestOnly
protected abstract fun dumpKey(key: K): String
@TestOnly
protected abstract fun dumpValue(value: V): String
}
abstract class BasicStringMap<V>(
storageFile: File,
keyDescriptor: KeyDescriptor<String>,
valueExternalizer: DataExternalizer<V>
) : BasicMap<String, V>(storageFile, keyDescriptor, valueExternalizer) {
constructor(
storageFile: File,
valueExternalizer: DataExternalizer<V>
) : this(storageFile, EnumeratorStringDescriptor.INSTANCE, valueExternalizer)
override fun dumpKey(key: String): String = key
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import org.jetbrains.kotlin.name.FqName
import java.io.File
internal open class ClassOneToManyMap(
storageFile: File
) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
fun add(key: FqName, value: FqName) {
storage.append(key.asString(), value.asString())
}
operator fun get(key: FqName): Collection<FqName> =
storage[key.asString()]?.map(::FqName) ?: setOf()
operator fun set(key: FqName, values: Collection<FqName>) {
if (values.isEmpty()) {
remove(key)
return
}
storage[key.asString()] = values.map(FqName::asString)
}
fun remove(key: FqName) {
storage.remove(key.asString())
}
fun removeValues(key: FqName, removed: Set<FqName>) {
val notRemoved = this[key].filter { it !in removed }
this[key] = notRemoved
}
}
internal class SubtypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
internal class SupertypesMap(storageFile: File) : ClassOneToManyMap(storageFile)

View File

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

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import java.io.File
internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(storage, LookupSymbolKeyDescriptor, IntCollectionExternalizer) {
override fun dumpKey(key: LookupSymbolKey): String = key.toString()
override fun dumpValue(value: Collection<Int>): String = value.toString()
fun add(name: String, scope: String, fileId: Int) {
storage.append(LookupSymbolKey(name, scope), fileId)
}
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {
storage[key] = fileIds
}
fun remove(key: LookupSymbolKey) {
storage.remove(key)
}
val keys: Collection<LookupSymbolKey>
get() = storage.keys
}

View File

@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.PersistentHashMap
import com.intellij.util.io.JpsPersistentHashMap
import java.io.File
@@ -28,10 +28,10 @@ class NonCachingLazyStorage<K, V>(
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
private var storage: JpsPersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
@@ -43,7 +43,7 @@ class NonCachingLazyStorage<K, V>(
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
@@ -69,7 +69,7 @@ class NonCachingLazyStorage<K, V>(
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
getStorageOrCreateNew().appendDataWithoutCache(key, value)
}
@Synchronized
@@ -79,7 +79,7 @@ class NonCachingLazyStorage<K, V>(
} catch (ignored: Throwable) {
}
PersistentHashMap.deleteFilesStartingWith(storageFile)
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@@ -101,6 +101,6 @@ class NonCachingLazyStorage<K, V>(
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> =
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
private fun createMap(): JpsPersistentHashMap<K, V> =
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

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

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.PersistentHashMap
import java.io.File
class NonCachingLazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
}
@Synchronized
override fun clean() {
try {
storage?.close()
} catch (ignored: Throwable) {
}
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
} else {
existingStorage.force()
}
}
@Synchronized
override fun close() {
storage?.close()
}
private fun createMap(): PersistentHashMap<K, V> =
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.incremental.dumpCollection
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.File
internal class SourceToJvmNameMap(
storageFile: File,
pathConverter: FileToPathConverter
) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile, pathConverter)
internal class SourceToFqNameMap(
storageFile: File,
pathConverter: FileToPathConverter
) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile, pathConverter)
internal abstract class AbstractSourceToOutputMap<Name>(
private val nameTransformer: NameTransformer<Name>,
storageFile: File,
private val pathConverter: FileToPathConverter
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
fun clearOutputsForSource(sourceFile: File) {
remove(pathConverter.toPath(sourceFile))
}
fun add(sourceFile: File, className: Name) {
storage.append(pathConverter.toPath(sourceFile), nameTransformer.asString(className))
}
fun contains(sourceFile: File): Boolean =
pathConverter.toPath(sourceFile) in storage
operator fun get(sourceFile: File): Collection<Name> =
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asName)
fun getFqNames(sourceFile: File): Collection<FqName> =
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asFqName)
override fun dumpValue(value: Collection<String>) =
value.dumpCollection()
private fun remove(path: String) {
storage.remove(path)
}
}

View File

@@ -208,65 +208,6 @@ public final class DebugJvmModuleProtoBuf {
*/
org.jetbrains.kotlin.metadata.DebugProtoBuf.AnnotationOrBuilder getAnnotationOrBuilder(
int index);
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
java.util.List<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class>
getOptionalAnnotationClassList();
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class getOptionalAnnotationClass(int index);
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
int getOptionalAnnotationClassCount();
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
java.util.List<? extends org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder>
getOptionalAnnotationClassOrBuilderList();
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder getOptionalAnnotationClassOrBuilder(
int index);
}
/**
* Protobuf type {@code org.jetbrains.kotlin.metadata.jvm.Module}
@@ -379,14 +320,6 @@ public final class DebugJvmModuleProtoBuf {
annotation_.add(input.readMessage(org.jetbrains.kotlin.metadata.DebugProtoBuf.Annotation.PARSER, extensionRegistry));
break;
}
case 130: {
if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
optionalAnnotationClass_ = new java.util.ArrayList<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class>();
mutable_bitField0_ |= 0x00000040;
}
optionalAnnotationClass_.add(input.readMessage(org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.PARSER, extensionRegistry));
break;
}
}
}
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
@@ -407,9 +340,6 @@ public final class DebugJvmModuleProtoBuf {
if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
annotation_ = java.util.Collections.unmodifiableList(annotation_);
}
if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
optionalAnnotationClass_ = java.util.Collections.unmodifiableList(optionalAnnotationClass_);
}
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
@@ -698,76 +628,6 @@ public final class DebugJvmModuleProtoBuf {
return annotation_.get(index);
}
public static final int OPTIONAL_ANNOTATION_CLASS_FIELD_NUMBER = 16;
private java.util.List<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class> optionalAnnotationClass_;
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public java.util.List<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class> getOptionalAnnotationClassList() {
return optionalAnnotationClass_;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public java.util.List<? extends org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder>
getOptionalAnnotationClassOrBuilderList() {
return optionalAnnotationClass_;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public int getOptionalAnnotationClassCount() {
return optionalAnnotationClass_.size();
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.Class getOptionalAnnotationClass(int index) {
return optionalAnnotationClass_.get(index);
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder getOptionalAnnotationClassOrBuilder(
int index) {
return optionalAnnotationClass_.get(index);
}
private void initFields() {
packageParts_ = java.util.Collections.emptyList();
metadataParts_ = java.util.Collections.emptyList();
@@ -775,7 +635,6 @@ public final class DebugJvmModuleProtoBuf {
stringTable_ = org.jetbrains.kotlin.metadata.DebugProtoBuf.StringTable.getDefaultInstance();
qualifiedNameTable_ = org.jetbrains.kotlin.metadata.DebugProtoBuf.QualifiedNameTable.getDefaultInstance();
annotation_ = java.util.Collections.emptyList();
optionalAnnotationClass_ = java.util.Collections.emptyList();
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -807,12 +666,6 @@ public final class DebugJvmModuleProtoBuf {
return false;
}
}
for (int i = 0; i < getOptionalAnnotationClassCount(); i++) {
if (!getOptionalAnnotationClass(i).isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
memoizedIsInitialized = 1;
return true;
}
@@ -838,9 +691,6 @@ public final class DebugJvmModuleProtoBuf {
for (int i = 0; i < annotation_.size(); i++) {
output.writeMessage(6, annotation_.get(i));
}
for (int i = 0; i < optionalAnnotationClass_.size(); i++) {
output.writeMessage(16, optionalAnnotationClass_.get(i));
}
getUnknownFields().writeTo(output);
}
@@ -879,10 +729,6 @@ public final class DebugJvmModuleProtoBuf {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(6, annotation_.get(i));
}
for (int i = 0; i < optionalAnnotationClass_.size(); i++) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(16, optionalAnnotationClass_.get(i));
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -997,7 +843,6 @@ public final class DebugJvmModuleProtoBuf {
getStringTableFieldBuilder();
getQualifiedNameTableFieldBuilder();
getAnnotationFieldBuilder();
getOptionalAnnotationClassFieldBuilder();
}
}
private static Builder create() {
@@ -1038,12 +883,6 @@ public final class DebugJvmModuleProtoBuf {
} else {
annotationBuilder_.clear();
}
if (optionalAnnotationClassBuilder_ == null) {
optionalAnnotationClass_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000040);
} else {
optionalAnnotationClassBuilder_.clear();
}
return this;
}
@@ -1120,15 +959,6 @@ public final class DebugJvmModuleProtoBuf {
} else {
result.annotation_ = annotationBuilder_.build();
}
if (optionalAnnotationClassBuilder_ == null) {
if (((bitField0_ & 0x00000040) == 0x00000040)) {
optionalAnnotationClass_ = java.util.Collections.unmodifiableList(optionalAnnotationClass_);
bitField0_ = (bitField0_ & ~0x00000040);
}
result.optionalAnnotationClass_ = optionalAnnotationClass_;
} else {
result.optionalAnnotationClass_ = optionalAnnotationClassBuilder_.build();
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -1239,32 +1069,6 @@ public final class DebugJvmModuleProtoBuf {
}
}
}
if (optionalAnnotationClassBuilder_ == null) {
if (!other.optionalAnnotationClass_.isEmpty()) {
if (optionalAnnotationClass_.isEmpty()) {
optionalAnnotationClass_ = other.optionalAnnotationClass_;
bitField0_ = (bitField0_ & ~0x00000040);
} else {
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.addAll(other.optionalAnnotationClass_);
}
onChanged();
}
} else {
if (!other.optionalAnnotationClass_.isEmpty()) {
if (optionalAnnotationClassBuilder_.isEmpty()) {
optionalAnnotationClassBuilder_.dispose();
optionalAnnotationClassBuilder_ = null;
optionalAnnotationClass_ = other.optionalAnnotationClass_;
bitField0_ = (bitField0_ & ~0x00000040);
optionalAnnotationClassBuilder_ =
org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
getOptionalAnnotationClassFieldBuilder() : null;
} else {
optionalAnnotationClassBuilder_.addAllMessages(other.optionalAnnotationClass_);
}
}
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -1294,12 +1098,6 @@ public final class DebugJvmModuleProtoBuf {
return false;
}
}
for (int i = 0; i < getOptionalAnnotationClassCount(); i++) {
if (!getOptionalAnnotationClass(i).isInitialized()) {
return false;
}
}
return true;
}
@@ -2628,372 +2426,6 @@ public final class DebugJvmModuleProtoBuf {
return annotationBuilder_;
}
private java.util.List<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class> optionalAnnotationClass_ =
java.util.Collections.emptyList();
private void ensureOptionalAnnotationClassIsMutable() {
if (!((bitField0_ & 0x00000040) == 0x00000040)) {
optionalAnnotationClass_ = new java.util.ArrayList<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class>(optionalAnnotationClass_);
bitField0_ |= 0x00000040;
}
}
private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder, org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder> optionalAnnotationClassBuilder_;
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public java.util.List<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class> getOptionalAnnotationClassList() {
if (optionalAnnotationClassBuilder_ == null) {
return java.util.Collections.unmodifiableList(optionalAnnotationClass_);
} else {
return optionalAnnotationClassBuilder_.getMessageList();
}
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public int getOptionalAnnotationClassCount() {
if (optionalAnnotationClassBuilder_ == null) {
return optionalAnnotationClass_.size();
} else {
return optionalAnnotationClassBuilder_.getCount();
}
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.Class getOptionalAnnotationClass(int index) {
if (optionalAnnotationClassBuilder_ == null) {
return optionalAnnotationClass_.get(index);
} else {
return optionalAnnotationClassBuilder_.getMessage(index);
}
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder setOptionalAnnotationClass(
int index, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class value) {
if (optionalAnnotationClassBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.set(index, value);
onChanged();
} else {
optionalAnnotationClassBuilder_.setMessage(index, value);
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder setOptionalAnnotationClass(
int index, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder builderForValue) {
if (optionalAnnotationClassBuilder_ == null) {
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.set(index, builderForValue.build());
onChanged();
} else {
optionalAnnotationClassBuilder_.setMessage(index, builderForValue.build());
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder addOptionalAnnotationClass(org.jetbrains.kotlin.metadata.DebugProtoBuf.Class value) {
if (optionalAnnotationClassBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.add(value);
onChanged();
} else {
optionalAnnotationClassBuilder_.addMessage(value);
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder addOptionalAnnotationClass(
int index, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class value) {
if (optionalAnnotationClassBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.add(index, value);
onChanged();
} else {
optionalAnnotationClassBuilder_.addMessage(index, value);
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder addOptionalAnnotationClass(
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder builderForValue) {
if (optionalAnnotationClassBuilder_ == null) {
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.add(builderForValue.build());
onChanged();
} else {
optionalAnnotationClassBuilder_.addMessage(builderForValue.build());
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder addOptionalAnnotationClass(
int index, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder builderForValue) {
if (optionalAnnotationClassBuilder_ == null) {
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.add(index, builderForValue.build());
onChanged();
} else {
optionalAnnotationClassBuilder_.addMessage(index, builderForValue.build());
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder addAllOptionalAnnotationClass(
java.lang.Iterable<? extends org.jetbrains.kotlin.metadata.DebugProtoBuf.Class> values) {
if (optionalAnnotationClassBuilder_ == null) {
ensureOptionalAnnotationClassIsMutable();
org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
values, optionalAnnotationClass_);
onChanged();
} else {
optionalAnnotationClassBuilder_.addAllMessages(values);
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder clearOptionalAnnotationClass() {
if (optionalAnnotationClassBuilder_ == null) {
optionalAnnotationClass_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000040);
onChanged();
} else {
optionalAnnotationClassBuilder_.clear();
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public Builder removeOptionalAnnotationClass(int index) {
if (optionalAnnotationClassBuilder_ == null) {
ensureOptionalAnnotationClassIsMutable();
optionalAnnotationClass_.remove(index);
onChanged();
} else {
optionalAnnotationClassBuilder_.remove(index);
}
return this;
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder getOptionalAnnotationClassBuilder(
int index) {
return getOptionalAnnotationClassFieldBuilder().getBuilder(index);
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder getOptionalAnnotationClassOrBuilder(
int index) {
if (optionalAnnotationClassBuilder_ == null) {
return optionalAnnotationClass_.get(index); } else {
return optionalAnnotationClassBuilder_.getMessageOrBuilder(index);
}
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public java.util.List<? extends org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder>
getOptionalAnnotationClassOrBuilderList() {
if (optionalAnnotationClassBuilder_ != null) {
return optionalAnnotationClassBuilder_.getMessageOrBuilderList();
} else {
return java.util.Collections.unmodifiableList(optionalAnnotationClass_);
}
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder addOptionalAnnotationClassBuilder() {
return getOptionalAnnotationClassFieldBuilder().addBuilder(
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.getDefaultInstance());
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder addOptionalAnnotationClassBuilder(
int index) {
return getOptionalAnnotationClassFieldBuilder().addBuilder(
index, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.getDefaultInstance());
}
/**
* <code>repeated .org.jetbrains.kotlin.metadata.Class optional_annotation_class = 16;</code>
*
* <pre>
* &#64;OptionalExpectation-annotated annotation classes in this module. This list is only used in the compiler frontend when compiling
* a second-tier multiplatform module against a multiplatform module which uses optional annotations, not actualized on the JVM.
* This is not needed in the IDE because optional annotations can only be used in common modules, where the IDE plugin resolves
* it to the corresponding class with the resolution capabilities of common modules.
* </pre>
*/
public java.util.List<org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder>
getOptionalAnnotationClassBuilderList() {
return getOptionalAnnotationClassFieldBuilder().getBuilderList();
}
private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder, org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder>
getOptionalAnnotationClassFieldBuilder() {
if (optionalAnnotationClassBuilder_ == null) {
optionalAnnotationClassBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class, org.jetbrains.kotlin.metadata.DebugProtoBuf.Class.Builder, org.jetbrains.kotlin.metadata.DebugProtoBuf.ClassOrBuilder>(
optionalAnnotationClass_,
((bitField0_ & 0x00000040) == 0x00000040),
getParentForChildren(),
isClean());
optionalAnnotationClass_ = null;
}
return optionalAnnotationClassBuilder_;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.metadata.jvm.Module)
}
@@ -5212,7 +4644,7 @@ public final class DebugJvmModuleProtoBuf {
"\n,core/metadata.jvm/src/jvm_module.debug" +
".proto\022!org.jetbrains.kotlin.metadata.jv" +
"m\032&core/metadata/src/metadata.debug.prot" +
"o\"\316\003\n\006Module\022F\n\rpackage_parts\030\001 \003(\0132/.or" +
"o\"\205\003\n\006Module\022F\n\rpackage_parts\030\001 \003(\0132/.or" +
"g.jetbrains.kotlin.metadata.jvm.PackageP" +
"arts\022G\n\016metadata_parts\030\002 \003(\0132/.org.jetbr" +
"ains.kotlin.metadata.jvm.PackageParts\022\030\n" +
@@ -5221,18 +4653,16 @@ public final class DebugJvmModuleProtoBuf {
"ringTable\022O\n\024qualified_name_table\030\005 \001(\0132",
"1.org.jetbrains.kotlin.metadata.Qualifie" +
"dNameTable\022=\n\nannotation\030\006 \003(\0132).org.jet" +
"brains.kotlin.metadata.Annotation\022G\n\031opt" +
"ional_annotation_class\030\020 \003(\0132$.org.jetbr" +
"ains.kotlin.metadata.Class\"\276\002\n\014PackagePa" +
"rts\022\027\n\017package_fq_name\030\001 \002(\t\022\030\n\020short_cl" +
"ass_name\030\002 \003(\t\022*\n\036multifile_facade_short" +
"_name_id\030\003 \003(\005B\002\020\001\022#\n\033multifile_facade_s" +
"hort_name\030\004 \003(\t\022.\n&class_with_jvm_packag" +
"e_name_short_name\030\005 \003(\t\022F\n:class_with_jv",
"m_package_name_multifile_facade_short_na" +
"me_id\030\007 \003(\005B\002\020\001\0222\n&class_with_jvm_packag" +
"e_name_package_id\030\006 \003(\005B\002\020\001B\030B\026DebugJvmM" +
"oduleProtoBuf"
"brains.kotlin.metadata.Annotation\"\276\002\n\014Pa" +
"ckageParts\022\027\n\017package_fq_name\030\001 \002(\t\022\030\n\020s" +
"hort_class_name\030\002 \003(\t\022*\n\036multifile_facad" +
"e_short_name_id\030\003 \003(\005B\002\020\001\022#\n\033multifile_f" +
"acade_short_name\030\004 \003(\t\022.\n&class_with_jvm" +
"_package_name_short_name\030\005 \003(\t\022F\n:class_" +
"with_jvm_package_name_multifile_facade_s" +
"hort_name_id\030\007 \003(\005B\002\020\001\0222\n&class_with_jvm",
"_package_name_package_id\030\006 \003(\005B\002\020\001B\030B\026De" +
"bugJvmModuleProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
@@ -5252,7 +4682,7 @@ public final class DebugJvmModuleProtoBuf {
internal_static_org_jetbrains_kotlin_metadata_jvm_Module_fieldAccessorTable = new
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_org_jetbrains_kotlin_metadata_jvm_Module_descriptor,
new java.lang.String[] { "PackageParts", "MetadataParts", "JvmPackageName", "StringTable", "QualifiedNameTable", "Annotation", "OptionalAnnotationClass", });
new java.lang.String[] { "PackageParts", "MetadataParts", "JvmPackageName", "StringTable", "QualifiedNameTable", "Annotation", });
internal_static_org_jetbrains_kotlin_metadata_jvm_PackageParts_descriptor =
getDescriptor().getMessageTypes().get(1);
internal_static_org_jetbrains_kotlin_metadata_jvm_PackageParts_fieldAccessorTable = new

View File

@@ -18,7 +18,6 @@ public final class DebugJvmProtoBuf {
registry.add(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.classModuleName);
registry.add(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.classLocalVariable);
registry.add(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.anonymousObjectOriginName);
registry.add(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.jvmClassFlags);
registry.add(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.packageModuleName);
registry.add(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.packageLocalVariable);
}
@@ -4651,21 +4650,6 @@ public final class DebugJvmProtoBuf {
.newFileScopedGeneratedExtension(
java.lang.Integer.class,
null);
public static final int JVM_CLASS_FLAGS_FIELD_NUMBER = 104;
/**
* <code>extend .org.jetbrains.kotlin.metadata.Class { ... }</code>
*
* <pre>
* isFunctionBodyInInterface: 0 if actual body generated in DefaultImpl, 1 - otherwise (in interface default method)
* </pre>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.metadata.DebugProtoBuf.Class,
java.lang.Integer> jvmClassFlags = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.Integer.class,
null);
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
/**
* <code>extend .org.jetbrains.kotlin.metadata.Package { ... }</code>
@@ -4774,13 +4758,12 @@ public final class DebugJvmProtoBuf {
"\'.org.jetbrains.kotlin.metadata.Property",
":P\n\034anonymous_object_origin_name\022$.org.j" +
"etbrains.kotlin.metadata.Class\030g \001(\005B\004\230\265" +
"\030\001:@\n\017jvm_class_flags\022$.org.jetbrains.ko" +
"tlin.metadata.Class\030h \001(\005:\0010:I\n\023package_" +
"module_name\022&.org.jetbrains.kotlin.metad" +
"ata.Package\030e \001(\005B\004\230\265\030\001:o\n\026package_local" +
"_variable\022&.org.jetbrains.kotlin.metadat" +
"a.Package\030f \003(\0132\'.org.jetbrains.kotlin.m" +
"etadata.PropertyB\022B\020DebugJvmProtoBuf"
"\030\001:I\n\023package_module_name\022&.org.jetbrain" +
"s.kotlin.metadata.Package\030e \001(\005B\004\230\265\030\001:o\n" +
"\026package_local_variable\022&.org.jetbrains." +
"kotlin.metadata.Package\030f \003(\0132\'.org.jetb" +
"rains.kotlin.metadata.PropertyB\022B\020DebugJ" +
"vmProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
@@ -4837,9 +4820,8 @@ public final class DebugJvmProtoBuf {
classModuleName.internalInit(descriptor.getExtensions().get(8));
classLocalVariable.internalInit(descriptor.getExtensions().get(9));
anonymousObjectOriginName.internalInit(descriptor.getExtensions().get(10));
jvmClassFlags.internalInit(descriptor.getExtensions().get(11));
packageModuleName.internalInit(descriptor.getExtensions().get(12));
packageLocalVariable.internalInit(descriptor.getExtensions().get(13));
packageModuleName.internalInit(descriptor.getExtensions().get(11));
packageLocalVariable.internalInit(descriptor.getExtensions().get(12));
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry =
org.jetbrains.kotlin.protobuf.ExtensionRegistry.newInstance();
registry.add(org.jetbrains.kotlin.metadata.DebugExtOptionsProtoBuf.stringIdInTable);

View File

@@ -1,13 +1,13 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.crypto.checksum.Checksum
import org.gradle.plugins.ide.idea.model.IdeaModel
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import proguard.gradle.ProGuardTask
buildscript {
extra["defaultSnapshotVersion"] = "1.4-SNAPSHOT"
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap("1.4.0-dev-1818", cacheRedirectorEnabled))
repositories {
bootstrapKotlinRepo?.let(::maven)
@@ -27,8 +27,10 @@ buildscript {
dependencies {
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.19")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
classpath("com.gradle.publish:plugin-publish-plugin:0.9.7")
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
classpath("net.sf.proguard:proguard-gradle:6.1.0")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:0.9.17")
}
}
@@ -38,12 +40,9 @@ if (kotlinBuildProperties.buildScanServer != null) {
}
plugins {
base
idea
id("jps-compatible")
id("org.jetbrains.gradle.plugin.idea-ext")
id("org.gradle.crypto.checksum") version "1.2.0"
signing
}
pill {
@@ -56,6 +55,9 @@ pill {
}
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
val includeStdlibJsIr by extra(
findProperty("include.stdlib.js.ir")?.let { it.toString().toBoolean() } ?: isTeamcityBuild
)
val configuredJdks: List<JdkId> =
getConfiguredJdks().also {
@@ -66,11 +68,7 @@ val configuredJdks: List<JdkId> =
val defaultSnapshotVersion: String by extra
val buildNumber by extra(findProperty("build.number")?.toString() ?: defaultSnapshotVersion)
val kotlinVersion by extra(
findProperty("deployVersion")?.toString()?.let { deploySnapshotStr ->
if (deploySnapshotStr != "default.snapshot") deploySnapshotStr else defaultSnapshotVersion
} ?: buildNumber
)
val kotlinVersion by extra(findProperty("deployVersion")?.toString() ?: buildNumber)
val kotlinLanguageVersion by extra("1.4")
@@ -150,9 +148,6 @@ rootProject.apply {
from(rootProject.file("gradle/report.gradle.kts"))
from(rootProject.file("gradle/javaInstrumentation.gradle.kts"))
from(rootProject.file("gradle/jps.gradle.kts"))
from(rootProject.file("gradle/checkArtifacts.gradle.kts"))
from(rootProject.file("gradle/checkCacheability.gradle.kts"))
from(rootProject.file("gradle/retryPublishing.gradle.kts"))
}
IdeVersionConfigurator.setCurrentIde(project)
@@ -166,34 +161,30 @@ extra["versions.junit"] = "4.12"
extra["versions.javaslang"] = "2.0.6"
extra["versions.ant"] = "1.8.2"
extra["versions.android"] = "2.3.1"
val coroutinesVersion = if (Platform[192].orHigher()) "1.3.7" else "1.1.1"
val coroutinesVersion = if (Platform[192].orHigher()) "1.2.1" else "1.1.1"
extra["versions.kotlinx-coroutines-core"] = coroutinesVersion
extra["versions.kotlinx-coroutines-jdk8"] = coroutinesVersion
extra["versions.json"] = "20160807"
extra["versions.native-platform"] = "0.14"
extra["versions.ant-launcher"] = "1.8.0"
extra["versions.robolectric"] = "4.0"
extra["versions.robolectric"] = "3.1"
extra["versions.org.springframework"] = "4.2.0.RELEASE"
extra["versions.jflex"] = "1.7.0"
extra["versions.markdown"] = "0.1.25"
extra["versions.trove4j"] = "1.0.20181211"
extra["versions.completion-ranking-kotlin"] = "0.1.2"
extra["versions.r8"] = "1.5.70"
val immutablesVersion = "0.3.1"
extra["versions.kotlinx-collections-immutable"] = immutablesVersion
extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
// NOTE: please, also change KTOR_NAME in pathUtil.kt and all versions in corresponding jar names in daemon tests.
extra["versions.ktor-network"] = "1.0.1"
if (!project.hasProperty("versions.kotlin-native")) {
extra["versions.kotlin-native"] = "1.4-M3-dev-15627"
extra["versions.kotlin-native"] = "1.4-dev-14579"
}
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
val effectSystemEnabled by extra(project.getBooleanProperty("kotlin.compiler.effectSystemEnabled") ?: false)
val newInferenceEnabled by extra(project.getBooleanProperty("kotlin.compiler.newInferenceEnabled") ?: false)
val useJvmIrBackend by extra(project.getBooleanProperty("kotlin.build.useIR") ?: false)
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
@@ -201,10 +192,7 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
extra["IntellijCoreDependencies"] =
listOf(
when {
Platform[202].orHigher() -> "asm-all-8.0.1"
else -> "asm-all-7.0.1"
},
if (Platform[191].orHigher()) "asm-all-7.0.1" else "asm-all",
"guava",
"jdom",
"jna",
@@ -218,8 +206,6 @@ extra["IntellijCoreDependencies"] =
extra["compilerModules"] = arrayOf(
":compiler:util",
":compiler:config",
":compiler:config.jvm",
":compiler:container",
":compiler:resolution",
":compiler:serialization",
@@ -237,7 +223,6 @@ extra["compilerModules"] = arrayOf(
":compiler:ir.serialization.common",
":compiler:ir.serialization.js",
":compiler:ir.serialization.jvm",
":compiler:ir.interpreter",
":kotlin-util-io",
":kotlin-util-klib",
":kotlin-util-klib-metadata",
@@ -245,20 +230,16 @@ extra["compilerModules"] = arrayOf(
":compiler:backend",
":compiler:plugin-api",
":compiler:light-classes",
":compiler:javac-wrapper",
":compiler:cli",
":compiler:cli-js",
":compiler:incremental-compilation-impl",
":compiler:compiler.version",
":js:js.ast",
":js:js.serializer",
":js:js.parser",
":js:js.config",
":js:js.frontend",
":js:js.translator",
":js:js.dce",
":native:frontend.native",
":native:kotlin-native-utils",
":compiler",
":kotlin-build-common",
":core:metadata",
@@ -271,48 +252,23 @@ extra["compilerModules"] = arrayOf(
":core:type-system",
":compiler:fir:cones",
":compiler:fir:resolve",
":compiler:fir:fir-serialization",
":compiler:fir:tree",
":compiler:fir:raw-fir:fir-common",
":compiler:fir:raw-fir:psi2fir",
":compiler:fir:raw-fir:light-tree2fir",
":compiler:fir:psi2fir",
":compiler:fir:lightTree",
":compiler:fir:fir2ir",
":compiler:fir:fir2ir:jvm-backend",
":compiler:fir:java",
":compiler:fir:jvm",
":compiler:fir:checkers",
":compiler:fir:analysis-tests"
)
extra["compilerModulesForJps"] = listOf(
":core:type-system",
":kotlin-build-common",
":kotlin-util-io",
":kotlin-util-klib",
":kotlin-util-klib-metadata",
":compiler:cli-common",
":kotlin-compiler-runner",
":daemon-common",
":daemon-common-new",
":core:descriptors",
":core:descriptors.jvm",
":idea:idea-jps-common",
":kotlin-preloader",
":compiler:util",
":compiler:config",
":compiler:config.jvm",
":js:js.config",
":core:util.runtime",
":compiler:compiler.version"
":compiler:fir:jvm"
)
val coreLibProjects = listOfNotNull(
":kotlin-stdlib",
":kotlin-stdlib-common",
":kotlin-stdlib-js",
// Exclude JS IR from core libs because it depends on local compiler build, which
// in turn depends on local JVM stdlib. It slows down library testing.
":kotlin-stdlib-js-ir".takeIf { includeStdlibJsIr },
":kotlin-stdlib-jdk7",
":kotlin-stdlib-jdk8",
":kotlin-test:kotlin-test-annotations-common",
":kotlin-test:kotlin-test-common",
":kotlin-test:kotlin-test-jvm",
":kotlin-test:kotlin-test-junit",
@@ -325,10 +281,14 @@ val coreLibProjects = listOfNotNull(
val gradlePluginProjects = listOf(
":kotlin-gradle-plugin",
":kotlin-gradle-plugin:plugin-marker",
":kotlin-gradle-plugin-api",
// ":kotlin-gradle-plugin-integration-tests", // TODO: build fails
":kotlin-allopen",
":kotlin-allopen:plugin-marker",
":kotlin-annotation-processing-gradle",
":kotlin-noarg",
":kotlin-noarg:plugin-marker",
":kotlin-sam-with-receiver"
)
@@ -354,27 +314,11 @@ fun Task.listConfigurationContents(configName: String) {
val defaultJvmTarget = "1.8"
val defaultJavaHome = jdkPath(defaultJvmTarget)
val ignoreTestFailures by extra(project.kotlinBuildProperties.ignoreTestFailures)
val ignoreTestFailures by extra(project.findProperty("ignoreTestFailures")?.toString()?.toBoolean() ?: project.hasProperty("teamcity"))
allprojects {
configurations.maybeCreate("embedded").apply {
isCanBeConsumed = false
isCanBeResolved = true
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
}
}
configurations.maybeCreate("embeddedElements").apply {
extendsFrom(configurations["embedded"])
isCanBeConsumed = true
isCanBeResolved = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named("embedded-java-runtime"))
}
}
configurations.maybeCreate("embedded")
jvmTarget = defaultJvmTarget
javaHome = defaultJavaHome
@@ -398,14 +342,15 @@ allprojects {
maven("https://jetbrains.bintray.com/intellij-third-party-dependencies")
maven("https://dl.google.com/dl/android/maven2")
bootstrapKotlinRepo?.let(::maven)
internalBootstrapRepo?.let(::maven)
internalKotlinRepo?.let(::maven)
}
configureJvmProject(javaHome!!, jvmTarget!!)
val commonCompilerArgs = listOfNotNull(
"-Xopt-in=kotlin.RequiresOptIn",
"-Xuse-experimental=kotlin.Experimental",
"-Xread-deserialized-contracts",
"-Xjvm-default=compatibility",
"-progressive".takeIf { hasProperty("test.progressive.mode") }
)
@@ -417,20 +362,9 @@ allprojects {
}
}
val jvmCompilerArgs = listOf(
"-Xjvm-default=compatibility",
"-Xno-optimized-callable-references",
"-Xno-kotlin-nothing-value-exception",
"-Xnormalize-constructor-calls=enable"
)
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
kotlinOptions {
freeCompilerArgs = commonCompilerArgs + jvmCompilerArgs
if (useJvmIrBackend) {
useIR = true
}
freeCompilerArgs = commonCompilerArgs + listOf("-Xnormalize-constructor-calls=enable")
}
}
@@ -452,16 +386,8 @@ allprojects {
}
tasks.withType<Test> {
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KT-37089") { true }
}
normalization {
runtimeClasspath {
ignore("META-INF/MANIFEST.MF")
ignore("META-INF/compiler.version")
ignore("META-INF/plugin.xml")
ignore("kotlin/KotlinVersionCurrentValue.class")
}
outputs.cacheIf { false }
// https://youtrack.jetbrains.com/issue/KT-37089
}
tasks {
@@ -470,9 +396,6 @@ allprojects {
register("listRuntimeJar") { listConfigurationContents("runtimeJar") }
register("listDistJar") { listConfigurationContents("distJar") }
// Aggregate task for build related checks
register("checkBuild")
}
afterEvaluate {
@@ -509,20 +432,19 @@ allprojects {
?.exclude("org.jetbrains.kotlin", "kotlin-scripting-compiler-embeddable")
}
// Aggregate task for build related checks
tasks.register("checkBuild")
apply(from = "$rootDir/gradle/cacheRedirector.gradle.kts")
}
}
gradle.taskGraph.whenReady {
fun Boolean.toOnOff(): String = if (this) "on" else "off"
val profile = if (isTeamcityBuild) "CI" else "Local"
val proguardMessage = "proguard is ${kotlinBuildProperties.proguard.toOnOff()}"
val jarCompressionMessage = "jar compression is ${kotlinBuildProperties.jarCompression.toOnOff()}"
val profileMessage = "$profile build profile is active ($proguardMessage, $jarCompressionMessage). " +
"Use -Pteamcity=<true|false> to reproduce CI/local build"
logger.warn("\n\n$profileMessage")
if (isTeamcityBuild) {
logger.warn("CI build profile is active (IC is off, proguard is on). Use -Pteamcity=false to reproduce local build")
} else {
logger.warn("Local build profile is active (IC is on, proguard is off). Use -Pteamcity=true to reproduce TC build")
}
allTasks.filterIsInstance<org.gradle.jvm.tasks.Jar>().forEach { task ->
task.entryCompression = if (kotlinBuildProperties.jarCompression)
@@ -536,10 +458,6 @@ val dist = tasks.register("dist") {
dependsOn(":kotlin-compiler:dist")
}
val syncMutedTests = tasks.register("syncMutedTests") {
dependsOn(":compiler:tests-mutes:run")
}
val copyCompilerToIdeaPlugin by task<Copy> {
dependsOn(dist)
into(ideaPluginDir)
@@ -552,7 +470,7 @@ val ideaPlugin by task<Task> {
}
tasks {
named("clean") {
register("clean") {
doLast {
delete("$buildDir/repo")
delete(distDir)
@@ -565,7 +483,7 @@ tasks {
}
}
listOf("clean", "assemble", "install").forEach { taskName ->
listOf("clean", "assemble", "install", "dist").forEach { taskName ->
register("coreLibs${taskName.capitalize()}") {
coreLibProjects.forEach { projectName -> dependsOn("$projectName:$taskName") }
}
@@ -574,8 +492,6 @@ tasks {
register("coreLibsTest") {
(coreLibProjects + listOf(
":kotlin-stdlib:samples",
":kotlin-stdlib-js-ir",
":kotlin-test:kotlin-test-js-ir".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
":kotlin-test:kotlin-test-js:kotlin-test-js-it".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
":kotlinx-metadata-jvm",
":tools:binary-compatibility-validator"
@@ -600,7 +516,7 @@ tasks {
":compiler:test",
":compiler:container:test",
":compiler:tests-java8:test",
":compiler:tests-spec:test",
":compiler:tests-spec:remoteRunTests",
":compiler:tests-against-klib:test"
)
dependsOn(":plugins:jvm-abi-gen:test")
@@ -623,25 +539,21 @@ tasks {
// dependsOn(":js:js.tests:wasmTest")
}
register("nativeCompilerTest") {
dependsOn(":native:kotlin-native-utils:test")
}
register("firCompilerTest") {
dependsOn(":compiler:fir:raw-fir:psi2fir:test")
dependsOn(":compiler:fir:raw-fir:light-tree2fir:test")
dependsOn(":compiler:fir:analysis-tests:test")
dependsOn(":compiler:fir:psi2fir:test")
dependsOn(":compiler:fir:resolve:test")
dependsOn(":compiler:fir:fir2ir:test")
dependsOn(":compiler:fir:lightTree:test")
}
register("firAllTest") {
dependsOn(
":dist",
":compiler:fir:raw-fir:psi2fir:test",
":compiler:fir:raw-fir:light-tree2fir:test",
":compiler:fir:analysis-tests:test",
":compiler:fir:psi2fir:test",
":compiler:fir:lightTree:test",
":compiler:fir:resolve:test",
":compiler:fir:fir2ir:test",
":plugins:fir:fir-plugin-prototype:test"
":compiler:firBlackBox:test",
":idea:firTest"
)
}
@@ -652,7 +564,7 @@ tasks {
register("scriptingTest") {
dependsOn("dist")
dependsOn(":kotlin-script-util:test")
dependsOn(":kotlin-scripting-compiler-embeddable:test")
dependsOn(":kotlin-scripting-compiler:test")
dependsOn(":kotlin-scripting-common:test")
dependsOn(":kotlin-scripting-jvm:test")
dependsOn(":kotlin-scripting-jvm-host-test:test")
@@ -663,23 +575,14 @@ tasks {
// dependsOn(":kotlin-scripting-jvm-host-test:embeddableTest")
dependsOn(":kotlin-scripting-jsr223-test:embeddableTest")
dependsOn(":kotlin-main-kts-test:test")
dependsOn(":kotlin-scripting-ide-services-test:test")
dependsOn(":kotlin-scripting-ide-services-test:embeddableTest")
dependsOn(":kotlin-scripting-js-test:test")
}
register("compilerTest") {
dependsOn("jvmCompilerTest")
dependsOn("jsCompilerTest")
dependsOn("miscCompilerTest")
}
register("miscCompilerTest") {
dependsOn("wasmCompilerTest")
dependsOn("nativeCompilerTest")
dependsOn("firCompilerTest")
dependsOn(":kotlin-daemon-tests:test")
dependsOn("scriptingTest")
dependsOn(":kotlin-build-common:test")
dependsOn(":compiler:incremental-compilation-impl:test")
@@ -690,7 +593,6 @@ tasks {
register("toolsTest") {
dependsOn(":tools:kotlinp:test")
dependsOn(":native:kotlin-klib-commonizer:test")
}
register("examplesTest") {
@@ -721,6 +623,13 @@ tasks {
dependsOn(":jps-plugin:test")
}
register("konan-tests") {
dependsOn("dist")
dependsOn(
":native:kotlin-klib-commonizer:test"
)
}
register("idea-plugin-main-tests") {
dependsOn("dist")
dependsOn(":idea:test")
@@ -729,6 +638,8 @@ tasks {
register("idea-plugin-additional-tests") {
dependsOn("dist")
dependsOn(
":idea:idea-gradle:test",
":idea:idea-gradle-native:test",
":idea:idea-maven:test",
":j2k:test",
":nj2k:test",
@@ -740,26 +651,21 @@ 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",
":idea:idea-new-project-wizard:test"
)
}
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"
)
}
register("idea-plugin-tests") {
dependsOn("dist")
dependsOn(
"idea-plugin-main-tests",
"idea-plugin-additional-tests"
"idea-plugin-additional-tests",
"idea-new-project-wizard-tests"
)
if (Ide.IJ()) {
dependsOn("idea-new-project-wizard-tests")
}
}
register("idea-plugin-performance-tests") {
@@ -782,6 +688,7 @@ tasks {
dependsOn("dist")
dependsOn(
":kotlin-annotation-processing:test",
":kotlin-source-sections-compiler-plugin:test",
":kotlin-allopen-compiler-plugin:test",
":kotlin-noarg-compiler-plugin:test",
":kotlin-sam-with-receiver-compiler-plugin:test",
@@ -795,81 +702,16 @@ tasks {
register("ideaPluginTest") {
dependsOn(
"gradleIdeTest",
"androidIdeTest",
"miscIdeTests"
)
}
register("miscIdeTests") {
dependsOn(
"idea-plugin-tests",
"jps-tests",
"konan-tests",
"plugins-tests",
"android-ide-tests",
":generators:test"
)
}
register("androidIdeTest") {
dependsOn("android-ide-tests")
}
register("gradleIdeTest") {
dependsOn(
":idea:idea-gradle:test",
":idea:idea-gradle-native:test"
)
}
register("publishIdeArtifacts") {
idePluginDependency {
dependsOn(
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-tests-for-ide:publish",
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-dist-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide:publish",
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide:publish",
":prepare:ide-plugin-dependencies:compiler-components-for-jps:publish",
":kotlin-script-runtime:publish",
":kotlin-script-util:publish",
":kotlin-scripting-common:publish",
":kotlin-scripting-jvm:publish",
":kotlin-scripting-compiler:publish",
":kotlin-scripting-compiler-impl:publish",
":kotlin-android-extensions-runtime:publish",
":kotlin-stdlib-common:publish",
":kotlin-stdlib:publish",
":kotlin-stdlib-jdk7:publish",
":kotlin-stdlib-jdk8:publish",
":kotlin-reflect:publish",
":kotlin-main-kts:publish",
":kotlin-stdlib-js:publish",
":kotlin-test:kotlin-test-js:publish"
)
}
}
register("kmmTest", AggregateTest::class) {
dependsOn(
":idea:idea-gradle:test",
":idea:test",
":compiler:test",
":js:js.tests:test"
)
if (Ide.IJ193.orHigher())
dependsOn(":kotlin-gradle-plugin-integration-tests:test")
if (Ide.AS40.orHigher())
dependsOn(":kotlin-ultimate:ide:android-studio-native:test")
testPatternFile = file("tests/mpp/kmm-patterns.csv")
}
register("test") {
doLast {
@@ -877,17 +719,9 @@ tasks {
}
}
named("check") {
register("check") {
dependsOn("test")
}
named("checkBuild") {
if (kotlinBuildProperties.isTeamcityBuild) {
doFirst {
println("##teamcity[setParameter name='bootstrap.kotlin.version' value='$bootstrapKotlinVersion']")
}
}
}
}
fun CopySpec.setExecutablePermissions() {
@@ -897,15 +731,15 @@ fun CopySpec.setExecutablePermissions() {
val zipCompiler by task<Zip> {
dependsOn(dist)
destinationDirectory.set(file(distDir))
archiveFileName.set("kotlin-compiler-$kotlinVersion.zip")
destinationDir = file(distDir)
archiveName = "kotlin-compiler-$kotlinVersion.zip"
from(distKotlinHomeDir)
into("kotlinc")
setExecutablePermissions()
doLast {
logger.lifecycle("Compiler artifacts packed to ${archiveFile.get().asFile.absolutePath}")
logger.lifecycle("Compiler artifacts packed to $archivePath")
}
}
@@ -914,7 +748,6 @@ val zipStdlibTests by task<Zip> {
archiveFileName.set("kotlin-stdlib-tests.zip")
from("libraries/stdlib/common/test") { into("common") }
from("libraries/stdlib/test") { into("test") }
from("libraries/kotlin.test/common/src/test/kotlin") { into("kotlin-test") }
doLast {
logger.lifecycle("Stdlib tests are packed to ${archiveFile.get()}")
}
@@ -943,45 +776,21 @@ val zipPlugin by task<Zip> {
}
val destPath = project.findProperty("pluginZipPath") as String?
val dest = File(destPath ?: "$buildDir/kotlin-plugin.zip")
destinationDirectory.set(dest.parentFile)
archiveFileName.set(dest.name)
destinationDir = dest.parentFile
archiveName = dest.name
doFirst {
if (destPath == null) throw GradleException("Specify target zip path with 'pluginZipPath' property")
}
from(src)
into("Kotlin")
setExecutablePermissions()
doLast {
logger.lifecycle("Plugin artifacts packed to $archiveFile")
logger.lifecycle("Plugin artifacts packed to $archivePath")
}
}
fun Project.secureZipTask(zipTask: TaskProvider<Zip>): RegisteringDomainObjectDelegateProviderWithAction<out TaskContainer, Task> {
val checkSumTask = tasks.register("${zipTask.name}Checksum", Checksum::class) {
dependsOn(zipTask)
val compilerFile = zipTask.get().outputs.files.singleFile
files = files(compilerFile)
outputDir = compilerFile.parentFile
algorithm = Checksum.Algorithm.SHA256
}
val signTask = tasks.register("${zipTask.name}Sign", Sign::class) {
description = "Signs the archive produced by the '" + zipTask.name + "' task."
sign(zipTask.get())
}
return tasks.registering {
dependsOn(checkSumTask)
dependsOn(signTask)
}
}
signing {
useGpgCmd()
}
val zipCompilerWithSignature by secureZipTask(zipCompiler)
val zipPluginWithSignature by secureZipTask(zipPlugin)
configure<IdeaModel> {
module {
excludeDirs = files(
@@ -1109,15 +918,3 @@ val Jar.outputFile: File
val Project.sourceSetsOrNull: SourceSetContainer?
get() = convention.findPlugin(JavaPluginConvention::class.java)?.sourceSets
val disableVerificationTasks = System.getProperty("disable.verification.tasks") == "true"
if (disableVerificationTasks) {
gradle.taskGraph.whenReady {
allTasks.forEach {
if (it is VerificationTask) {
logger.info("DISABLED: '$it'")
it.enabled = false
}
}
}
}

View File

@@ -1,11 +1,10 @@
extra["versions.native-platform"] = "0.14"
buildscript {
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
extra["defaultSnapshotVersion"] = kotlinBuildProperties.defaultSnapshotVersion
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap(kotlinBuildProperties.kotlinBootstrapVersion!!, cacheRedirectorEnabled))
val buildSrcKotlinVersion: String by extra(findProperty("buildSrc.kotlin.version")?.toString() ?: embeddedKotlinVersion)
val buildSrcKotlinRepo: String? by extra(findProperty("buildSrc.kotlin.repo") as String?)
repositories {
if (cacheRedirectorEnabled) {
@@ -16,29 +15,27 @@ buildscript {
maven("https://kotlin.bintray.com/kotlin-dependencies")
}
project.bootstrapKotlinRepo?.let {
buildSrcKotlinRepo?.let {
maven(url = it)
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.19")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$buildSrcKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:$buildSrcKotlinVersion")
}
}
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
logger.info("buildSrcKotlinVersion: " + extra["bootstrapKotlinVersion"])
logger.info("buildSrcKotlinVersion: " + extra["buildSrcKotlinVersion"])
logger.info("buildSrc kotlin compiler version: " + org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)
logger.info("buildSrc stdlib version: " + KotlinVersion.CURRENT)
apply {
plugin("kotlin")
plugin("kotlin-sam-with-receiver")
from("../gradle/checkCacheability.gradle.kts")
}
plugins {
@@ -55,10 +52,6 @@ gradlePlugin {
}
}
kotlinDslPluginOptions {
experimentalWarning.set(false)
}
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
val v = it.toString()
if (v.isBlank()) true
@@ -72,6 +65,7 @@ rootProject.apply {
val isTeamcityBuild = kotlinBuildProperties.isTeamcityBuild
val intellijUltimateEnabled by extra(kotlinBuildProperties.intellijUltimateEnabled)
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
val verifyDependencyOutput by extra( getBooleanProperty("kotlin.build.dependency.output.verification") ?: isTeamcityBuild)
extra["intellijReleaseType"] = when {
extra["versions.intellijSdk"]?.toString()?.contains("-EAP-") == true -> "snapshots"
@@ -89,16 +83,14 @@ repositories {
maven("https://kotlin.bintray.com/kotlin-dependencies")
gradlePluginPortal()
extra["bootstrapKotlinRepo"]?.let {
extra["buildSrcKotlinRepo"]?.let {
maven(url = it)
}
}
dependencies {
implementation(kotlin("stdlib", embeddedKotlinVersion))
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.19")
implementation("com.gradle.publish:plugin-publish-plugin:0.11.0")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
implementation("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
@@ -106,8 +98,7 @@ dependencies {
implementation("com.jakewharton.dex:dex-method-list:3.0.0")
implementation("com.github.jengelman.gradle.plugins:shadow:${rootProject.extra["versions.shadow"]}")
implementation("net.sf.proguard:proguard-gradle:6.2.2")
implementation("org.jetbrains.intellij.deps:asm-all:8.0.1")
implementation("org.jetbrains.intellij.deps:asm-all:7.0.1")
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
}

View File

@@ -0,0 +1,8 @@
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
cacheRedirectorEnabled=true
#buildSrc.kotlin.repo=https://jcenter.bintray.com
#buildSrc.kotlin.version=1.1.50
intellijUltimateEnabled=false

View File

@@ -0,0 +1,8 @@
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
cacheRedirectorEnabled=true
#buildSrc.kotlin.repo=https://jcenter.bintray.com
#buildSrc.kotlin.version=1.1.50
intellijUltimateEnabled=false

View File

@@ -0,0 +1,8 @@
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
cacheRedirectorEnabled=true
#buildSrc.kotlin.repo=https://jcenter.bintray.com
#buildSrc.kotlin.version=1.1.50
intellijUltimateEnabled=false

View File

@@ -1,13 +1,11 @@
@file:Suppress("PropertyName", "HasPlatformType", "UnstableApiUsage")
import org.gradle.internal.os.OperatingSystem
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import java.io.Closeable
import java.io.FileWriter
import java.io.OutputStreamWriter
import java.net.URI
import java.text.SimpleDateFormat
import java.time.Duration
import java.time.Instant
import java.util.*
import javax.xml.stream.XMLOutputFactory
@@ -15,6 +13,7 @@ plugins {
base
}
val verifyDependencyOutput: Boolean by rootProject.extra
val intellijUltimateEnabled: Boolean by rootProject.extra
val intellijReleaseType: String by rootProject.extra
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
@@ -23,7 +22,7 @@ val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelea
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
val intellijSeparateSdks: Boolean by rootProject.extra
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
val installIntellijUltimate = intellijUltimateEnabled && androidStudioRelease == null
val installIntellijUltimate = intellijUltimateEnabled
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
if (intellijVersionDelimiterIndex == -1) {
@@ -32,6 +31,7 @@ if (intellijVersionDelimiterIndex == -1) {
val platformBaseVersion = intellijVersion.substring(0, intellijVersionDelimiterIndex)
logger.info("verifyDependencyOutput: $verifyDependencyOutput")
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
logger.info("intellijVersion: $intellijVersion")
logger.info("androidStudioRelease: $androidStudioRelease")
@@ -105,7 +105,7 @@ val nodeJSPlugin by configurations.creating
val intellijRuntimeAnnotations = "intellij-runtime-annotations"
val dependenciesDir = (findProperty("kotlin.build.dependencies.dir") as String?)?.let(::File)
?: rootProject.gradle.gradleUserHomeDir.resolve("kotlin-build-dependencies")
?: rootProject.rootDir.parentFile.resolve("dependencies")
val customDepsRepoDir = dependenciesDir.resolve("repo")
@@ -147,20 +147,14 @@ val makeIntellijCore = buildIvyRepositoryTask(intellijCore, customDepsOrg, custo
val makeIntellijAnnotations by tasks.registering(Copy::class) {
dependsOn(makeIntellijCore)
val intellijCoreRepo = CleanableStore[repoDir.resolve("intellij-core").absolutePath][intellijVersion].use()
from(intellijCoreRepo.resolve("artifacts/annotations.jar"))
from(repoDir.resolve("intellij-core/$intellijVersion/artifacts/annotations.jar"))
val annotationsStore = CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath]
val targetDir = annotationsStore[intellijVersion].use()
val targetDir = File(repoDir, "$intellijRuntimeAnnotations/$intellijVersion")
into(targetDir)
val ivyFile = File(targetDir, "$intellijRuntimeAnnotations.ivy.xml")
outputs.files(ivyFile)
doFirst {
annotationsStore.cleanStore()
}
doLast {
writeIvyXml(
customDepsOrg,
@@ -177,12 +171,7 @@ val makeIntellijAnnotations by tasks.registering(Copy::class) {
val mergeSources by tasks.creating(Jar::class.java) {
dependsOn(sources)
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
isZip64 = true
if (!kotlinBuildProperties.isTeamcityBuild) {
from(provider { sources.map(::zipTree) })
}
from(provider { sources.map(::zipTree) })
destinationDirectory.set(File(repoDir, sources.name))
archiveBaseName.set("intellij")
archiveClassifier.set("sources")
@@ -197,8 +186,8 @@ val makeIde = if (androidStudioBuild != null) {
customDepsOrg,
customDepsRepoDir,
if (androidStudioOs == "mac")
::skipContentsDirectory
else
::skipContentsDirectory
else
::skipToplevelDirectory
)
} else {
@@ -216,6 +205,7 @@ val makeIde = if (androidStudioBuild != null) {
}
val buildJpsStandalone = buildIvyRepositoryTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
val buildNodeJsPlugin = buildIvyRepositoryTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
tasks.named("build") {
dependsOn(
@@ -225,12 +215,15 @@ tasks.named("build") {
makeIntellijAnnotations
)
if (installIntellijUltimate) {
dependsOn(buildNodeJsPlugin)
}
}
if (installIntellijUltimate) {
val buildNodeJsPlugin =
buildIvyRepositoryTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
tasks.named("build") { dependsOn(buildNodeJsPlugin) }
// Task to delete legacy repo locations
tasks.register<Delete>("cleanLegacy") {
delete("$projectDir/android-dx")
delete("$projectDir/intellij-sdk")
}
tasks.named<Delete>("clean") {
@@ -243,96 +236,86 @@ fun buildIvyRepositoryTask(
repoDirectory: File,
pathRemap: ((String) -> String)? = null,
sources: File? = null
): TaskProvider<Task> {
fun ResolvedArtifact.storeDirectory(): CleanableStore =
CleanableStore[repoDirectory.resolve("$organization/${moduleVersion.id.name}").absolutePath]
) = tasks.register("buildIvyRepositoryFor${configuration.name.capitalize()}") {
fun ResolvedArtifact.moduleDirectory(): File =
storeDirectory()[moduleVersion.id.version].use()
File(repoDirectory, "$organization/${moduleVersion.id.name}/${moduleVersion.id.version}")
return tasks.register("buildIvyRepositoryFor${configuration.name.capitalize()}") {
dependsOn(configuration)
inputs.files(configuration)
dependsOn(configuration)
inputs.files(configuration)
if (verifyDependencyOutput) {
outputs.dir(provider {
configuration.resolvedConfiguration.resolvedArtifacts.single().moduleDirectory()
})
} else {
outputs.upToDateWhen {
configuration.resolvedConfiguration.resolvedArtifacts.single()
.moduleDirectory()
.exists()
}
}
doFirst {
val artifact = configuration.resolvedConfiguration.resolvedArtifacts.single()
val moduleDirectory = artifact.moduleDirectory()
doFirst {
configuration.resolvedConfiguration.resolvedArtifacts.single().run {
val moduleDirectory = moduleDirectory()
val artifactsDirectory = File(moduleDirectory(), "artifacts")
artifact.storeDirectory().cleanStore()
logger.info("Unpacking ${file.name} into ${artifactsDirectory.absolutePath}")
copy {
val fileTree = when (extension) {
"tar.gz" -> tarTree(file)
"zip" -> zipTree(file)
else -> error("Unsupported artifact extension: $extension")
}
if (moduleDirectory.exists()) {
logger.info("Path ${moduleDirectory.absolutePath} already exists, skipping unpacking.")
return@doFirst
from(fileTree.matching {
exclude("**/plugins/Kotlin/**")
})
into(artifactsDirectory)
if (pathRemap != null) {
eachFile {
path = pathRemap(path)
}
}
includeEmptyDirs = false
}
with(artifact) {
val artifactsDirectory = File(moduleDirectory, "artifacts")
logger.info("Unpacking ${file.name} into ${artifactsDirectory.absolutePath}")
copy {
val fileTree = when (extension) {
"tar.gz" -> tarTree(file)
"zip" -> zipTree(file)
else -> error("Unsupported artifact extension: $extension")
writeIvyXml(
organization,
moduleVersion.id.name,
moduleVersion.id.version,
moduleVersion.id.name,
File(artifactsDirectory, "lib"),
File(artifactsDirectory, "lib"),
File(moduleDirectory, "ivy"),
*listOfNotNull(sources).toTypedArray()
)
val pluginsDirectory = File(artifactsDirectory, "plugins")
if (pluginsDirectory.exists()) {
file(File(artifactsDirectory, "plugins"))
.listFiles { file: File -> file.isDirectory }
.forEach {
writeIvyXml(
organization,
it.name,
moduleVersion.id.version,
it.name,
File(it, "lib"),
File(it, "lib"),
File(moduleDirectory, "ivy"),
*listOfNotNull(sources).toTypedArray()
)
}
from(
fileTree.matching {
exclude("**/plugins/Kotlin/**")
}
)
into(artifactsDirectory)
if (pathRemap != null) {
eachFile {
path = pathRemap(path)
}
}
includeEmptyDirs = false
}
writeIvyXml(
organization,
moduleVersion.id.name,
moduleVersion.id.version,
moduleVersion.id.name,
File(artifactsDirectory, "lib"),
File(artifactsDirectory, "lib"),
File(moduleDirectory, "ivy"),
*listOfNotNull(sources).toTypedArray()
)
val pluginsDirectory = File(artifactsDirectory, "plugins")
if (pluginsDirectory.exists()) {
file(File(artifactsDirectory, "plugins"))
.listFiles { file: File -> file.isDirectory }
.forEach {
writeIvyXml(
organization,
it.name,
moduleVersion.id.version,
it.name,
File(it, "lib"),
File(it, "lib"),
File(moduleDirectory, "ivy"),
*listOfNotNull(sources).toTypedArray()
)
}
}
}
}
}
}
fun CleanableStore.cleanStore() = cleanDir(Instant.now().minus(Duration.ofDays(30)))
fun writeIvyXml(
organization: String,
moduleName: String,
@@ -352,7 +335,7 @@ fun writeIvyXml(
val ivyFile = targetDir.resolve("$fileName.ivy.xml")
ivyFile.parentFile.mkdirs()
with(XMLWriter(ivyFile.writer())) {
with(XMLWriter(FileWriter(ivyFile))) {
document("UTF-8", "1.0") {
element("ivy-module") {
attribute("version", "2.0")
@@ -376,19 +359,16 @@ fun writeIvyXml(
}
element("publications") {
artifactDir.listFiles()
?.filter(::shouldIncludeIntellijJar)
?.sortedBy { it.name.toLowerCase() }
?.forEach { jarFile ->
val relativeName = jarFile.toRelativeString(baseDir).removeSuffix(".jar")
emptyElement("artifact") {
attributes(
"name" to relativeName,
"type" to "jar",
"ext" to "jar",
"conf" to "default"
)
}
artifactDir.listFiles()?.filter(::shouldIncludeIntellijJar)?.forEach { jarFile ->
val relativeName = jarFile.toRelativeString(baseDir).removeSuffix(".jar")
emptyElement("artifact") {
attributes(
"name" to relativeName,
"type" to "jar",
"ext" to "jar",
"conf" to "default"
)
}
}
sourcesJar.forEach { jarFile ->

View File

@@ -20,13 +20,15 @@ buildscript {
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.19")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
}
}
def buildProperties = BuildPropertiesKt.getKotlinBuildPropertiesForSettings(settings)
def projectVersions = file("../gradle/versions.properties").text
BuildCacheKt.setupBuildCache(settings)
include "prepare-deps"
def target_AppCode_Clion = buildProperties.includeCidrPlugins && !projectVersions.contains("versions.androidStudioRelease")
@@ -37,12 +39,9 @@ if (target_AppCode_Clion) {
logger.info("Including modules for AC and CL in buildSrc/settings.gradle")
include ":prepare-deps:kotlin-native-platform-deps"
include ":prepare-deps:native-debug-plugin"
project(":prepare-deps:kotlin-native-platform-deps").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/kotlin-native-platform-deps")
project(":prepare-deps:native-debug-plugin").projectDir =
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/native-debug-plugin")
} else if (target_AndroidStudio) {
logger.info("Including modules for AS (mobile plugin) in buildSrc/settings.gradle")

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
import org.gradle.api.GradleException
import org.gradle.api.tasks.*
import org.gradle.api.tasks.testing.Test
import java.io.File
// You can see "How To" via link: https://jetbrains.quip.com/xQ2WAUy9bZmy/How-to-use-AggregateTest-task
open class AggregateTest : Test() { // Inherit from Test to see test results in IDEA Test viewer
private var patterns: MutableMap<String, MutableList<String>> = mutableMapOf()
@InputFile
lateinit var testPatternFile: File
init {
// Set empty FileCollection to avoid NPE when initializing a base 'Test' class
classpath = project.objects.fileCollection()
testClassesDirs = project.objects.fileCollection()
project.gradle.taskGraph.whenReady {
if (allTasks.filterIsInstance<AggregateTest>().isNotEmpty()) {
initPatterns()
allTasks.filterIsInstance<Test>().forEach { testTask -> subTaskConfigure(testTask) }
if (!project.gradle.startParameter.taskNames.all { project.tasks.findByPath(it) is AggregateTest }) {
logger.warn("Please, don't use AggregateTest and non-AggregateTest test tasks together. You can get incorrect results.")
}
}
}
}
private fun initPatterns() {
if (!testPatternFile.exists())
throw GradleException("File with test patterns is not found")
testPatternFile
.readLines()
.asSequence()
.filter { it.isNotEmpty() }
.forEach { line ->
// patternType is exclude or include value
val (pattern, patternType) = line.split(',').map { it.trim() }
patterns.getOrPut(patternType) { mutableListOf() }.add(pattern)
}
}
private fun subTaskConfigure(testTask: Test) {
testTask.outputs.upToDateWhen { false }
testTask.ignoreFailures = true
testTask.filter {
isFailOnNoMatchingTests = false
patterns["include"]?.let {
it.forEach { pattern ->
includeTestsMatching(pattern)
}
}
patterns["exclude"]?.let {
it.forEach { pattern ->
excludeTestsMatching(pattern)
}
}
}
}
@Override
@TaskAction
override fun executeTests() {
// Do nothing
}
}

View File

@@ -0,0 +1,114 @@
@file:Suppress("unused") // usages in build scripts are not tracked properly
import org.gradle.api.Project
import org.gradle.kotlin.dsl.*
import java.net.URI
var Project.bootstrapKotlinVersion: String
get() = this.property("bootstrapKotlinVersion") as String
private set(value) {
this.extra["bootstrapKotlinVersion"] = value
}
var Project.bootstrapKotlinRepo: String?
get() = this.property("bootstrapKotlinRepo") as String?
private set(value) {
this.extra["bootstrapKotlinRepo"] = value
}
val Project.internalKotlinRepo: String?
get() = "https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:$bootstrapKotlinVersion," +
"branch:default:any/artifacts/content/internal/repo"
fun Project.kotlinBootstrapFrom(defaultSource: BootstrapOption) {
val customVersion = project.findProperty("bootstrap.kotlin.version") as String?
val customRepo = project.findProperty("bootstrap.kotlin.repo") as String?
val teamCityVersion = project.findProperty("bootstrap.teamcity.kotlin.version") as String?
val teamCityBuild = project.findProperty("bootstrap.teamcity.build.number") as String?
val teamCityProject = project.findProperty("bootstrap.teamcity.project") as String?
val bootstrapSource = when {
project.hasProperty("bootstrap.local") -> BootstrapOption.Local(
project.findProperty("bootstrap.local.version") as String?,
project.findProperty("bootstrap.local.path") as String?
)
teamCityVersion != null -> BootstrapOption.TeamCity(
teamCityVersion,
teamCityBuild,
projectExtId = teamCityProject,
onlySuccessBootstrap = false
)
customVersion != null -> BootstrapOption.Custom(kotlinVersion = customVersion, repo = customRepo)
else -> defaultSource
}
bootstrapSource.applyToProject(project)
project.logger.lifecycle("Using kotlin bootstrap version $bootstrapKotlinVersion from repo $bootstrapKotlinRepo")
}
sealed class BootstrapOption {
abstract fun applyToProject(project: Project)
/** Manual repository and version specification.
*
* If [repo] is not specified the default buildscript and project repositories are used
*/
open class Custom(val kotlinVersion: String, val repo: String?, val cacheRedirector: Boolean = false) : BootstrapOption() {
override fun applyToProject(project: Project) {
project.bootstrapKotlinVersion = kotlinVersion
project.bootstrapKotlinRepo = if (cacheRedirector)
repo?.let { URI(it) }?.let { "https://cache-redirector.jetbrains.com/${it.host}/${it.path}" }
else
repo
}
}
/** Get bootstrap from kotlin-dev bintray repo */
class BintrayDev(kotlinVersion: String, cacheRedirector: Boolean = false) :
Custom(kotlinVersion, "https://dl.bintray.com/kotlin/kotlin-dev", cacheRedirector)
/** Get bootstrap from kotlin-bootstrap bintray repo, where bootstraps are published */
class BintrayBootstrap(kotlinVersion: String, cacheRedirector: Boolean = false) :
Custom(kotlinVersion, "https://dl.bintray.com/kotlin/kotlin-bootstrap", cacheRedirector)
/** Get bootstrap from teamcity maven artifacts of the specified build configuration
*
* [kotlinVersion] the version of maven artifacts
* [buildNumber] build number of a teamcity build, by default the same as [kotlinVersion],
* [projectExtId] extId of a teamcity build configuration, by default "Kotlin_dev_Compiler",
* [onlySuccessBootstrap] allow artifacts only from success builds of the default branch tagged with 'bootstrap' tag
*/
class TeamCity(
val kotlinVersion: String,
val buildNumber: String? = null,
val projectExtId: String? = null,
val onlySuccessBootstrap: Boolean = true,
val teamcityUrl: String = "https://teamcity.jetbrains.com"
) : BootstrapOption() {
override fun applyToProject(project: Project) {
val query = if (onlySuccessBootstrap) "status:SUCCESS,tag:bootstrap,pinned:true" else "branch:default:any"
project.bootstrapKotlinRepo = "$teamcityUrl/guestAuth/app/rest/builds/buildType:(id:${projectExtId
?: "Kotlin_dev_Compiler"}),number:${buildNumber ?: kotlinVersion},$query/artifacts/content/maven/"
project.bootstrapKotlinVersion = kotlinVersion
}
}
/**
* Use previously published local artifacts from the build/repo maven repository
*
* [kotlinVersion] version of artifacts, by default the snapshot version of project is used
* [localPath] the path to local repository, if specified it is resolved with respect or project dir
*/
class Local(val kotlinVersion: String? = null, val localPath: String? = null) : BootstrapOption() {
override fun applyToProject(project: Project) {
val repoPath = if (localPath != null)
project.projectDir.resolve(localPath).canonicalFile
else
project.buildDir.resolve("repo")
project.bootstrapKotlinRepo = repoPath.toURI().toString()
project.bootstrapKotlinVersion = kotlinVersion ?: project.property("defaultSnapshotVersion") as String
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
val KotlinBuildProperties.includeJava9: Boolean
get() = !isInJpsBuildIdeaSync && getBoolean("kotlin.build.java9", true)
val KotlinBuildProperties.useBootstrapStdlib: Boolean
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
val KotlinBuildProperties.postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
val KotlinBuildProperties.relocation: Boolean get() = postProcessing
val KotlinBuildProperties.proguard: Boolean get() = postProcessing && getBoolean("kotlin.build.proguard", isTeamcityBuild)
val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.build.jar.compression", isTeamcityBuild)
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)

View File

@@ -1,385 +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 groovy.lang.Closure
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.*
import org.gradle.internal.jvm.Jvm
import org.gradle.internal.jvm.inspection.JvmVersionDetector
import proguard.ClassSpecification
import java.io.File
import javax.inject.Inject
@CacheableTask
open class CacheableProguardTask @Inject constructor(
private val jvmVersionDetector: JvmVersionDetector
) : proguard.gradle.ProGuardTask() {
@Internal
var jdkHome: File? = null
@get:Optional
@get:Input
internal val jdkMajorVersion: String?
get() = jdkHome?.let { jvmVersionDetector.getJavaVersion(Jvm.forHome(jdkHome)) }?.majorVersion
@CompileClasspath
override fun getLibraryJarFileCollection(): FileCollection = super.getLibraryJarFileCollection().filter { libraryFile ->
jdkHome?.let { !libraryFile.absoluteFile.startsWith(it.absoluteFile) } ?: true
}
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
override fun getConfigurationFileCollection(): FileCollection = super.getConfigurationFileCollection()
@InputFiles
@Classpath
override fun getInJarFileCollection(): FileCollection = super.getInJarFileCollection()
@Optional
@OutputFiles
override fun getOutJarFileCollection(): FileCollection = super.getOutJarFileCollection()
@get:Optional
@get:OutputFile
internal val printConfigurationFile: File?
get() = configuration.printConfiguration?.takeIf { it.path.isNotEmpty() }
@Input
override fun getOutJarFilters(): MutableList<Any?> = super.getOutJarFilters()
@Input
override fun getInJarFilters(): MutableList<Any?> = super.getInJarFilters()
@Input
override fun getLibraryJarFilters(): MutableList<Any?> = super.getLibraryJarFilters()
@Internal
override fun getOutJarFiles(): MutableList<Any?> = super.getOutJarFiles()
@Internal
override fun getInJarFiles(): MutableList<Any?> = super.getInJarFiles()
@Internal
override fun getInJarCounts(): MutableList<Any?> = super.getInJarCounts()
@Internal
override fun getLibraryJarFiles(): MutableList<Any?> = super.getLibraryJarFiles()
/*
* Inputs properly declared these methods so we don't override them
*
* configuration(configurationFiles: Any?)
* libraryjars(libraryJarFiles: Any?)
* libraryjars(filterArgs: MutableMap<Any?, Any?>?, libraryJarFiles: Any?)
* injars(inJarFiles: Any?)
* injars(filterArgs: MutableMap<Any?, Any?>?, inJarFiles: Any?)
* outjars(outJarFiles: Any?)
* outjars(filterArgs: MutableMap<Any?, Any?>?, outJarFiles: Any?)
* printconfiguration()
* printconfiguration(printConfiguration: Any?)
*/
override fun renamesourcefileattribute() = throw NotImplementedError()
override fun renamesourcefileattribute(newSourceFileAttribute: String?) = throw NotImplementedError()
override fun dontshrink() = throw NotImplementedError()
override fun assumenosideeffects(classSpecificationString: String?) = throw NotImplementedError()
override fun assumenosideeffects(classSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun keepnames(classSpecificationString: String?) = throw NotImplementedError()
override fun keepnames(keepArgs: MutableMap<Any?, Any?>?, classSpecificationString: String?) = throw NotImplementedError()
override fun keepnames(keepClassSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun keepnames(keepClassSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun printmapping() = throw NotImplementedError()
override fun printmapping(printMapping: Any?) = throw NotImplementedError()
override fun keep(classSpecificationString: String?) = throw NotImplementedError()
override fun keep(keepArgs: MutableMap<Any?, Any?>?, classSpecificationString: String?) = throw NotImplementedError()
override fun keep(keepClassSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun keep(keepClassSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun keepdirectories() = throw NotImplementedError()
override fun keepdirectories(filter: String?) = throw NotImplementedError()
override fun dontpreverify() = throw NotImplementedError()
override fun dontnote() = throw NotImplementedError()
override fun dontnote(filter: String?) = throw NotImplementedError()
@Internal
override fun getrenamesourcefileattribute(): Any? = throw NotImplementedError()
override fun useuniqueclassmembernames() = throw NotImplementedError()
override fun overloadaggressively() = throw NotImplementedError()
@Internal
override fun getprintusage(): Any? = throw NotImplementedError()
@Internal
override fun getforceprocessing(): Any? = throw NotImplementedError()
override fun whyareyoukeeping(classSpecificationString: String?) = throw NotImplementedError()
override fun whyareyoukeeping(classSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun whyareyoukeeping(classSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun obfuscationdictionary(obfuscationDictionary: Any?) = throw NotImplementedError()
override fun adaptclassstrings() = throw NotImplementedError()
override fun adaptclassstrings(filter: String?) = throw NotImplementedError()
override fun applymapping(applyMapping: Any?) = throw NotImplementedError()
override fun mergeinterfacesaggressively() = throw NotImplementedError()
@Internal
override fun getdontwarn(): Any? = throw NotImplementedError()
override fun ignorewarnings() = throw NotImplementedError()
@Internal
override fun getaddconfigurationdebugging(): Any? = throw NotImplementedError()
override fun field(memberSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
@Internal
override fun getallowaccessmodification(): Any? = throw NotImplementedError()
override fun constructor(memberSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun dontusemixedcaseclassnames() = throw NotImplementedError()
@Internal
override fun getignorewarnings(): Any? = throw NotImplementedError()
@Internal
override fun getkeepdirectories(): Any? = throw NotImplementedError()
override fun classobfuscationdictionary(classObfuscationDictionary: Any?) = throw NotImplementedError()
override fun verbose() = throw NotImplementedError()
override fun optimizations(filter: String?) = throw NotImplementedError()
@Internal
override fun getuseuniqueclassmembernames(): Any? = throw NotImplementedError()
@Internal
override fun getmicroedition(): Any? = throw NotImplementedError()
override fun assumenoescapingparameters(classSpecificationString: String?) = throw NotImplementedError()
override fun assumenoescapingparameters(classSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
@Internal
override fun getandroid(): Any? = throw NotImplementedError()
override fun keeppackagenames() = throw NotImplementedError()
override fun keeppackagenames(filter: String?) = throw NotImplementedError()
@Internal
override fun getoverloadaggressively(): Any? = throw NotImplementedError()
override fun skipnonpubliclibraryclasses() = throw NotImplementedError()
@Internal
override fun getdontusemixedcaseclassnames(): Any? = throw NotImplementedError()
@Internal
override fun getdontnote(): Any? = throw NotImplementedError()
override fun assumenoexternalreturnvalues(classSpecificationString: String?) = throw NotImplementedError()
override fun assumenoexternalreturnvalues(classSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun target(targetClassVersion: String?) = throw NotImplementedError()
override fun keepattributes() = throw NotImplementedError()
override fun keepattributes(filter: String?) = throw NotImplementedError()
override fun keepclassmembernames(classSpecificationString: String?) = throw NotImplementedError()
override fun keepclassmembernames(keepArgs: MutableMap<Any?, Any?>?, classSpecificationString: String?) = throw NotImplementedError()
override fun keepclassmembernames(keepClassSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun keepclassmembernames(keepClassSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
@Internal
override fun getdontpreverify(): Any? = throw NotImplementedError()
@Internal
override fun getverbose(): Any? = throw NotImplementedError()
@Internal
override fun getskipnonpubliclibraryclasses(): Any? = throw NotImplementedError()
@Internal
override fun getdontoptimize(): Any? = throw NotImplementedError()
override fun keepclasseswithmembernames(classSpecificationString: String?) = throw NotImplementedError()
override fun keepclasseswithmembernames(keepArgs: MutableMap<Any?, Any?>?, classSpecificationString: String?) = throw NotImplementedError()
override fun keepclasseswithmembernames(keepClassSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun keepclasseswithmembernames(keepClassSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun keepclasseswithmembers(classSpecificationString: String?) = throw NotImplementedError()
override fun keepclasseswithmembers(keepArgs: MutableMap<Any?, Any?>?, classSpecificationString: String?) = throw NotImplementedError()
override fun keepclasseswithmembers(keepClassSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun keepclasseswithmembers(keepClassSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
@Internal
override fun getdump(): Any? = throw NotImplementedError()
override fun printseeds() = throw NotImplementedError()
override fun printseeds(printSeeds: Any?) = throw NotImplementedError()
override fun dontoptimize() = throw NotImplementedError()
override fun dontobfuscate() = throw NotImplementedError()
override fun extendClassSpecifications(
classSpecifications: MutableList<Any?>?,
classSpecification: ClassSpecification?
): MutableList<Any?> = throw NotImplementedError()
override fun allowaccessmodification() = throw NotImplementedError()
@Internal
override fun getdontobfuscate(): Any? = throw NotImplementedError()
@Internal
override fun getprintmapping(): Any? = throw NotImplementedError()
override fun flattenpackagehierarchy() = throw NotImplementedError()
override fun flattenpackagehierarchy(flattenPackageHierarchy: String?) = throw NotImplementedError()
override fun android() = throw NotImplementedError()
override fun dump() = throw NotImplementedError()
override fun dump(dump: Any?) = throw NotImplementedError()
@Internal
override fun getdontshrink(): Any? = throw NotImplementedError()
@Internal
override fun getkeepattributes(): Any? = throw NotImplementedError()
override fun microedition() = throw NotImplementedError()
override fun keepparameternames() = throw NotImplementedError()
override fun addconfigurationdebugging() = throw NotImplementedError()
override fun packageobfuscationdictionary(packageObfuscationDictionary: Any?) = throw NotImplementedError()
@Internal
override fun getdontskipnonpubliclibraryclassmembers(): Any? = throw NotImplementedError()
override fun dontskipnonpubliclibraryclassmembers() = throw NotImplementedError()
@Internal
override fun getprintconfiguration(): Any? = throw NotImplementedError()
override fun forceprocessing() = throw NotImplementedError()
override fun keepclassmembers(classSpecificationString: String?) = throw NotImplementedError()
override fun keepclassmembers(keepArgs: MutableMap<Any?, Any?>?, classSpecificationString: String?) = throw NotImplementedError()
override fun keepclassmembers(keepClassSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
override fun keepclassmembers(keepClassSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
@Internal
override fun getmergeinterfacesaggressively(): Any? = throw NotImplementedError()
@Internal
override fun getConfigurationFiles(): MutableList<Any?> = throw NotImplementedError()
@Internal
override fun getkeeppackagenames(): Any? = throw NotImplementedError()
override fun assumevalues(classSpecificationString: String?) = throw NotImplementedError()
override fun assumevalues(classSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun printusage() = throw NotImplementedError()
override fun printusage(printUsage: Any?) = throw NotImplementedError()
@Internal
override fun getprintseeds(): Any? = throw NotImplementedError()
@Internal
override fun getadaptresourcefilenames(): Any? = throw NotImplementedError()
override fun assumenoexternalsideeffects(classSpecificationString: String?) = throw NotImplementedError()
override fun assumenoexternalsideeffects(classSpecificationArgs: MutableMap<Any?, Any?>?, classMembersClosure: Closure<*>?) = throw NotImplementedError()
override fun dontwarn() = throw NotImplementedError()
override fun dontwarn(filter: String?) = throw NotImplementedError()
@Internal
override fun getrepackageclasses(): Any? = throw NotImplementedError()
@Internal
override fun getadaptresourcefilecontents(): Any? = throw NotImplementedError()
@Internal
override fun getflattenpackagehierarchy(): Any? = throw NotImplementedError()
override fun optimizationpasses(optimizationPasses: Int) = throw NotImplementedError()
override fun adaptresourcefilenames() = throw NotImplementedError()
override fun adaptresourcefilenames(filter: String?) = throw NotImplementedError()
override fun method(memberSpecificationArgs: MutableMap<Any?, Any?>?) = throw NotImplementedError()
@Internal
override fun getadaptclassstrings(): Any? = throw NotImplementedError()
override fun repackageclasses() = throw NotImplementedError()
override fun repackageclasses(repackageClasses: String?) = throw NotImplementedError()
@Internal
override fun getkeepparameternames(): Any? = throw NotImplementedError()
override fun adaptresourcefilecontents() = throw NotImplementedError()
override fun adaptresourcefilecontents(filter: String?) = throw NotImplementedError()
}

View File

@@ -7,12 +7,10 @@ import org.gradle.api.Task
import org.gradle.api.file.CopySourceSpec
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.SourceSetOutput
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.kotlin.dsl.*
import proguard.gradle.ProGuardTask
import java.io.File
import java.util.concurrent.Callable
@@ -56,9 +54,8 @@ var Project.javaHome: String?
fun Project.generator(fqName: String, sourceSet: SourceSet? = null) = smartJavaExec {
classpath = (sourceSet ?: testSourceSet).runtimeClasspath
mainClass.set(fqName)
main = fqName
workingDir = rootDir
systemProperty("line.separator", "\n")
}
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
@@ -72,11 +69,3 @@ inline fun CopySourceSpec.from(crossinline filesProvider: () -> Any?): CopySourc
fun Project.javaPluginConvention(): JavaPluginConvention = the()
fun Project.findJavaPluginConvention(): JavaPluginConvention? = convention.findByType() ?: convention.findPlugin()
fun JavaExec.pathRelativeToWorkingDir(file: File): String = file.relativeTo(workingDir).invariantSeparatorsPath
fun Task.singleOutputFile(): File = when (this) {
is AbstractArchiveTask -> archiveFile.get().asFile
is ProGuardTask -> project.file(outJarFiles.single()!!)
else -> outputs.files.singleFile
}

View File

@@ -26,12 +26,10 @@ fun CompatibilityPredicate.or(other: CompatibilityPredicate): CompatibilityPredi
}
enum class Platform : CompatibilityPredicate {
P183, P191, P192, P193, P201, P202, P203;
P183, P191, P192, P193, P201;
val version: Int = name.drop(1).toInt()
val displayVersion: String = "20${name.drop(1).dropLast(1)}.${name.last()}"
override fun matches(ide: Ide) = ide.platform == this
companion object {
@@ -47,22 +45,14 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
IJ192(Platform.P192),
IJ193(Platform.P193),
IJ201(Platform.P201),
IJ202(Platform.P202),
IJ203(Platform.P203),
AS35(Platform.P183),
AS36(Platform.P192),
AS40(Platform.P193),
AS41(Platform.P201);
AS40(Platform.P193);
val kind = Kind.values().first { it.shortName == name.take(2) }
val version = name.dropWhile { !it.isDigit() }.toInt()
val displayVersion: String = when (kind) {
Kind.IntelliJ -> "IJ${platform.displayVersion}"
Kind.AndroidStudio -> "Studio${name.substringAfter("AS").toCharArray().joinToString(separator = ".")}"
}
override fun matches(ide: Ide) = ide == this
enum class Kind(val shortName: String) {

View File

@@ -23,10 +23,6 @@ fun JavaExec.passClasspathInJar() {
dependsOn(classpath)
inputs.files(classpath)
inputs.property("main", main)
archiveFileName.set("$main.${this@passClasspathInJar.name}.classpath.container.jar")
destinationDirectory.set(temporaryDir)
doFirst {
val classPathString = classpath.joinToString(" ") { project.file(it).toURI().toString() }
manifest {
@@ -38,11 +34,16 @@ fun JavaExec.passClasspathInJar() {
)
}
}
archiveName = "$main.${this@passClasspathInJar.name}.classpath.container.$extension"
destinationDir = temporaryDir
}
dependsOn(jarTask)
main = "-jar"
classpath = project.files()
args = listOf(jarTask.outputs.files.singleFile.path) + args.orEmpty()
doFirst {
main = "-jar"
classpath = project.files()
args = listOf(jarTask.outputs.files.singleFile.path) + args.orEmpty()
}
}

View File

@@ -6,29 +6,14 @@ import org.gradle.api.Task
import org.gradle.api.artifacts.ConfigurablePublishArtifact
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.PublishArtifact
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.LibraryElements
import org.gradle.api.attributes.Usage
import org.gradle.api.component.AdhocComponentWithVariants
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.plugins.BasePluginConvention
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPlugin.*
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.tasks.GenerateModuleMetadata
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.Upload
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetContainer
import plugins.KotlinBuildPublishingPlugin
private const val MAGIC_DO_NOT_CHANGE_TEST_JAR_TASK_NAME = "testJar"
@@ -41,7 +26,7 @@ fun Project.testsJar(body: Jar.() -> Unit = {}): Jar {
pluginManager.withPlugin("java") {
from(testSourceSet.output)
}
archiveClassifier.set("tests")
classifier = "tests"
body()
project.addArtifact(testsJarCfg, this, this)
}
@@ -71,26 +56,18 @@ fun Project.noDefaultJar() {
}
}
fun <T : Task> Project.runtimeJarArtifactBy(
task: TaskProvider<T>,
artifactRef: Any,
body: ConfigurablePublishArtifact.() -> Unit = {}
) {
fun Project.runtimeJarArtifactBy(task: Task, artifactRef: Any, body: ConfigurablePublishArtifact.() -> Unit = {}) {
addArtifact("archives", task, artifactRef, body)
addArtifact("runtimeJar", task, artifactRef, body)
configurations.findByName("runtime")?.let {
addArtifact(it.name, task, artifactRef, body)
addArtifact(it, task, artifactRef, body)
}
}
fun Project.runtimeJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> = runtimeJar(getOrCreateTask("jar", body)) { }
fun <T : Jar> Project.runtimeJar(task: TaskProvider<T>, body: T.() -> Unit = {}): TaskProvider<T> {
tasks.named<Jar>("jar").configure {
removeArtifacts(configurations.getOrCreate("archives"), this)
}
task.configure {
configurations.findByName("embedded")?.let { embedded ->
dependsOn(embedded)
@@ -99,47 +76,21 @@ fun <T : Jar> Project.runtimeJar(task: TaskProvider<T>, body: T.() -> Unit = {})
}
}
setupPublicJar(project.the<BasePluginConvention>().archivesBaseName)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
body()
project.runtimeJarArtifactBy(this, this)
}
project.runtimeJarArtifactBy(task, task)
val runtimeJar = configurations.maybeCreate("runtimeJar").apply {
isCanBeConsumed = true
isCanBeResolved = false
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
}
}
configurePublishedComponent {
withVariantsFromConfiguration(configurations[RUNTIME_ELEMENTS_CONFIGURATION_NAME]) { skip() }
addVariantsFromConfiguration(runtimeJar) { }
}
return task
}
fun Project.runtimeJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> = runtimeJar(getOrCreateTask("jar", body), { })
fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
configure<JavaPluginExtension> {
withSourcesJar()
}
val sourcesJar = getOrCreateTask<Jar>("sourcesJar") {
fun Project.mainJavaPluginSourceSet() = findJavaPluginConvention()?.sourceSets?.findByName("main")
fun Project.mainKotlinSourceSet() =
(extensions.findByName("kotlin") as? KotlinSourceSetContainer)?.sourceSets?.findByName("main")
fun Project.sources() = mainJavaPluginSourceSet()?.allSource ?: mainKotlinSourceSet()?.kotlin
val task = tasks.register<Jar>("sourcesJar") {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveClassifier.set("sources")
from(project.sources())
from(project.mainSourceSet.allSource)
project.configurations.findByName("embedded")?.let { embedded ->
from(provider {
@@ -148,7 +99,10 @@ fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
.map { it.id.componentIdentifier }
.filterIsInstance<ProjectComponentIdentifier>()
.mapNotNull {
project(it.projectPath).sources()
project(it.projectPath)
.findJavaPluginConvention()
?.mainSourceSet
?.allSource
}
})
}
@@ -156,21 +110,13 @@ fun Project.sourcesJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
body()
}
addArtifact("archives", sourcesJar)
addArtifact("sources", sourcesJar)
addArtifact("archives", task)
addArtifact("sources", task)
configurePublishedComponent {
addVariantsFromConfiguration(configurations[SOURCES_ELEMENTS_CONFIGURATION_NAME]) { }
}
return sourcesJar
return task
}
fun Project.javadocJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
configure<JavaPluginExtension> {
withJavadocJar()
}
val javadocTask = getOrCreateTask<Jar>("javadocJar") {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveClassifier.set("javadoc")
@@ -182,40 +128,9 @@ fun Project.javadocJar(body: Jar.() -> Unit = {}): TaskProvider<Jar> {
}
addArtifact("archives", javadocTask)
configurePublishedComponent {
addVariantsFromConfiguration(configurations[JAVADOC_ELEMENTS_CONFIGURATION_NAME]) { }
}
return javadocTask
}
fun Project.modularJar(body: Jar.() -> Unit): TaskProvider<Jar> {
val modularJar = configurations.maybeCreate("modularJar").apply {
isCanBeConsumed = true
isCanBeResolved = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named("modular-jar"))
}
}
val modularJarTask = getOrCreateTask<Jar>("modularJar") {
archiveClassifier.set("modular")
body()
}
addArtifact("modularJar", modularJarTask)
addArtifact("archives", modularJarTask)
configurePublishedComponent {
addVariantsFromConfiguration(modularJar) { mapToMavenScope("runtime") }
}
return modularJarTask
}
fun Project.standardPublicJars() {
runtimeJar()
@@ -223,22 +138,7 @@ fun Project.standardPublicJars() {
javadocJar()
}
fun Project.publish(moduleMetadata: Boolean = false, configure: MavenPublication.() -> Unit = { }) {
apply<KotlinBuildPublishingPlugin>()
if (!moduleMetadata) {
tasks.withType<GenerateModuleMetadata> {
enabled = false
}
}
val publication = extensions.findByType<PublishingExtension>()
?.publications
?.findByName(KotlinBuildPublishingPlugin.PUBLICATION_NAME) as MavenPublication
publication.configure()
}
fun Project.publishWithLegacyMavenPlugin(body: Upload.() -> Unit = {}): Upload {
fun Project.publish(body: Upload.() -> Unit = {}): Upload {
apply<plugins.PublishedKotlinModule>()
if (artifactsRemovedDiagnosticFlag) {
@@ -255,87 +155,12 @@ fun Project.publishWithLegacyMavenPlugin(body: Upload.() -> Unit = {}): Upload {
}
}
fun Project.idePluginDependency(block: () -> Unit) {
val shouldActivate = rootProject.findProperty("publish.ide.plugin.dependencies")?.toString()?.toBoolean() == true
if (shouldActivate) {
block()
}
}
fun Project.publishProjectJars(projects: List<String>, libraryDependencies: List<String> = emptyList()) {
apply<JavaPlugin>()
val fatJarContents by configurations.creating
dependencies {
for (projectName in projects) {
fatJarContents(project(projectName)) { isTransitive = false }
}
for (libraryDependency in libraryDependencies) {
fatJarContents(libraryDependency)
}
}
publish()
val jar: Jar by tasks
jar.apply {
dependsOn(fatJarContents)
from {
fatJarContents.map(::zipTree)
}
}
sourcesJar {
from {
projects.map {
project(it).mainSourceSet.allSource
}
}
}
javadocJar()
}
fun Project.publishTestJar(projectName: String) {
apply<JavaPlugin>()
val fatJarContents by configurations.creating
dependencies {
fatJarContents(project(projectName, configuration = "tests-jar")) { isTransitive = false }
}
publish()
val jar: Jar by tasks
jar.apply {
dependsOn(fatJarContents)
from {
fatJarContents.map(::zipTree)
}
}
sourcesJar {
from {
project(projectName).testSourceSet.allSource
}
}
javadocJar()
}
fun ConfigurationContainer.getOrCreate(name: String): Configuration = findByName(name) ?: create(name)
fun Jar.setupPublicJar(baseName: String, classifier: String = "") {
val buildNumber = project.rootProject.extra["buildNumber"] as String
this.archiveBaseName.set(baseName)
this.archiveClassifier.set(classifier)
this.baseName = baseName
this.classifier = classifier
manifest.attributes.apply {
put("Implementation-Vendor", "JetBrains")
put("Implementation-Title", baseName)
@@ -354,26 +179,9 @@ fun Project.addArtifact(configuration: Configuration, task: Task, artifactRef: A
fun Project.addArtifact(configurationName: String, task: Task, artifactRef: Any, body: ConfigurablePublishArtifact.() -> Unit = {}) =
addArtifact(configurations.getOrCreate(configurationName), task, artifactRef, body)
fun <T : Task> Project.addArtifact(
configurationName: String,
task: TaskProvider<T>,
body: ConfigurablePublishArtifact.() -> Unit = {}
): PublishArtifact {
fun <T : Task> Project.addArtifact(configurationName: String, task: TaskProvider<T>, body: ConfigurablePublishArtifact.() -> Unit = {}) {
configurations.maybeCreate(configurationName)
return artifacts.add(configurationName, task, body)
}
fun <T : Task> Project.addArtifact(
configurationName: String,
task: TaskProvider<T>,
artifactRef: Any,
body: ConfigurablePublishArtifact.() -> Unit = {}
): PublishArtifact {
configurations.maybeCreate(configurationName)
return artifacts.add(configurationName, artifactRef) {
builtBy(task)
body()
}
artifacts.add(configurationName, task, body)
}
fun Project.cleanArtifacts() {
@@ -383,6 +191,3 @@ fun Project.cleanArtifacts() {
}
}
}
fun Project.configurePublishedComponent(configure: AdhocComponentWithVariants.() -> Unit) =
(components.findByName(KotlinBuildPublishingPlugin.ADHOC_COMPONENT_NAME) as AdhocComponentWithVariants?)?.apply(configure)

View File

@@ -1,18 +1,15 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("unused")
// usages in build scripts are not tracked properly
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.GradleException
import org.gradle.api.Project
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.api.tasks.AbstractCopyTask
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.project
import java.io.File
@@ -27,15 +24,6 @@ val Project.intellijRepo get() =
else -> "https://www.jetbrains.com/intellij-repository/releases"
}
val Project.internalBootstrapRepo: String? get() =
when {
bootstrapKotlinRepo?.startsWith("https://buildserver.labs.intellij.net") == true ->
bootstrapKotlinRepo!!.replace("artifacts/content/maven", "artifacts/content/internal/repo")
else -> "https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:$bootstrapKotlinVersion," +
"branch:default:any/artifacts/content/internal/repo/"
}
fun Project.commonDep(coord: String): String {
val parts = coord.split(':')
return when (parts.size) {
@@ -102,11 +90,9 @@ fun Project.kotlinStdlib(suffix: String? = null, classifier: String? = null): An
dependencies.project(listOfNotNull(":kotlin-stdlib", suffix).joinToString("-"), classifier)
}
fun Project.kotlinBuiltins(): Any = kotlinBuiltins(forJvm = false)
fun Project.kotlinBuiltins(forJvm: Boolean): Any =
fun Project.kotlinBuiltins(): Any =
if (kotlinBuildProperties.useBootstrapStdlib) "org.jetbrains.kotlin:builtins:$bootstrapKotlinVersion"
else dependencies.project(":core:builtins", configuration = "runtimeElementsJvm".takeIf { forJvm })
else dependencies.project(":core:builtins")
fun DependencyHandler.projectTests(name: String): ProjectDependency = project(name, configuration = "tests-jar")
fun DependencyHandler.projectRuntimeJar(name: String): ProjectDependency = project(name, configuration = "runtimeJar")

View File

@@ -11,19 +11,17 @@ import java.io.File
val kotlinEmbeddableRootPackage = "org.jetbrains.kotlin"
val packagesToRelocate =
listOf(
"com.intellij",
"com.google",
"com.sampullara",
"org.apache",
"org.jdom",
"org.picocontainer",
"org.jline",
"org.fusesource",
"net.jpountz",
"one.util.streamex",
"kotlinx.collections.immutable"
)
listOf( "com.intellij",
"com.google",
"com.sampullara",
"org.apache",
"org.jdom",
"org.picocontainer",
"org.jline",
"org.fusesource",
"kotlinx.coroutines",
"net.jpountz",
"one.util.streamex")
// The shaded compiler "dummy" is used to rewrite dependencies in projects that are used with the embeddable compiler
// on the runtime and use some shaded dependencies from the compiler

View File

@@ -24,14 +24,11 @@ import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.*
import java.io.File
private fun Project.kotlinBuildLocalDependenciesDir(): File =
(findProperty("kotlin.build.dependencies.dir") as String?)?.let(::File)
?: rootProject.gradle.gradleUserHomeDir.resolve("kotlin-build-dependencies")
(findProperty("kotlin.build.dependencies.dir") as String?)?.let(::File) ?: project.rootDir.absoluteFile.resolve("dependencies")
private fun Project.kotlinBuildLocalRepoDir(): File = kotlinBuildLocalDependenciesDir().resolve("repo")
@@ -165,7 +162,7 @@ fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File,
classpath = mainSourceSet.runtimeClasspath
mainClass.set("com.intellij.idea.Main")
main = "com.intellij.idea.Main"
workingDir = File(intellijRootDir(), "bin")
@@ -177,17 +174,12 @@ fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File,
"-Didea.debug.mode=true",
"-Didea.system.path=$ideaSandboxDir",
"-Didea.config.path=$ideaSandboxConfigDir",
"-Didea.tooling.debug=true",
"-Dapple.laf.useScreenMenuBar=true",
"-Dapple.awt.graphics.UseQuartz=true",
"-Dsun.io.useCanonCaches=false",
"-Dplugin.path=${ideaPluginDir.absolutePath}"
)
if (Platform[201].orHigher() && !isIntellijUltimateSdkAvailable()) {
jvmArgs("-Didea.platform.prefix=Idea")
}
if (rootProject.findProperty("versions.androidStudioRelease") != null) {
jvmArgs("-Didea.platform.prefix=AndroidStudio")
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
import com.gradle.publish.PluginBundleExtension
import com.gradle.publish.PluginConfig
import org.gradle.api.Project
import org.gradle.api.publish.PublicationContainer
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.*
import plugins.KotlinBuildPublishingPlugin
import plugins.configureRepository
import java.util.*
internal const val PLUGIN_MARKER_SUFFIX = ".gradle.plugin"
@UseExperimental(ExperimentalStdlibApi::class)
fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
val pluginDevelopment = extensions.getByType<PluginBundleExtension>()
val publishingExtension = extensions.getByType<PublishingExtension>()
val mainPublication = publishingExtension.publications[KotlinBuildPublishingPlugin.PUBLICATION_NAME] as MavenPublication
pluginDevelopment.plugins.forEach { declaration ->
val markerPublication = createMavenMarkerPublication(declaration, mainPublication, publishingExtension.publications)
if (withEmptyJars) {
addEmptyJarArtifacts(markerPublication)
}
tasks.named<PublishToMavenRepository>(
"publish${markerPublication.name.capitalize(Locale.ROOT)}PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository"
).configureRepository()
}
}
fun Project.addEmptyJarArtifacts(publication: MavenPublication) {
val emptyJar = getOrCreateTask<Jar>("emptyJar") {
archiveBaseName.set("empty")
}
publication.artifact(emptyJar.get()) { }
publication.artifact(emptyJar.get()) { classifier = "sources" }
publication.artifact(emptyJar.get()) { classifier = "javadoc" }
}
// Based on code from `java-gradle-plugin`
// https://github.com/gradle/gradle/blob/v6.4.0/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/MavenPluginPublishPlugin.java#L84
private fun createMavenMarkerPublication(
declaration: PluginConfig,
coordinates: MavenPublication,
publications: PublicationContainer
): MavenPublication {
return publications.create<MavenPublication>(declaration.name.toString() + "PluginMarkerMaven") {
val pluginId: String = declaration.id
artifactId = pluginId + PLUGIN_MARKER_SUFFIX
groupId = pluginId
pom.withXml {
val root = asElement()
val document = root.ownerDocument
val dependencies = root.appendChild(document.createElement("dependencies"))
val dependency = dependencies.appendChild(document.createElement("dependency"))
val groupId = dependency.appendChild(document.createElement("groupId"))
groupId.textContent = coordinates.groupId
val artifactId = dependency.appendChild(document.createElement("artifactId"))
artifactId.textContent = coordinates.artifactId
val version = dependency.appendChild(document.createElement("version"))
version.textContent = coordinates.version
}
pom.name.set(declaration.displayName)
pom.description.set(declaration.description)
}
}

View File

@@ -36,8 +36,8 @@ open class DexMethodCount : DefaultTask() {
get() = artifactName ?: project.name
fun from(jar: Jar) {
jarFile = jar.archiveFile.get().asFile
artifactName = jar.archiveBaseName.orNull
jarFile = jar.archivePath
artifactName = jar.baseName
dependsOn(jar)
}
@@ -51,7 +51,10 @@ open class DexMethodCount : DefaultTask() {
@TaskAction
fun invoke() {
val methods = dexMethods(jarFile)
val counts = methods.getCounts().also { this.counts = it }
printTotals(counts)
outputDetails(counts)
}
@@ -59,7 +62,7 @@ open class DexMethodCount : DefaultTask() {
val byPackage = this.groupingBy { it.`package` }.eachCount()
val byClass = this.groupingBy { it.declaringType }.eachCount()
val ownPackages = ownPackages?.map { "$it." }
val ownPackages = ownPackages?.map { it + '.' }
val byOwnPackages = if (ownPackages != null) {
this.partition { method -> ownPackages.any { method.declaringType.startsWith(it) } }.let {
it.first.size to it.second.size
@@ -75,6 +78,14 @@ open class DexMethodCount : DefaultTask() {
)
}
private fun printTotals(counts: Counts) {
logger.lifecycle("Artifact $artifactOrArchiveName, total methods: ${counts.total}")
ownPackages?.let { packages ->
logger.lifecycle("Artifact $artifactOrArchiveName, total methods from packages ${packages.joinToString { "$it.*" }}: ${counts.totalOwnPackages}")
logger.lifecycle("Artifact $artifactOrArchiveName, total methods from other packages: ${counts.totalOtherPackages}")
}
}
private fun outputDetails(counts: Counts) {
detailOutputFile.printWriter().use { writer ->
writer.println("${counts.total.padRight()}\tTotal methods")
@@ -96,7 +107,7 @@ open class DexMethodCount : DefaultTask() {
}
}
open class DexMethodCountStats : DefaultTask() {
open class TCDexMethodCountStats : DefaultTask() {
@Internal
lateinit var from: TaskProvider<DexMethodCount>
@@ -106,41 +117,25 @@ open class DexMethodCountStats : DefaultTask() {
get() = from.get().detailOutputFile
@TaskAction
private fun printStats() {
private fun printTCStats() {
val artifactOrArchiveName = from.get().artifactOrArchiveName
inputFile.reader().useLines { lines ->
fun String.getStatValue() = substringBefore("\t").trim()
val ownPackages = from.get().ownPackages
val statsLineCount = if (ownPackages == null) 1 else 3
val stats = lines.take(statsLineCount).map { it.getStatValue() }.toList()
val stats = lines.take(3).toList()
val total = stats[0].getStatValue()
val totalOwnPackages = stats[1].getStatValue()
val totalOtherPackages = stats[2].getStatValue()
val total = stats[0]
logger.lifecycle("Artifact $artifactOrArchiveName, total methods: $total")
if (project.kotlinBuildProperties.isTeamcityBuild) {
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='$total']")
}
ownPackages?.let { packages ->
val totalOwnPackages = stats[1]
val totalOtherPackages = stats[2]
logger.lifecycle("Artifact $artifactOrArchiveName, total methods from packages ${packages.joinToString { "$it.*" }}: $totalOwnPackages")
logger.lifecycle("Artifact $artifactOrArchiveName, total methods from other packages: $totalOtherPackages")
if (project.kotlinBuildProperties.isTeamcityBuild) {
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}_OwnPackages' value='$totalOwnPackages']")
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}_OtherPackages' value='$totalOtherPackages']")
}
}
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='$total']")
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}_OwnPackages' value='$totalOwnPackages']")
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}_OtherPackages' value='$totalOtherPackages']")
}
}
}
fun Project.printStats(dexMethodCount: TaskProvider<DexMethodCount>) {
val dexMethodCountStats = tasks.register("dexMethodCountStats", DexMethodCountStats::class.java) {
dependsOn(dexMethodCount)
fun Project.printTCStats(dexMethodCount: TaskProvider<DexMethodCount>) {
val dexMethodCountStats = tasks.register("dexMethodCountStats", TCDexMethodCountStats::class.java) {
from = dexMethodCount
}
@@ -149,12 +144,5 @@ fun Project.printStats(dexMethodCount: TaskProvider<DexMethodCount>) {
}
}
fun Project.dexMethodCount(action: DexMethodCount.() -> Unit): TaskProvider<DexMethodCount> {
val dexMethodCount = tasks.register("dexMethodCount", DexMethodCount::class.java, action)
printStats(dexMethodCount)
tasks.getByName("check").dependsOn(dexMethodCount)
return dexMethodCount
}
private val DexMethod.`package`: String get() = declaringType.substringBeforeLast('.')
private fun Int.padRight() = toString().padStart(5, ' ')

View File

@@ -1,160 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package plugins
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Usage
import org.gradle.api.component.AdhocComponentWithVariants
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.*
import org.gradle.plugins.signing.SigningExtension
import org.gradle.plugins.signing.SigningPlugin
import java.net.URI
import java.util.*
import javax.inject.Inject
class KotlinBuildPublishingPlugin @Inject constructor(
private val componentFactory: SoftwareComponentFactory
) : Plugin<Project> {
override fun apply(target: Project): Unit = with(target) {
apply<MavenPublishPlugin>()
apply<SigningPlugin>()
val publishedRuntime = configurations.maybeCreate(RUNTIME_CONFIGURATION).apply {
isCanBeConsumed = false
isCanBeResolved = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
}
}
val publishedCompile = configurations.maybeCreate(COMPILE_CONFIGURATION).apply {
isCanBeConsumed = false
isCanBeResolved = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_API))
}
}
val kotlinLibraryComponent = componentFactory.adhoc(ADHOC_COMPONENT_NAME) as AdhocComponentWithVariants
components.add(kotlinLibraryComponent)
kotlinLibraryComponent.addVariantsFromConfiguration(publishedCompile) { mapToMavenScope("compile") }
kotlinLibraryComponent.addVariantsFromConfiguration(publishedRuntime) { mapToMavenScope("runtime") }
pluginManager.withPlugin("java-base") {
val runtimeElements by configurations
val apiElements by configurations
publishedRuntime.extendsFrom(runtimeElements)
publishedCompile.extendsFrom(apiElements)
kotlinLibraryComponent.addVariantsFromConfiguration(runtimeElements) {
mapToMavenScope("runtime")
if (configurationVariant.artifacts.any { JavaBasePlugin.UNPUBLISHABLE_VARIANT_ARTIFACTS.contains(it.type) }) {
skip()
}
}
}
configure<PublishingExtension> {
publications {
create<MavenPublication>(PUBLICATION_NAME) {
from(kotlinLibraryComponent)
pom {
packaging = "jar"
name.set(humanReadableName(project))
description.set(project.description ?: humanReadableName(project))
url.set("https://kotlinlang.org/")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
scm {
url.set("https://github.com/JetBrains/kotlin")
connection.set("scm:git:https://github.com/JetBrains/kotlin.git")
developerConnection.set("scm:git:https://github.com/JetBrains/kotlin.git")
}
developers {
developer {
name.set("Kotlin Team")
organization.set("JetBrains")
organizationUrl.set("https://www.jetbrains.com")
}
}
}
}
}
repositories {
maven {
name = REPOSITORY_NAME
url = file("${project.rootDir}/build/repo").toURI()
}
}
}
configure<SigningExtension> {
setRequired(provider {
project.findProperty("signingRequired")?.toString()?.toBoolean()
?: project.property("isSonatypeRelease") as Boolean
})
sign(extensions.getByType<PublishingExtension>().publications[PUBLICATION_NAME])
}
tasks.register("install") {
dependsOn(tasks.named("publishToMavenLocal"))
}
tasks.named<PublishToMavenRepository>("publish${PUBLICATION_NAME}PublicationTo${REPOSITORY_NAME}Repository")
.configureRepository()
}
companion object {
const val PUBLICATION_NAME = "Main"
const val REPOSITORY_NAME = "Maven"
const val ADHOC_COMPONENT_NAME = "kotlinLibrary"
const val COMPILE_CONFIGURATION = "publishedCompile"
const val RUNTIME_CONFIGURATION = "publishedRuntime"
@UseExperimental(ExperimentalStdlibApi::class)
fun humanReadableName(project: Project) =
project.name.split("-").joinToString(separator = " ") { it.capitalize(Locale.ROOT) }
}
}
fun TaskProvider<PublishToMavenRepository>.configureRepository() = configure {
dependsOn(project.rootProject.tasks.named("preparePublication"))
doFirst {
val preparePublication = project.rootProject.tasks.named("preparePublication").get()
val username: String? by preparePublication.extra
val password: String? by preparePublication.extra
val repoUrl: String by preparePublication.extra
repository.apply {
url = project.uri(repoUrl)
if (url.scheme != "file" && username != null && password != null) {
credentials {
this.username = username
this.password = password
}
}
}
}
}

View File

@@ -31,18 +31,12 @@ open class PublishedKotlinModule : Plugin<Project> {
plugins.apply("maven")
configurations.maybeCreate("publishedRuntime").apply {
val publishedRuntime by configurations.creating {
the<MavenPluginConvention>()
.conf2ScopeMappings
.addMapping(0, this, Conf2ScopeMappingContainer.RUNTIME)
}
configurations.maybeCreate("publishedCompile").apply {
the<MavenPluginConvention>()
.conf2ScopeMappings
.addMapping(0, this, Conf2ScopeMappingContainer.COMPILE)
}
if (!project.hasProperty("prebuiltJar")) {
plugins.apply("signing")

View File

@@ -23,15 +23,3 @@ fun DependencyHandler.publishedRuntime(
): ExternalModuleDependency =
addDependencyTo(this, "publishedRuntime", dependencyNotation, dependencyConfiguration)
val NamedDomainObjectContainer<Configuration>.publishedCompile: NamedDomainObjectProvider<Configuration> get() = named("publishedCompile")
fun DependencyHandler.publishedCompile(dependencyNotation: Any): Dependency? =
add("publishedCompile", dependencyNotation)
fun DependencyHandler.publishedCompile(
dependencyNotation: String,
dependencyConfiguration: Action<ExternalModuleDependency>
): ExternalModuleDependency =
addDependencyTo(this, "publishedCompile", dependencyNotation, dependencyConfiguration)

View File

@@ -31,44 +31,6 @@ import java.lang.Character.isUpperCase
import java.nio.file.Files
import java.nio.file.Path
fun Task.dependsOnKotlinPluginInstall() {
dependsOn(
":kotlin-allopen:install",
":kotlin-noarg:install",
":kotlin-sam-with-receiver:install",
":kotlin-android-extensions:install",
":kotlin-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-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"
)
}
fun Project.projectTest(
taskName: String = "test",
parallel: Boolean = false,
@@ -117,20 +79,21 @@ fun Project.projectTest(
}
}
if (project.findProperty("kotlin.test.instrumentation.disable")?.toString()?.toBoolean() != true) {
doFirst {
val agent = tasks.findByPath(":test-instrumenter:jar")!!.outputs.files.singleFile
val args = project.findProperty("kotlin.test.instrumentation.args")?.let { "=$it" }.orEmpty()
jvmArgs("-javaagent:$agent$args")
}
dependsOn(":test-instrumenter:jar")
doFirst {
val agent = tasks.findByPath(":test-instrumenter:jar")!!.outputs.files.singleFile
val args = project.findProperty("kotlin.test.instrumentation.args")?.let { "=$it" }.orEmpty()
jvmArgs("-javaagent:$agent$args")
}
dependsOn(":test-instrumenter:jar")
jvmArgs(
"-ea",
"-XX:+HeapDumpOnOutOfMemoryError",
"-XX:+UseCodeCacheFlushing",
"-XX:ReservedCodeCacheSize=256m",
"-XX:ReservedCodeCacheSize=128m",
"-Djna.nosys=true"
)
@@ -143,11 +106,6 @@ fun Project.projectTest(
environment("PROJECT_BUILD_DIR", buildDir)
systemProperty("jps.kotlin.home", rootProject.extra["distKotlinHomeDir"]!!)
systemProperty("kotlin.ni", if (rootProject.hasProperty("newInferenceTests")) "true" else "false")
systemProperty("org.jetbrains.kotlin.skip.muted.tests", if (rootProject.hasProperty("skipMutedTests")) "true" else "false")
if (Platform[202].orHigher()) {
systemProperty("idea.ignore.disabled.plugins", "true")
}
var subProjectTempRoot: Path? = null
doFirst {
@@ -196,10 +154,6 @@ object TaskUtils {
fun useAndroidJar(task: Task) {
task.useAndroidConfiguration(systemPropertyName = "android.jar", configName = "androidJar")
}
fun useAndroidEmulator(task: Task) {
task.useAndroidConfiguration(systemPropertyName = "android.sdk", configName = "androidEmulator")
}
}
private fun Task.useAndroidConfiguration(systemPropertyName: String, configName: String) {

View File

@@ -1,14 +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:3.5.3'
classpath 'com.android.tools.build:gradle:3.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
apply plugin: 'com.android.application'
@@ -19,7 +19,7 @@ repositories {
}
android {
compileSdkVersion 26
compileSdkVersion 19
buildToolsVersion "28.0.3"
defaultConfig {
@@ -51,7 +51,7 @@ android {
dexOptions {
dexInProcess false
javaMaxHeapSize "1500m"
javaMaxHeapSize "1200m"
maxProcessCount 4
additionalParameters "--debug"
}
@@ -60,42 +60,21 @@ android {
resultsDir = "build/test/results"
}
if (isD8Enabled) {
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
flavorDimensions "box"
productFlavors {
common0 {
ktest0 {
dimension "box"
}
common1 {
ktest1 {
dimension "box"
}
common2 {
ktest2 {
dimension "box"
}
reflect0 {
dimension "box"
}
if (isD8Enabled) {
jvm80 {
dimension "box"
}
reflectjvm80 {
dimension "box"
}
}
}
}
@@ -103,9 +82,9 @@ android {
task jarTestFolders() {
println "Jar folders..."
new File("${projectDir}/libs/").listFiles().each { File file ->
if (file.isDirectory()) {
if (file.isDirectory() && !file.name.equals("test")) {
println "Jar '${file.name}' folder..."
ant.jar(basedir: "libs/${file.name}/", destfile: "libs/" + file.name + ".jar")
ant.jar(basedir: "libs/${file.name}/", destfile: "libs/test/" + file.name + ".jar")
}
}
}
@@ -115,18 +94,11 @@ tasks.withType(JavaCompile) {
}
dependencies {
implementation fileTree(dir: 'libs', include: ['kotlin-test.jar', 'kotlin-stdlib.jar'])
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
android.applicationVariants.all { variant ->
variant.productFlavors.each {
def configuration = configurations.getByName(it.name + 'Implementation').name
add(configuration, project.fileTree(dir: 'libs', include: [it.name + ".jar"]))
if (it.name.startsWith("reflect")) {
add(configuration, project.fileTree(dir: 'libs', include: ['kotlin-reflect.jar']))
}
}
}
ktest0Implementation fileTree(dir: 'libs/test', include: ['libtest0.jar'])
ktest1Implementation fileTree(dir: 'libs/test', include: ['libtest1.jar'])
ktest2Implementation fileTree(dir: 'libs/test', include: ['libtest2.jar'])
}

View File

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

View File

@@ -1,4 +1,3 @@
import TaskUtils.useAndroidEmulator
plugins {
kotlin("jvm")
@@ -29,12 +28,9 @@ dependencies {
testCompile(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
}
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", rootProject = rootProject) }
Platform[202].orHigher {
testCompile(intellijDep()) { includeJars("groovy", rootProject = rootProject) }
}
Platform[201].orLower {
testCompile(intellijDep()) { includeJars("groovy-all", rootProject = rootProject) }
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", "groovy-all", rootProject = rootProject) }
Platform[191].orLower {
testCompile(intellijDep()) { includeJars("jps-builders") }
}
Platform[192].orHigher {
testCompile(intellijPluginDep("java")) { includeJars("jps-builders") }
@@ -63,7 +59,6 @@ projectTest {
}
workingDir = rootDir
useAndroidEmulator(this)
}
val generateAndroidTests by generator("org.jetbrains.kotlin.android.tests.CodegenTestsOnAndroidGenerator")

View File

@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.android.tests
import com.intellij.util.PlatformUtils
import junit.framework.TestCase
import junit.framework.TestSuite
import org.jetbrains.kotlin.android.tests.download.SDKDownloader
import org.jetbrains.kotlin.android.tests.emulator.Emulator
import org.jetbrains.kotlin.android.tests.gradle.GradleRunner
import org.jetbrains.kotlin.android.tests.run.PermissionManager
import org.junit.Assert
import org.w3c.dom.Element
import org.xml.sax.SAXException
@@ -37,6 +39,8 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
private fun runTestsInEmulator(): TestSuite {
val rootSuite = TestSuite("Root")
downloadDependencies()
val emulatorType = if (isTeamcity) Emulator.ARM else Emulator.X86
println("Using $emulatorType emulator!")
val emulator = Emulator(pathManager, emulatorType)
@@ -52,16 +56,16 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
try {
emulator.waitEmulatorStart()
runTestsOnEmulator(gradleRunner, TestSuite("D8")).apply {
runTestsOnEmulator(gradleRunner, TestSuite("Dex")).apply {
rootSuite.addTest(this)
}
renameFlavorFolder()
enableD8(false)
runTestsOnEmulator(gradleRunner, TestSuite("DX")).apply {
enableD8(true)
runTestsOnEmulator(gradleRunner, TestSuite("D8")).apply {
(0 until this.countTestCases()).forEach {
val testCase = testAt(it) as TestCase
testCase.name += "_DX"
testCase.name += "_D8"
}
rootSuite.addTest(this)
}
@@ -102,14 +106,14 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
testCases.forEach { aCase -> suite.addTest(aCase) }
Assert.assertNotEquals("There is no test results in report", 0, testCases.size.toLong())
}
} catch (e: Throwable) {
} catch (e: Exception) {
throw RuntimeException("Can't parse test results in $reportFolder\n$resultOutput", e)
}
}
private fun renameFlavorFolder() {
val reportFolder = File(flavorFolder())
reportFolder.renameTo(File(reportFolder.parentFile, reportFolder.name + "_d8"))
reportFolder.renameTo(File(reportFolder.parentFile, reportFolder.name + "_dex"))
}
private fun flavorFolder() = pathManager.tmpFolder + "/build/test/results/connected/flavors"
@@ -130,6 +134,18 @@ class CodegenTestsOnAndroidRunner private constructor(private val pathManager: P
}
private fun downloadDependencies() {
val rootForAndroidDependencies = File(pathManager.dependenciesRoot)
if (!rootForAndroidDependencies.exists()) {
rootForAndroidDependencies.mkdirs()
}
val downloader = SDKDownloader(pathManager)
downloader.downloadAll()
downloader.unzipAll()
PermissionManager.setPermissions(pathManager)
}
companion object {
@JvmStatic

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.android.tests;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.android.tests.download.SDKDownloader;
import java.io.File;
@@ -35,7 +35,7 @@ public class PathManager {
}
public String getAndroidAvdRoot() {
String androidEmulatorRoot = getAndroidSdkRoot() + "/compiler_box_test_avd";
String androidEmulatorRoot = getAndroidSdkRoot() + "/emulatoravd";
new File(androidEmulatorRoot).mkdirs();
return androidEmulatorRoot;
}
@@ -52,8 +52,12 @@ public class PathManager {
return getAndroidSdkRoot() + "/emulator";
}
public String getOutputForCompiledFiles(String flavor) {
return tmpFolder + "/libs/" + flavor;
public String getBuildToolsFolderInAndroidSdk() {
return getAndroidSdkRoot() + "/build-tools";
}
public String getOutputForCompiledFiles(int index) {
return tmpFolder + "/libs/libtest" + index;
}
public String getLibsFolderInAndroidTmpFolder() {
@@ -69,7 +73,19 @@ public class PathManager {
}
public String getAndroidSdkRoot() {
return KotlinTestUtils.getAndroidSdkSystemIndependentPath();
return getDependenciesRoot() + "/android-sdk";
}
public String getDependenciesRoot() {
return rootFolder + "/dependencies/android.tests.dependencies";
}
public String getGradleBinFolder() {
return getDependenciesRoot() + "/gradle-" + SDKDownloader.GRADLE_VERSION + "/bin";
}
public String getRootForDownload() {
return getDependenciesRoot() + "/download";
}
public String getAndroidModuleRoot() {

View File

@@ -0,0 +1,269 @@
/*
* 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.download;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.kotlin.android.tests.PathManager;
import org.jetbrains.kotlin.android.tests.run.RunUtils;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class SDKDownloader {
private final String platformZipPath;
private final String armImage;
private final String x86Image;
private final String platformToolsZipPath;
private final String skdToolsZipPath;
private final String buildToolsZipPath;
private final String gradleZipPath;
private final String emulatorZipPath;
private final PathManager pathManager;
private static final String PLATFORM_TOOLS = "28.0.1";
private static final String SDK_TOOLS = "4333796"; //"26.1.1";
public static final String BUILD_TOOLS = "28.0.3";
private static final int ANDROID_VERSION = 19;
public static final String GRADLE_VERSION = "5.1.1";
public static final String EMULATOR_TOOLS_VERSION = "5264690"; //"28.0.23";
public SDKDownloader(PathManager pathManager) {
this.pathManager = pathManager;
platformZipPath = pathManager.getRootForDownload() + "/platform" + ANDROID_VERSION + ".zip";
armImage = pathManager.getRootForDownload() + "/arm-image.zip";
x86Image = pathManager.getRootForDownload() + "/x86-image.zip";
platformToolsZipPath = pathManager.getRootForDownload() + "/platform-tools" + PLATFORM_TOOLS + ".zip";
skdToolsZipPath = pathManager.getRootForDownload() + "/sdk-tools" + SDK_TOOLS + ".zip";
buildToolsZipPath = pathManager.getRootForDownload() + "/build-tools" + BUILD_TOOLS + ".zip";
gradleZipPath = pathManager.getRootForDownload() + "/gradle" + GRADLE_VERSION + ".zip";
emulatorZipPath = pathManager.getRootForDownload() + "/emulator" + EMULATOR_TOOLS_VERSION + ".zip";
}
public void downloadPlatform() {
download("https://dl-ssl.google.com/android/repository/android-" + ANDROID_VERSION + "_r04.zip", platformZipPath); //Same for all platforms
}
private void downloadAbi() {
download("https://dl.google.com/android/repository/sys-img/android/armeabi-v7a-" + ANDROID_VERSION + "_r05.zip", armImage); //Same for all platforms
download("https://dl.google.com/android/repository/sys-img/android/x86-" + ANDROID_VERSION + "_r06.zip", x86Image); //Same for all platforms
}
public void downloadPlatformTools() {
download(getDownloadUrl("https://dl-ssl.google.com/android/repository/platform-tools_r" + PLATFORM_TOOLS), platformToolsZipPath);
}
public void downloadSdkTools() {
download("https://dl.google.com/android/repository/sdk-tools-" + getPlatformName() + "-" + SDK_TOOLS + ".zip",
skdToolsZipPath);
}
public void downloadBuildTools() {
download(getDownloadUrl("https://dl.google.com/android/repository/build-tools_r" + BUILD_TOOLS), buildToolsZipPath);
}
public void downloadEmulator() {
download("https://dl.google.com/android/repository/emulator-" + getPlatformName() + "-" + EMULATOR_TOOLS_VERSION + ".zip",
emulatorZipPath);
}
public void downloadGradle() {
download("https://services.gradle.org/distributions/gradle-" + GRADLE_VERSION + "-bin.zip", gradleZipPath);
}
private static String getDownloadUrl(String prefix) {
String suffix;
if (SystemInfo.isWindows) {
suffix = "-windows.zip";
}
else if (SystemInfo.isMac) {
suffix = "-macosx.zip";
}
else if (SystemInfo.isUnix) {
suffix = "-linux.zip";
}
else {
throw new IllegalStateException("Your operating system isn't supported yet.");
}
return prefix + suffix;
}
private static String getPlatformName() {
if (SystemInfo.isWindows) {
return "windows";
}
else if (SystemInfo.isMac) {
return "darwin";
}
else if (SystemInfo.isUnix) {
return "linux";
}
else {
throw new IllegalStateException("Your operating system isn't supported yet.");
}
}
public void downloadAll() {
downloadSdkTools();
downloadAbi();
downloadPlatform();
downloadPlatformTools();
downloadBuildTools();
downloadGradle();
downloadEmulator();
}
public void unzipAll() {
String androidSdkRoot = pathManager.getAndroidSdkRoot();
unzip(platformZipPath, pathManager.getPlatformFolderInAndroidSdk());
new File(pathManager.getPlatformFolderInAndroidSdk() + "/android-4.4.2").renameTo(new File(pathManager.getPlatformFolderInAndroidSdk() + "/android-" + ANDROID_VERSION));
unzip(armImage, androidSdkRoot + "/system-images/android-" + ANDROID_VERSION + "/default/");
unzip(x86Image, androidSdkRoot + "/system-images/android-" + ANDROID_VERSION + "/default/");
unzip(platformToolsZipPath, androidSdkRoot);
unzip(skdToolsZipPath, androidSdkRoot);
unzip(gradleZipPath, pathManager.getDependenciesRoot());
//BUILD TOOLS
String buildTools = androidSdkRoot + "/build-tools/";
unzip(buildToolsZipPath, buildTools);
unzip(emulatorZipPath, androidSdkRoot);
}
public void deleteAll() {
delete(platformZipPath);
delete(platformToolsZipPath);
delete(skdToolsZipPath);
delete(buildToolsZipPath);
delete(armImage);
delete(x86Image);
delete(gradleZipPath);
}
private static void download(String urlString, String output) {
System.out.println("Start downloading: " + urlString + " to " + output);
OutputStream outStream = null;
URLConnection urlConnection;
InputStream is;
try {
URL Url;
byte[] buf;
int read;
//int written = 0;
Url = new URL(urlString);
File outputFile = new File(output);
outputFile.getParentFile().mkdirs();
if (outputFile.exists()) {
System.out.println("File was already downloaded: " + output);
return;
}
outputFile.createNewFile();
FileOutputStream outputStream = new FileOutputStream(outputFile);
outStream = new BufferedOutputStream(outputStream);
urlConnection = Url.openConnection();
is = urlConnection.getInputStream();
buf = new byte[1024];
while ((read = is.read(buf)) != -1) {
outStream.write(buf, 0, read);
//written += read;
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
RunUtils.close(outStream);
}
System.out.println("Finish downloading: " + urlString + " to " + output);
}
protected void unzip(String pathToFile, String outputFolder) {
System.out.println("Start unzipping: " + pathToFile + " to " + outputFolder);
String pathToUnzip;
if (outputFolder.equals(pathManager.getPlatformFolderInAndroidSdk())) {
pathToUnzip = outputFolder;
}
else {
pathToUnzip = outputFolder + "/" + FileUtil.getNameWithoutExtension(new File(pathToFile));
}
if (new File(pathToUnzip).listFiles() != null) {
System.out.println("File was already unzipped: " + pathToFile);
return;
}
try {
byte[] buf = new byte[1024];
ZipEntry zipEntry = null;
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(pathToFile))) {
zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
String entryName = zipEntry.getName();
int n;
File outputFile = new File(outputFolder + "/" + entryName);
if (zipEntry.isDirectory()) {
outputFile.mkdirs();
zipInputStream.closeEntry();
zipEntry = zipInputStream.getNextEntry();
continue;
}
else {
File parentFile = outputFile.getParentFile();
if (parentFile != null && !parentFile.exists()) {
parentFile.mkdirs();
}
outputFile.createNewFile();
}
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile)) {
while ((n = zipInputStream.read(buf, 0, 1024)) > -1) {
fileOutputStream.write(buf, 0, n);
}
}
zipInputStream.closeEntry();
zipEntry = zipInputStream.getNextEntry();
}
}
catch (IOException e) {
if (zipEntry != null) {
System.err.println("Entry name: " + zipEntry.getName());
}
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
System.out.println("Finish unzipping: " + pathToFile + " to " + outputFolder);
}
private static void delete(String filePath) {
new File(filePath).delete();
}
}

View File

@@ -48,8 +48,8 @@ public class Emulator {
private GeneralCommandLine getCreateCommand() {
GeneralCommandLine commandLine = new GeneralCommandLine();
String androidCmdName = SystemInfo.isWindows ? "avdmanager.bat" : "avdmanager";
commandLine.setExePath(pathManager.getToolsFolderInAndroidSdk() + "/bin/" + androidCmdName);
String androidCmdName = SystemInfo.isWindows ? "android.bat" : "android";
commandLine.setExePath(pathManager.getToolsFolderInAndroidSdk() + "/" + androidCmdName);
commandLine.addParameter("create");
commandLine.addParameter("avd");
commandLine.addParameter("--force");

View File

@@ -31,8 +31,8 @@ public class GradleRunner {
public GradleRunner(PathManager pathManager) {
listOfCommands = new ArrayList<>();
String cmdName = SystemInfo.isWindows ? "gradlew.bat" : "gradlew";
listOfCommands.add(pathManager.getTmpFolder() + "/" + cmdName);
String cmdName = SystemInfo.isWindows ? "gradle.bat" : "gradle";
listOfCommands.add(pathManager.getGradleBinFolder() + "/" + cmdName);
listOfCommands.add("--no-daemon");
listOfCommands.add("--build-file");
listOfCommands.add(pathManager.getTmpFolder() + "/build.gradle");

View File

@@ -0,0 +1,64 @@
/*
* 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.run;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.kotlin.android.tests.PathManager;
import org.jetbrains.kotlin.android.tests.download.SDKDownloader;
import java.io.File;
public class PermissionManager {
private PermissionManager() {
}
public static void setPermissions(PathManager pathManager) {
if (!SystemInfo.isWindows) {
setExecPermissionForSimpleNamedFiles(new File(pathManager.getToolsFolderInAndroidSdk()));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getBuildToolsFolderInAndroidSdk() + "/" + SDKDownloader.BUILD_TOOLS));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getPlatformToolsFolderInAndroidSdk()));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getToolsFolderInAndroidSdk() +"/bin"));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getEmulatorFolderInAndroidSdk()));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getEmulatorFolderInAndroidSdk() +"/bin"));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getEmulatorFolderInAndroidSdk() +"/bin64"));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getEmulatorFolderInAndroidSdk() +"/qemu/linux-x86_64"));
setExecPermissionForSimpleNamedFiles(new File(pathManager.getAndroidSdkRoot() + "/system-images/android-19/default/armeabi-v7a/"));
RunUtils.execute(generateChmodCmd(pathManager.getGradleBinFolder() + "/gradle"));
}
}
private static void setExecPermissionForSimpleNamedFiles(File folder) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile() && !file.getName().contains(".")) {
RunUtils.execute(generateChmodCmd(file.getAbsolutePath()));
}
}
}
}
private static GeneralCommandLine generateChmodCmd(String path) {
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.setExePath("chmod");
commandLine.addParameter("a+x");
commandLine.addParameter(path);
return commandLine;
}
}

View File

@@ -17,10 +17,10 @@
package org.jetbrains.kotlin.android.tests
import com.intellij.openapi.util.Ref
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.test.KotlinBaseTest
import java.io.File
import java.util.regex.Pattern
@@ -34,7 +34,7 @@ private data class OldPackageAndNew(val oldFqName: FqName, val newFqName: FqName
internal fun patchFilesAndAddTest(
testFile: File,
testFiles: List<KotlinBaseTest.TestFile>,
testFiles: List<CodegenTestCase.TestFile>,
filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter
): FqName? {
if (testFiles.any { it.name.endsWith(".java") }) {
@@ -46,21 +46,18 @@ internal fun patchFilesAndAddTest(
val newPackagePrefix = testFile.path.replace("\\\\|-|\\.|/".toRegex(), "_")
val oldPackage = Ref<FqName>()
val isJvmName = Ref<Boolean>(false)
val isSingle = testFiles.size == 1
val resultFiles = testFiles.map {
val fileName = if (isSingle) it.name else testFile.name.substringBeforeLast(".kt") + "/" + it.name
TestClassInfo(
fileName,
changePackage(newPackagePrefix, it.content, oldPackage, isJvmName),
changePackage(newPackagePrefix, it.content, oldPackage),
oldPackage.get(),
isJvmName.get(),
getGeneratedClassName(File(fileName), it.content, newPackagePrefix, oldPackage.get())
)
}
val packages =
resultFiles.map { OldPackageAndNew(it.oldPackage, it.newPackagePartClassId.parent()) }
.sortedByDescending { it.oldFqName.asString().length }
resultFiles.map { OldPackageAndNew(it.oldPackage, it.newClassId.parent()) }.sortedByDescending { it.oldFqName.asString().length }
//If files contain any val or var declaration with same name as any package name
// then use old conservative renaming scheme, otherwise use aggressive one
@@ -97,7 +94,7 @@ internal fun patchFilesAndAddTest(
/*replace all Class.forName*/
resultFiles.forEach { file ->
file.content = resultFiles.fold(file.content) { r, param ->
patchClassForName(param.newPackagePartClassId, param.oldPackage, r, conservativeRenameScheme)
patchClassForName(param.newClassId, param.oldPackage, r, conservativeRenameScheme)
}
}
@@ -106,13 +103,6 @@ internal fun patchFilesAndAddTest(
file.content = file.content.patchSelfImports(file.newPackage)
}
//patch root package parts usages in strings
resultFiles.forEach { file ->
file.content = resultFiles.fold(file.content) { r, param ->
patchRootPartNamesInStrings(param.newPackagePartClassId, param.oldPackage, param.isJvmName, r)
}
}
val boxFiles = resultFiles.filter { hasBoxMethod(it.content) }
if (boxFiles.size != 1) {
println("Several box methods in $testFile")
@@ -120,22 +110,22 @@ internal fun patchFilesAndAddTest(
filesHolder.addTest(
resultFiles.filter { resultFile -> resultFile.name.endsWith(".kt") || resultFile.name.endsWith(".kts") },
TestInfo("", boxFiles.last().newPackagePartClassId, testFile)
TestInfo("", boxFiles.last().newClassId, testFile)
)
return boxFiles.last().newPackagePartClassId
return boxFiles.last().newClassId
}
private fun hasBoxMethod(text: String): Boolean {
return text.contains("fun box()")
}
class TestClassInfo(val name: String, var content: String, val oldPackage: FqName, val isJvmName: Boolean, val newPackagePartClassId: FqName) {
val newPackage = newPackagePartClassId.parent()
class TestClassInfo(val name: String, var content: String, val oldPackage: FqName, val newClassId: FqName) {
val newPackage = newClassId.parent()
}
private fun changePackage(newPackagePrefix: String, text: String, oldPackage: Ref<FqName>, isJvmName: Ref<Boolean>): String {
private fun changePackage(newPackagePrefix: String, text: String, oldPackage: Ref<FqName>): String {
val matcher = packagePattern.matcher(text)
if (matcher.find()) {
val oldPackageName = matcher.toMatchResult().group(1)
@@ -147,7 +137,6 @@ private fun changePackage(newPackagePrefix: String, text: String, oldPackage: Re
if (text.contains("@file:")) {
val index = text.lastIndexOf("@file:")
val packageDirectiveIndex = text.indexOf("\n", index)
isJvmName.set(true)
return text.substring(0, packageDirectiveIndex + 1) + packageDirective + text.substring(packageDirectiveIndex + 1)
} else {
return packageDirective + text
@@ -180,19 +169,6 @@ private fun patchClassForName(className: FqName, oldPackage: FqName, text: Strin
)
}
private fun patchRootPartNamesInStrings(
className: FqName,
oldPackage: FqName,
isJvmName: Boolean,
text: String
): String {
if (!oldPackage.isRoot || isJvmName) return text
return text.replace(
("\"" + oldPackage.child(className.shortName()).asString()).toRegex(),
"\"" + className.asString()
)
}
private fun patchPackages(newPackage: FqName, oldPackage: FqName, text: String): String {
if (oldPackage.isRoot) return text

View File

@@ -5,9 +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
import com.intellij.openapi.util.io.FileUtilRt
import org.jetbrains.kotlin.cli.common.output.writeAllTo
@@ -19,102 +17,50 @@ import org.jetbrains.kotlin.codegen.GenerationUtils
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
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.psi.KtFile
import org.jetbrains.kotlin.test.*
import org.junit.Assert
import org.junit.Ignore
import java.io.File
import java.io.FileWriter
import java.io.IOException
import kotlin.test.assertTrue
data class ConfigurationKey(val kind: ConfigurationKind, val jdkKind: TestJdkKind, val configuration: String)
class CodegenTestsOnAndroidGenerator private constructor(private val pathManager: PathManager) {
@Ignore
class CodegenTestsOnAndroidGenerator private constructor(private val pathManager: PathManager) : CodegenTestCase() {
private var writtenFilesCount = 0
private var currentModuleIndex = 1
private val pathFilter: String? = System.getProperties().getProperty("kotlin.test.android.path.filter")
private val pendingUnitTestGenerators = hashMapOf<String, UnitTestFileWriter>()
private val pendingUnitTestGenerators = hashMapOf<Int, UnitTestFileWriter>()
//keep it globally to avoid test grouping on TC
private val generatedTestNames = hashSetOf<String>()
private val COMMON = FlavorConfig("common", 3);
private val REFLECT = FlavorConfig("reflect", 1);
private val JVM8 = FlavorConfig("jvm8", 1);
private val JVM8REFLECT = FlavorConfig("reflectjvm8", 1);
class FlavorConfig(private val prefix: String, val limit: Int) {
private var writtenFilesCount = 0
fun printStatistics() {
println("FlavorTestCompiler: $prefix, generated file count: $writtenFilesCount")
}
fun getFlavorForNewFiles(newFilesCount: Int): String {
writtenFilesCount += newFilesCount
//2500 files per folder that would be used by flavor to avoid multidex usage,
// each folder would be jared by build.gradle script
val index = writtenFilesCount / 2500
return getFlavorName(index, prefix).also {
assertTrue("Please Add new flavor in build.gradle for $it") { index < limit }
}
}
private fun getFlavorName(index: Int, prefix: String): String {
return prefix + index
}
fun getFlavorUnitTestFilePath(index: Int): String {
return pathManager.srcFolderInAndroidTmpFolder + "/androidTestKtest$index/java/" + testClassPackage.replace(
".",
"/"
) + "/" + testClassName + "$index.java"
}
private fun prepareAndroidModuleAndGenerateTests(skipSdkDirWriting: Boolean) {
prepareAndroidModule(skipSdkDirWriting)
private fun prepareAndroidModuleAndGenerateTests() {
prepareAndroidModule()
generateTestsAndFlavourSuites()
}
private fun prepareAndroidModule(skipSdkDirWriting: Boolean) {
private fun prepareAndroidModule() {
FileUtil.copyDir(File(pathManager.androidModuleRoot), File(pathManager.tmpFolder))
if (!skipSdkDirWriting) {
writeAndroidSkdToLocalProperties(pathManager)
}
writeAndroidSkdToLocalProperties(pathManager)
println("Copying kotlin-stdlib.jar and kotlin-reflect.jar in android module...")
copyKotlinRuntimeJars()
copyGradleWrapperAndPatch()
}
private fun copyGradleWrapperAndPatch() {
val projectRoot = File(pathManager.tmpFolder)
val target = File(projectRoot, "gradle/wrapper")
File("./gradle/wrapper/").copyRecursively(target)
val gradlew = File(projectRoot, "gradlew")
File("./gradlew").copyTo(gradlew).also {
if (!SystemInfo.isWindows) {
it.setExecutable(true)
}
}
File("./gradlew.bat").copyTo(File(projectRoot, "gradlew.bat"));
val file = File(target, "gradle-wrapper.properties")
file.readLines().map {
when {
it.startsWith("distributionUrl") -> "distributionUrl=https\\://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip"
it.startsWith("distributionSha256Sum") -> "distributionSha256Sum=$GRADLE_SHA_256"
else -> it
}
}.let { lines ->
FileWriter(file).use { fw ->
lines.forEach { line ->
fw.write("$line\n")
}
}
}
}
private fun copyKotlinRuntimeJars() {
FileUtil.copy(
ForTestCompileRuntime.runtimeJarForTests(),
@@ -150,15 +96,9 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
holders.values.forEach {
it.writeFilesOnDisk()
}
COMMON.printStatistics()
REFLECT.printStatistics()
JVM8.printStatistics()
JVM8REFLECT.printStatistics()
}
internal inner class FilesWriter(
private val flavorConfig: FlavorConfig,
private val configuration: CompilerConfiguration
) {
private val rawFiles = arrayListOf<TestClassInfo>()
@@ -173,40 +113,38 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
}
fun writeFilesOnDisk() {
val disposable = Disposer.newDisposable()
val disposable = TestDisposable()
val environment = KotlinCoreEnvironment.createForTests(
disposable,
configuration.copy().apply { put(CommonConfigurationKeys.MODULE_NAME, "android-module-" + currentModuleIndex++) },
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
try {
writeFiles(
rawFiles.map {
try {
CodegenTestFiles.create(it.name, it.content, environment.project).psiFile
} catch (e: Throwable) {
throw RuntimeException("Error on processing ${it.name}:\n${it.content}", e)
}
}, environment, unitTestDescriptions
)
} finally {
rawFiles.clear()
unitTestDescriptions.clear()
Disposer.dispose(disposable)
}
writeFiles(
rawFiles.map {
try {
CodegenTestFiles.create(it.name, it.content, environment.project).psiFile
} catch (e: Throwable) {
throw RuntimeException("Error on processing ${it.name}:\n${it.content}", e)
}
}, environment
)
Disposer.dispose(disposable)
rawFiles.clear()
unitTestDescriptions.clear()
}
private fun writeFiles(
filesToCompile: List<KtFile>,
environment: KotlinCoreEnvironment,
unitTestDescriptions: ArrayList<TestInfo>
) {
private fun writeFiles(filesToCompile: List<KtFile>, environment: KotlinCoreEnvironment) {
if (filesToCompile.isEmpty()) return
val flavorName = flavorConfig.getFlavorForNewFiles(filesToCompile.size)
//2500 files per folder that would be used by flavor to avoid multidex usage,
// each folder would be jared by build.gradle script
writtenFilesCount += filesToCompile.size
val index = writtenFilesCount / 2500
val outputDir = File(pathManager.getOutputForCompiledFiles(index))
assertTrue("Add flavors for ktest$index", index < 3)
val outputDir = File(pathManager.getOutputForCompiledFiles(flavorName))
println("Generating ${filesToCompile.size} files into ${outputDir.name}, configuration: '${environment.configuration}'...")
val outputFiles = GenerationUtils.compileFiles(filesToCompile, environment).run { destroy(); factory }
@@ -215,10 +153,10 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
outputDir.mkdirs()
}
Assert.assertTrue("Cannot create directory for compiled files", outputDir.exists())
val unitTestFileWriter = pendingUnitTestGenerators.getOrPut(flavorName) {
val unitTestFileWriter = pendingUnitTestGenerators.getOrPut(index) {
UnitTestFileWriter(
getFlavorUnitTestFolder(flavorName),
flavorName,
getFlavorUnitTestFilePath(index),
index,
generatedTestNames
)
}
@@ -226,12 +164,6 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
outputFiles.writeAllTo(outputDir)
}
private fun getFlavorUnitTestFolder(flavourName: String): String {
return pathManager.srcFolderInAndroidTmpFolder +
"/androidTest${flavourName.capitalize()}/java/" +
testClassPackage.replace(".", "/") + "/"
}
fun addTest(testFiles: List<TestClassInfo>, info: TestInfo) {
rawFiles.addAll(testFiles)
unitTestDescriptions.add(info)
@@ -248,6 +180,9 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
}
for (file in files) {
if (SpecialFiles.getExcludedFiles().contains(file.name)) {
continue
}
if (file.isDirectory) {
val listFiles = file.listFiles()
if (listFiles != null) {
@@ -260,9 +195,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
continue
}
if (!InTextDirectivesUtils.isPassingTarget(TargetBackend.JVM, file) ||
InTextDirectivesUtils.isIgnoredTarget(TargetBackend.ANDROID, file)
) {
if (!InTextDirectivesUtils.isPassingTarget(TargetBackend.JVM, file)) {
continue
}
@@ -278,32 +211,23 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
if (fullFileText.contains("@file:JvmPackageName(")) continue
// TODO: Support jvm assertions
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 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 JVM 8 test with D8
if (fullFileText.contains("// JVM_TARGET")) continue
// TODO: support SKIP_JDK6 on new platforms
if (fullFileText.contains("// SKIP_JDK6")) continue
if (hasBoxMethod(fullFileText)) {
val testFiles = createTestFiles(file, fullFileText)
val kind = KotlinBaseTest.extractConfigurationKind(testFiles)
val jdkKind = KotlinBaseTest.getTestJdkKind(testFiles)
val kind = extractConfigurationKind(testFiles)
val jdkKind = getJdkKind(testFiles)
val keyConfiguration = CompilerConfiguration()
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
val compiler = if (isJvm8Target) {
if (kind.withReflection) JVM8REFLECT else JVM8
} else if (kind.withReflection) REFLECT else COMMON
val filesHolder = holders.getOrPut(key) {
FilesWriter(compiler, KotlinTestUtils.newConfiguration(kind, jdkKind, KotlinTestUtils.getAnnotationsJar()).apply {
FilesWriter(KotlinTestUtils.newConfiguration(kind, jdkKind, KotlinTestUtils.getAnnotationsJar()).apply {
println("Creating new configuration by $key")
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, this)
updateConfigurationByDirectivesInTestFiles(testFiles, this)
})
}
@@ -313,12 +237,19 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
}
}
private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> =
CodegenTestCase.createTestFilesFromFile(file, expectedText, "kotlin.coroutines", false, TargetBackend.JVM)
private fun createTestFiles(file: File, expectedText: String): List<TestFile> =
TestFiles.createTestFiles(
file.name,
expectedText,
object : TestFiles.TestFileFactoryNoModules<TestFile>() {
override fun create(fileName: String, text: String, directives: Map<String, String>): TestFile {
return TestFile(fileName, text)
}
}, false,
"kotlin.coroutines"
)
companion object {
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"
@@ -326,11 +257,10 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
const val generatorName = "CodegenTestsOnAndroidGenerator"
@JvmOverloads
@JvmStatic
@Throws(Throwable::class)
fun generate(pathManager: PathManager, skipSdkDirWriting: Boolean = false) {
CodegenTestsOnAndroidGenerator(pathManager).prepareAndroidModuleAndGenerateTests(skipSdkDirWriting)
fun generate(pathManager: PathManager) {
CodegenTestsOnAndroidGenerator(pathManager).prepareAndroidModuleAndGenerateTests()
}
private fun hasBoxMethod(text: String): Boolean {
@@ -339,7 +269,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
@Throws(IOException::class)
internal fun writeAndroidSkdToLocalProperties(pathManager: PathManager) {
val sdkRoot = KotlinTestUtils.getAndroidSdkSystemIndependentPath()
val sdkRoot = File(pathManager.androidSdkRoot).invariantSeparatorsPath
println("Writing android sdk to local.properties: $sdkRoot")
val file = File(pathManager.tmpFolder + "/local.properties")
FileWriter(file).use { fw -> fw.write("sdk.dir=$sdkRoot") }
@@ -351,8 +281,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
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.absolutePath + " folder")
generate(pathManager)
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.android.tests;
import java.util.HashSet;
import java.util.Set;
public class SpecialFiles {
private static final Set<String> excludedFiles = new HashSet<>();
static {
fillExcludedFiles();
}
public static Set<String> getExcludedFiles() {
return excludedFiles;
}
private static void fillExcludedFiles() {
// Reflection
excludedFiles.add("enclosing");
excludedFiles.add("kt10259.kt");
excludedFiles.add("simpleClassLiteral.kt");
//UnsatisfiedLinkError
excludedFiles.add("nativePropertyAccessors.kt");
excludedFiles.add("topLevel.kt");
//Test with no reflection at runtime
excludedFiles.add("noReflectAtRuntime");
excludedFiles.add("noReflect");
excludedFiles.add("functionNtoStringNoReflect.kt");
excludedFiles.add("getDelegateWithoutReflection.kt");
// "IOOBE: Invalid index 4, size is 4" for java.lang.reflect.ParameterizedType on Android
excludedFiles.add("innerGenericTypeArgument.kt");
// Cannot change package name
excludedFiles.add("kt6990.kt");
excludedFiles.add("typeParameters.kt");
excludedFiles.add("kt13133.kt");
// StackOverflow with StringBuilder (escape())
excludedFiles.add("kt684.kt");
// Wrong enclosing info or signature after package renaming
excludedFiles.add("enclosingInfo");
excludedFiles.add("signature");
// Some classes are not visible on android
excludedFiles.add("classpath.kt");
// Out of memory
excludedFiles.add("manyNumbers.kt");
// Native methods
excludedFiles.add("external");
// Additional nested class in 'Thread' class on Android
excludedFiles.add("nestedClasses.kt");
// KT-8120
excludedFiles.add("closureOfInnerLocalClass.kt");
excludedFiles.add("closureWithSelfInstantiation.kt");
excludedFiles.add("quotedClassName.kt");
//wrong function resolution after package renaming
excludedFiles.add("apiVersionAtLeast1.kt");
//special symbols in names
excludedFiles.add("nameWithWhitespace.kt");
//some classes are moved from stdlib to compatibility package
excludedFiles.add("suspendFunction_1_2.kt");
}
private SpecialFiles() {
}
}

View File

@@ -15,11 +15,7 @@ import java.io.FileWriter
class TestInfo(val name: String, val fqName: FqName, val file: File)
class UnitTestFileWriter(
private val flavourFolder: String,
private val flavourName: String,
private val generatedTestNames: MutableSet<String>
) {
class UnitTestFileWriter(private val fileName: String, private val index: Int, private val generatedTestNames: MutableSet<String>) {
private val infos = arrayListOf<TestInfo>()
fun addTests(info: List<TestInfo>) {
@@ -27,7 +23,7 @@ class UnitTestFileWriter(
}
fun generate() {
FileWriter(File(flavourFolder, flavourName.capitalize() + ".java").also { it.parentFile.mkdirs() }).use { suite ->
FileWriter(File(fileName).also { it.parentFile.mkdirs() }).use { suite ->
val p = Printer(suite)
p.println(
"""package ${CodegenTestsOnAndroidGenerator.testClassPackage};
@@ -35,7 +31,7 @@ class UnitTestFileWriter(
|import ${CodegenTestsOnAndroidGenerator.baseTestClassPackage}.${CodegenTestsOnAndroidGenerator.baseTestClassName};
|
|/* This class is generated by ${CodegenTestsOnAndroidGenerator.generatorName}. DO NOT MODIFY MANUALLY */
|public class ${flavourName.capitalize()} extends ${CodegenTestsOnAndroidGenerator.baseTestClassName} {
|public class ${CodegenTestsOnAndroidGenerator.testClassName}$index extends ${CodegenTestsOnAndroidGenerator.baseTestClassName} {
|
""".trimMargin()
)

View File

@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
@@ -23,7 +24,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.getExceptionMessage
import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
@@ -55,8 +55,14 @@ object CodegenUtil {
@JvmOverloads
fun getNonPrivateTraitMethods(descriptor: ClassDescriptor, copy: Boolean = true): Map<FunctionDescriptor, FunctionDescriptor> {
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) {
if (declaration !is CallableMemberDescriptor) continue
val traitMember = findInterfaceImplementation(declaration)
if (traitMember == null ||
Visibilities.isPrivate(traitMember.visibility) ||
traitMember.visibility == Visibilities.INVISIBLE_FAKE) continue
for ((declaration, traitMember) in getNonPrivateTraitMembersForDelegation(descriptor)) {
assert(traitMember.modality !== Modality.ABSTRACT) { "Cannot delegate to abstract trait method: $declaration" }
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
@@ -87,18 +93,20 @@ object CodegenUtil {
private fun mapMembers(
inherited: CallableMemberDescriptor,
traitMember: CallableMemberDescriptor
): Map<FunctionDescriptor, FunctionDescriptor> = when (traitMember) {
is SimpleFunctionDescriptor -> mapOf(traitMember to inherited as FunctionDescriptor)
is PropertyDescriptor -> linkedMapOf<FunctionDescriptor, FunctionDescriptor>().also { result ->
): LinkedHashMap<FunctionDescriptor, FunctionDescriptor> {
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
if (traitMember is SimpleFunctionDescriptor) {
result[traitMember] = inherited as FunctionDescriptor
} else if (traitMember is PropertyDescriptor) {
for (traitAccessor in traitMember.accessors) {
for (inheritedAccessor in (inherited as PropertyDescriptor).accessors) {
if ((inheritedAccessor is PropertyGetterDescriptor) == (traitAccessor is PropertyGetterDescriptor)) {
result[traitAccessor] = inheritedAccessor
if (inheritedAccessor::class.java == traitAccessor::class.java) { // same accessor kind
result.put(traitAccessor, inheritedAccessor)
}
}
}
}
else -> error("Unexpected member: $inherited")
return result
}
@JvmStatic

View File

@@ -16,11 +16,17 @@
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.common.CodegenUtil.getMemberToGenerate
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
/**
* A platform-independent logic for generating data class synthetic methods.

View File

@@ -18,16 +18,15 @@ package org.jetbrains.kotlin.backend.common.bridges
import org.jetbrains.kotlin.utils.DFS
import java.util.*
import kotlin.collections.LinkedHashMap
interface FunctionHandle {
val isDeclaration: Boolean
val isAbstract: Boolean
/** On finding concrete super declaration we should distinguish non-abstract java8/js default methods from
* class ones (see [findConcreteSuperDeclaration] method in bridges.kt).
* Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation
* (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/
* class ones (see [findConcreteSuperDeclaration] method in bridges.kt).
* Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation
* (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/
val mayBeUsedAsSuperImplementation: Boolean
fun getOverridden(): Iterable<FunctionHandle>
@@ -35,19 +34,18 @@ interface FunctionHandle {
val mightBeIncorrectCode: Boolean get() = false
}
data class Bridge<out Signature, out Function : FunctionHandle>(
val from: Signature,
val to: Signature,
val originalFunctions: Set<Function>
data class Bridge<out Signature>(
val from: Signature,
val to: Signature
) {
override fun toString() = "$from -> $to"
}
fun <Function : FunctionHandle, Signature> generateBridges(
function: Function,
signature: (Function) -> Signature
): Set<Bridge<Signature, Function>> {
function: Function,
signature: (Function) -> Signature
): Set<Bridge<Signature>> {
// If it's an abstract function, no bridges are needed: when an implementation will appear in some concrete subclass, all necessary
// bridges will be generated there
if (function.isAbstract) return setOf()
@@ -60,7 +58,7 @@ fun <Function : FunctionHandle, Signature> generateBridges(
val implementation = findConcreteSuperDeclaration(function) ?: return setOf()
val bridgesToGenerate = findAllReachableDeclarations(function).groupByTo(LinkedHashMap(), signature)
val bridgesToGenerate = findAllReachableDeclarations(function).mapTo(LinkedHashSet<Signature>(), signature)
if (fake) {
// If it's a concrete fake override, some of the bridges may be inherited from the super-classes. Specifically, bridges for all
@@ -69,20 +67,14 @@ fun <Function : FunctionHandle, Signature> generateBridges(
@Suppress("UNCHECKED_CAST")
for (overridden in function.getOverridden() as Iterable<Function>) {
if (!overridden.isAbstract) {
for (reachable in findAllReachableDeclarations(overridden)) {
bridgesToGenerate.remove(signature(reachable))
}
bridgesToGenerate.removeAll(findAllReachableDeclarations(overridden).map(signature))
}
}
}
val method = signature(implementation)
bridgesToGenerate.remove(method)
return bridgesToGenerate.entries
.map { (overriddenSignature, overriddenFunctions) ->
Bridge(overriddenSignature, method, overriddenFunctions.toSet())
}
.toSet()
return bridgesToGenerate.map { Bridge(it, method) }.toSet()
}
fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
@@ -103,7 +95,7 @@ fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function)
* The implementation is guaranteed to exist because if it wouldn't, the given function would've been abstract
*/
fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function? {
require(!function.isAbstract) { "Only concrete functions have implementations: $function" }
require(!function.isAbstract, { "Only concrete functions have implementations: $function" })
if (function.isDeclaration) return function

View File

@@ -24,13 +24,11 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.util.findImplementationFromInterface
import org.jetbrains.kotlin.util.findInterfaceImplementation
fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature
): Set<Bridge<Signature, DescriptorBasedFunctionHandle>> {
): Set<Bridge<Signature>> {
return generateBridges(DescriptorBasedFunctionHandle(descriptor), { signature(it.descriptor) })
}
@@ -83,4 +81,55 @@ open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F
override fun toString(): String {
return descriptor.toString()
}
}
}
/**
* Given a fake override in a class, returns an overridden declaration with implementation in trait, such that a method delegating to that
* trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake
* override of any trait implementation or such method was already generated into the superclass or is a method from Any.
*/
fun findInterfaceImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
if (descriptor.kind.isReal) return null
if (isOrOverridesSynthesized(descriptor)) return null
val implementation = findImplementationFromInterface(descriptor) ?: return null
val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null
if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) {
// If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited
return null
}
return immediateConcreteSuper
}
/**
* Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function
* that should be called when the given fake override is called.
*/
fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
val overridden = OverridingUtil.getOverriddenDeclarations(descriptor)
val filtered = OverridingUtil.filterOutOverridden(overridden)
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null
return result
}
/**
* Given a fake override and its implementation (non-abstract declaration) somewhere in supertypes,
* returns the first immediate super function of the given fake override which overrides that implementation.
* The returned function should be called from TImpl-bridges generated for the given fake override.
*/
fun firstSuperMethodFromKotlin(
descriptor: CallableMemberDescriptor,
implementation: CallableMemberDescriptor
): CallableMemberDescriptor? {
return descriptor.overriddenDescriptors.firstOrNull { overridden ->
overridden.modality != Modality.ABSTRACT &&
(overridden == implementation || OverridingUtil.overrides(overridden, implementation, overridden.module.isTypeRefinementEnabled()))
}
}

View File

@@ -21,7 +21,6 @@ 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.*;
@@ -39,6 +38,8 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
private final List<FileMapping> fileMappings = new ArrayList<>();
private String sourceName;
private String debugInfo;
@@ -105,7 +106,15 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
@Override
public void done() {
getVisitor().visitSource(sourceName, debugInfo);
if (!fileMappings.isEmpty() && GENERATE_SMAP) {
FileMapping origin = fileMappings.get(0);
assert sourceName == null || origin.getName().equals(sourceName) : "Error " + origin.getName() + " != " + sourceName;
getVisitor().visitSource(origin.getName(), new SMAPBuilder(origin.getName(), origin.getPath(), fileMappings).build());
}
else {
getVisitor().visitSource(sourceName, debugInfo);
}
getVisitor().visitEnd();
}
@@ -125,21 +134,10 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
@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);
@@ -156,4 +154,9 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
assert thisName != null : "This name isn't set";
return thisName;
}
@Override
public void addSMAP(FileMapping mapping) {
fileMappings.add(mapping);
}
}

View File

@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.descriptors.annotations.*;
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
@@ -41,6 +40,7 @@ import org.jetbrains.kotlin.types.FlexibleType;
import org.jetbrains.kotlin.types.FlexibleTypesKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext;
import org.jetbrains.org.objectweb.asm.*;
import java.lang.annotation.*;
@@ -90,18 +90,12 @@ public abstract class AnnotationCodegen {
private final KotlinTypeMapper typeMapper;
private final ModuleDescriptor module;
private final GenerationState state;
private final boolean skipNullabilityAnnotations;
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state) {
this(innerClassConsumer, state, false);
}
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state, boolean skipNullabilityAnnotations) {
this.innerClassConsumer = innerClassConsumer;
this.typeMapper = state.getTypeMapper();
this.module = state.getModule();
this.state = state;
this.skipNullabilityAnnotations = skipNullabilityAnnotations;
}
/**
@@ -111,16 +105,6 @@ public abstract class AnnotationCodegen {
@Nullable Annotated annotated,
@Nullable Type returnType,
@Nullable KotlinType typeForTypeAnnotations
) {
genAnnotations(annotated, returnType, typeForTypeAnnotations, null, Collections.emptyList());
}
public void genAnnotations(
@Nullable Annotated annotated,
@Nullable Type returnType,
@Nullable KotlinType typeForTypeAnnotations,
@Nullable DeclarationDescriptorWithVisibility parameterContainer,
@NotNull List<Class<?>> additionalAnnotations
) {
if (annotated == null) return;
@@ -155,28 +139,22 @@ public abstract class AnnotationCodegen {
}
}
for (Class<?> annotation : additionalAnnotations) {
String descriptor = generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, annotation);
annotationDescriptorsAlreadyPresent.add(descriptor);
}
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent, parameterContainer);
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent);
generateTypeAnnotations(annotated, typeForTypeAnnotations);
}
private void generateAdditionalAnnotations(
@NotNull Annotated annotated,
@Nullable Type returnType,
@NotNull Set<String> annotationDescriptorsAlreadyPresent,
@Nullable DeclarationDescriptorWithVisibility parameterContainer
@NotNull Set<String> annotationDescriptorsAlreadyPresent
) {
if (annotated instanceof CallableDescriptor) {
generateAdditionalCallableAnnotations((CallableDescriptor) annotated, returnType, annotationDescriptorsAlreadyPresent, parameterContainer);
generateAdditionalCallableAnnotations((CallableDescriptor) annotated, returnType, annotationDescriptorsAlreadyPresent);
}
else if (annotated instanceof FieldDescriptor) {
generateAdditionalCallableAnnotations(
((FieldDescriptor) annotated).getCorrespondingProperty(), returnType, annotationDescriptorsAlreadyPresent,
parameterContainer);
((FieldDescriptor) annotated).getCorrespondingProperty(), returnType, annotationDescriptorsAlreadyPresent
);
}
else if (annotated instanceof ClassDescriptor) {
generateAdditionalClassAnnotations(annotationDescriptorsAlreadyPresent, (ClassDescriptor) annotated);
@@ -186,15 +164,11 @@ public abstract class AnnotationCodegen {
private void generateAdditionalCallableAnnotations(
@NotNull CallableDescriptor descriptor,
@Nullable Type returnType,
@NotNull Set<String> annotationDescriptorsAlreadyPresent,
@Nullable DeclarationDescriptorWithVisibility parameterContainer
@NotNull Set<String> annotationDescriptorsAlreadyPresent
) {
// No need to annotate privates, synthetic accessors and their parameters
if (isInvisibleFromTheOutside(descriptor)) return;
if (descriptor instanceof ParameterDescriptor &&
isInvisibleFromTheOutside(parameterContainer != null ? parameterContainer : descriptor.getContainingDeclaration())) {
return;
}
if (descriptor instanceof ValueParameterDescriptor && isInvisibleFromTheOutside(descriptor.getContainingDeclaration())) return;
// No need to annotate annotation methods since they're always non-null
if (descriptor instanceof PropertyGetterDescriptor &&
@@ -202,7 +176,7 @@ public abstract class AnnotationCodegen {
return;
}
if (returnType != null && !AsmUtil.isPrimitive(returnType) && !skipNullabilityAnnotations) {
if (returnType != null && !AsmUtil.isPrimitive(returnType)) {
generateNullabilityAnnotation(descriptor.getReturnType(), annotationDescriptorsAlreadyPresent);
}
}
@@ -280,11 +254,12 @@ public abstract class AnnotationCodegen {
jvm8.put(KotlinTarget.TYPE, ElementType.TYPE_USE);
annotationTargetMaps.put(JvmTarget.JVM_1_6, jvm6);
for (JvmTarget target : JvmTarget.values()) {
if (target != JvmTarget.JVM_1_6) {
annotationTargetMaps.put(target, jvm8);
}
}
annotationTargetMaps.put(JvmTarget.JVM_1_8, jvm8);
annotationTargetMaps.put(JvmTarget.JVM_9, jvm8);
annotationTargetMaps.put(JvmTarget.JVM_10, jvm8);
annotationTargetMaps.put(JvmTarget.JVM_11, jvm8);
annotationTargetMaps.put(JvmTarget.JVM_12, jvm8);
annotationTargetMaps.put(JvmTarget.JVM_13, jvm8);
}
private void generateTargetAnnotation(
@@ -338,13 +313,11 @@ public abstract class AnnotationCodegen {
visitor.visitEnd();
}
@NotNull
private String generateAnnotationIfNotPresent(Set<String> annotationDescriptorsAlreadyPresent, Class<?> annotationClass) {
private void generateAnnotationIfNotPresent(Set<String> annotationDescriptorsAlreadyPresent, Class<?> annotationClass) {
String descriptor = Type.getType(annotationClass).getDescriptor();
if (!annotationDescriptorsAlreadyPresent.contains(descriptor)) {
visitAnnotation(descriptor, false).visitEnd();
}
return descriptor;
}
private static boolean isBareTypeParameterWithNullableUpperBound(@NotNull KotlinType type) {
@@ -461,13 +434,8 @@ public abstract class AnnotationCodegen {
@Override
public Void visitEnumValue(EnumValue value, Void data) {
ClassId enumClassId = value.getEnumClassId();
String enumClassInternalName = AsmUtil.asmTypeByClassId(enumClassId).getDescriptor();
String enumClassInternalName = AsmUtil.asmTypeByClassId(value.getEnumClassId()).getDescriptor();
String enumEntryName = value.getEnumEntryName().asString();
ClassDescriptor descriptor = FindClassInModuleKt.findClassAcrossModuleDependencies(state.getModule(), enumClassId);
if (descriptor != null) {
innerClassConsumer.addInnerClassInfoFromAnnotation(descriptor);
}
annotationVisitor.visitEnum(name, enumClassInternalName, enumEntryName);
return null;
}
@@ -484,9 +452,8 @@ public abstract class AnnotationCodegen {
@Override
public Void visitAnnotationValue(AnnotationValue value, Void data) {
KotlinType classType = value.getValue().getType();
innerClassConsumer.addInnerClassInfoFromAnnotation(DescriptorUtils.getClassDescriptorForType(classType));
AnnotationVisitor visitor = annotationVisitor.visitAnnotation(name, typeMapper.mapType(classType).getDescriptor());
String internalAnnName = typeMapper.mapType(value.getValue().getType()).getDescriptor();
AnnotationVisitor visitor = annotationVisitor.visitAnnotation(name, internalAnnName);
genAnnotationArguments(value.getValue(), visitor);
visitor.visitEnd();
return null;
@@ -494,9 +461,7 @@ public abstract class AnnotationCodegen {
@Override
public Void visitKClassValue(KClassValue value, Void data) {
KotlinType classType = value.getArgumentType(module);
innerClassConsumer.addInnerClassInfoFromAnnotation(DescriptorUtils.getClassDescriptorForType(classType));
annotationVisitor.visit(name, typeMapper.mapType(classType));
annotationVisitor.visit(name, typeMapper.mapType(value.getArgumentType(module)));
return null;
}
@@ -628,16 +593,7 @@ public abstract class AnnotationCodegen {
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state
) {
return forMethod(mv, innerClassConsumer, state, false);
}
public static AnnotationCodegen forMethod(
@NotNull MethodVisitor mv,
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state,
boolean skipNullabilityAnnotations
) {
return new AnnotationCodegen(innerClassConsumer, state, skipNullabilityAnnotations) {
return new AnnotationCodegen(innerClassConsumer, state) {
@NotNull
@Override
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
@@ -657,16 +613,7 @@ public abstract class AnnotationCodegen {
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state
) {
return forField(fv, innerClassConsumer, state, false);
}
public static AnnotationCodegen forField(
@NotNull FieldVisitor fv,
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state,
boolean skipNullabilityAnnotations
) {
return new AnnotationCodegen(innerClassConsumer, state, skipNullabilityAnnotations) {
return new AnnotationCodegen(innerClassConsumer, state) {
@NotNull
@Override
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
@@ -685,10 +632,9 @@ public abstract class AnnotationCodegen {
int parameter,
@NotNull MethodVisitor mv,
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state,
boolean skipNullabilityAnnotations
@NotNull GenerationState state
) {
return new AnnotationCodegen(innerClassConsumer, state, skipNullabilityAnnotations) {
return new AnnotationCodegen(innerClassConsumer, state) {
@NotNull
@Override
AnnotationVisitor visitAnnotation(String descr, boolean visible) {

View File

@@ -17,13 +17,11 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.mapToIndex
@@ -37,10 +35,10 @@ abstract class ArgumentGenerator {
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
*/
open fun generate(
valueArgumentsByIndex: List<ResolvedValueArgument>,
actualArgs: List<ResolvedValueArgument>,
// may be null for a constructor of an object literal
calleeDescriptor: CallableDescriptor?
valueArgumentsByIndex: List<ResolvedValueArgument>,
actualArgs: List<ResolvedValueArgument>,
// may be null for a constructor of an object literal
calleeDescriptor: CallableDescriptor?
): DefaultCallArgs {
assert(valueArgumentsByIndex.size == actualArgs.size) {
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
@@ -52,9 +50,9 @@ abstract class ArgumentGenerator {
ArgumentAndDeclIndex(it, arg2Index[it]!!)
}.toMutableList()
for ((index, value) in valueArgumentsByIndex.withIndex()) {
if (value is DefaultValueArgument) {
actualArgsWithDeclIndex.add(index, ArgumentAndDeclIndex(value, index))
valueArgumentsByIndex.withIndex().forEach {
if (it.value is DefaultValueArgument) {
actualArgsWithDeclIndex.add(it.index, ArgumentAndDeclIndex(it.value, it.index))
}
}
@@ -72,7 +70,8 @@ abstract class ArgumentGenerator {
is DefaultValueArgument -> {
if (calleeDescriptor?.defaultValueFromJava(declIndex) == true) {
generateDefaultJava(declIndex, argument)
} else {
}
else {
defaultArgs.mark(declIndex)
generateDefault(declIndex, argument)
}
@@ -117,42 +116,11 @@ abstract class ArgumentGenerator {
}
private fun CallableDescriptor.defaultValueFromJava(index: Int): Boolean = DFS.ifAny(
listOf(this),
{ current -> current.original.overriddenDescriptors.map { it.original } },
{ descriptor ->
descriptor.original.overriddenDescriptors.isEmpty() &&
descriptor is JavaCallableMemberDescriptor &&
descriptor.valueParameters[index].declaresDefaultValue()
}
listOf(this),
{ current -> current.original.overriddenDescriptors.map { it.original } },
{ descriptor ->
descriptor.original.overriddenDescriptors.isEmpty() &&
descriptor is JavaCallableMemberDescriptor &&
descriptor.valueParameters[index].declaresDefaultValue()
}
)
fun shouldInvokeDefaultArgumentsStub(resolvedCall: ResolvedCall<*>): Boolean {
val descriptor = resolvedCall.resultingDescriptor
val valueArgumentsByIndex = resolvedCall.valueArgumentsByIndex ?: return false
for (index in valueArgumentsByIndex.indices) {
val resolvedValueArgument = valueArgumentsByIndex[index]
if (resolvedValueArgument is DefaultValueArgument && !descriptor.defaultValueFromJava(index)) {
return true
}
}
return false
}
fun getFunctionWithDefaultArguments(functionDescriptor: FunctionDescriptor): FunctionDescriptor {
if (functionDescriptor.containingDeclaration !is ClassDescriptor) return functionDescriptor
if (functionDescriptor.overriddenDescriptors.isEmpty()) return functionDescriptor
// We are calling a function with some arguments mapped as defaults.
// Multiple override-equivalent functions from different supertypes with (potentially different) default values
// can't be overridden by any function in a subtype.
// Also, a function overriding some other function can't introduce default parameter values.
// Thus, among all overridden functions should be one (and only one) function
// that doesn't override anything and has parameters with default values.
return functionDescriptor.overriddenTreeUniqueAsSequence(true)
.firstOrNull { function ->
function.kind == CallableMemberDescriptor.Kind.DECLARATION &&
function.overriddenDescriptors.isEmpty() &&
function.valueParameters.any { valueParameter -> valueParameter.hasDefaultValue() }
}
?: functionDescriptor
}

View File

@@ -22,7 +22,10 @@ import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.*;
import org.jetbrains.kotlin.config.ApiVersion;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
@@ -39,10 +42,10 @@ import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver;
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.jvm.*;
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
@@ -66,6 +69,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineWithReified;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmSyntheticAnnotation;
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -305,10 +309,9 @@ public class AsmUtil {
return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes));
}
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind, JvmDefaultMode jvmDefaultMode) {
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
return (functionDescriptor.getModality() == Modality.ABSTRACT ||
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !JvmAnnotationUtilKt
.isCompiledToJvmDefault(functionDescriptor, jvmDefaultMode)))
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !hasJvmDefaultAnnotation(functionDescriptor)))
&& !isStaticMethod(kind, functionDescriptor);
}
@@ -323,15 +326,10 @@ public class AsmUtil {
}
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) {
return getMethodAsmFlags(functionDescriptor, kind, state.getDeprecationProvider(), state.getJvmDefaultMode());
return getMethodAsmFlags(functionDescriptor, kind, state.getDeprecationProvider());
}
public static int getMethodAsmFlags(
FunctionDescriptor functionDescriptor,
OwnerKind kind,
DeprecationResolver deprecationResolver,
JvmDefaultMode jvmDefaultMode
) {
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, DeprecationResolver deprecationResolver) {
int flags = getCommonCallableFlags(functionDescriptor, kind, deprecationResolver);
for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.METHOD_FLAGS) {
@@ -359,7 +357,7 @@ public class AsmUtil {
flags |= ACC_STATIC;
}
if (isAbstractMethod(functionDescriptor, kind, jvmDefaultMode)) {
if (isAbstractMethod(functionDescriptor, kind)) {
flags |= ACC_ABSTRACT;
}
@@ -432,6 +430,9 @@ public class AsmUtil {
if (descriptor instanceof SyntheticClassDescriptorForLambda) {
return getVisibilityAccessFlagForAnonymous(descriptor);
}
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor)) {
return NO_FLAG_PACKAGE_PRIVATE;
}
if (descriptor.getKind() == ClassKind.ENUM_ENTRY) {
return NO_FLAG_PACKAGE_PRIVATE;
}
@@ -1022,7 +1023,9 @@ public class AsmUtil {
}
value.put(asmType, v);
v.visitLdcInsn(name);
String methodName = state.getUnifiedNullChecks() ? "checkNotNullParameter" : "checkParameterIsNotNull";
String methodName = state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_4) >= 0
? "checkNotNullParameter"
: "checkParameterIsNotNull";
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, methodName, "(Ljava/lang/Object;Ljava/lang/String;)V", false);
}
}
@@ -1045,7 +1048,9 @@ public class AsmUtil {
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
v.dup();
v.visitLdcInsn(runtimeAssertionInfo.getMessage());
String methodName = state.getUnifiedNullChecks() ? "checkNotNullExpressionValue" : "checkExpressionValueIsNotNull";
String methodName = state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_4) >= 0
? "checkNotNullExpressionValue"
: "checkExpressionValueIsNotNull";
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, methodName, "(Ljava/lang/Object;Ljava/lang/String;)V", false);
}
StackValue.coerce(innerType, innerKotlinType, type, kotlinType, v);
@@ -1076,23 +1081,27 @@ public class AsmUtil {
}
public static void pushDefaultValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) {
v.visitInsn(defaultValueOpcode(type));
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
v.aconst(null);
}
else {
pushDefaultPrimitiveValueOnStack(type, v);
}
}
public static int defaultValueOpcode(@NotNull Type type) {
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
return ACONST_NULL;
}
public static void pushDefaultPrimitiveValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) {
if (type.getSort() == Type.FLOAT) {
return FCONST_0;
v.fconst(0);
}
if (type.getSort() == Type.DOUBLE) {
return DCONST_0;
else if (type.getSort() == Type.DOUBLE) {
v.dconst(0);
}
if (type.getSort() == Type.LONG) {
return LCONST_0;
else if (type.getSort() == Type.LONG) {
v.lconst(0);
}
else {
v.iconst(0);
}
return ICONST_0;
}
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {

View File

@@ -240,9 +240,8 @@ class ObjectCompare(
companion object {
fun getObjectCompareOpcode(opToken: IElementType): Int = when (opToken) {
// "==" and "!=" are here because enum values are compared using reference equality.
KtTokens.EQEQEQ, KtTokens.EQEQ -> IF_ACMPNE
KtTokens.EXCLEQEQEQ, KtTokens.EXCLEQ -> IF_ACMPEQ
KtTokens.EQEQEQ -> IF_ACMPNE
KtTokens.EXCLEQEQEQ -> IF_ACMPEQ
else -> throw UnsupportedOperationException("don't know how to generate this condjump")
}
}

View File

@@ -37,7 +37,7 @@ interface Callable {
fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
// it's important to use unsubstituted return type here to unbox value if it comes from type variable
return StackValue.functionCall(returnType, returnKotlinType ?: resolvedCall.resultingDescriptor.original.returnType) {
return StackValue.functionCall(returnType, resolvedCall.resultingDescriptor.original.returnType) {
codegen.invokeMethodWithArguments(this, resolvedCall, receiver)
}
}

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
@@ -19,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.util.Printer
class CallableMethod(
override val owner: Type,
private val defaultImplOwner: Type?,
computeDefaultMethod: () -> Method,
computeDefaultMethodDesc: () -> String,
private val signature: JvmMethodSignature,
val invokeOpcode: Int,
override val dispatchReceiverType: Type?,
@@ -31,10 +32,7 @@ class CallableMethod(
val isInterfaceMethod: Boolean,
private val isDefaultMethodInInterface: Boolean
) : Callable {
private val defaultImplMethod: Method by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethod)
private val defaultImplMethodName: String get() = defaultImplMethod.name
private val defaultMethodDesc: String get() = defaultImplMethod.descriptor
private val defaultMethodDesc: String by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethodDesc)
fun getValueParameters(): List<JvmMethodParameterSignature> =
signature.valueParameters
@@ -70,14 +68,10 @@ class CallableMethod(
} else {
v.visitMethodInsn(
INVOKESTATIC, defaultImplOwner.internalName,
defaultImplMethodName, defaultMethodDesc, isDefaultMethodInInterface
method.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, isDefaultMethodInInterface
)
StackValue.coerce(
Type.getReturnType(defaultMethodDesc),
Type.getReturnType(signature.asmMethod.descriptor),
v
)
StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v)
}
}

View File

@@ -10,10 +10,10 @@ import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.context.ClassContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptorKt;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
@@ -37,8 +36,8 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
import static org.jetbrains.kotlin.util.DeclarationUtilKt.findInterfaceImplementation;
public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject> {
@NotNull
@@ -125,7 +124,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
if (memberDescriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
if (!member.getKind().isReal() && findInterfaceImplementation(member) == null) {
if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) {
if (member instanceof FunctionDescriptor) {
functionCodegen.generateBridges((FunctionDescriptor) member);
}
@@ -220,29 +219,17 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
protected void generateDelegatesToDefaultImpl() {
if (isJvmInterface(descriptor)) return;
boolean isErasedInlineClass = InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
JvmKotlinType receiverType = new JvmKotlinType(typeMapper.mapType(descriptor), descriptor.getDefaultType());
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
generateDelegationToDefaultImpl(entry.getKey(), entry.getValue(), receiverType, functionCodegen, state, isErasedInlineClass);
FunctionDescriptor interfaceFun = entry.getKey();
//skip java 8 default methods
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !hasJvmDefaultAnnotation(interfaceFun)) {
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
}
}
}
public static void generateDelegationToDefaultImpl(
@NotNull FunctionDescriptor interfaceFun,
@NotNull FunctionDescriptor inheritedFun,
@NotNull JvmKotlinType receiverType,
@NotNull FunctionCodegen functionCodegen,
@NotNull GenerationState state,
boolean isErasedInlineClass
) {
// Skip Java 8 default methods
if (CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) ||
JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(interfaceFun, state.getJvmDefaultMode())) {
return;
}
private void generateDelegationToDefaultImpl(@NotNull FunctionDescriptor interfaceFun, @NotNull FunctionDescriptor inheritedFun) {
KotlinTypeMapper typeMapper = state.getTypeMapper();
functionCodegen.generateMethod(
new JvmDeclarationOrigin(
CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun, null
@@ -257,7 +244,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
PsiElement classForInheritedFun = descriptorToDeclaration(declarationInheritedFun);
if (classForInheritedFun instanceof KtDeclaration) {
codegen.markLineNumber(classForInheritedFun, false);
codegen.markLineNumber((KtElement) classForInheritedFun, false);
}
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
@@ -291,15 +278,18 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
InstructionAdapter iv = codegen.v;
Type[] myArgTypes = signature.getAsmMethod().getArgumentTypes();
Type[] toArgTypes = defaultImplsMethod.getArgumentTypes();
boolean isErasedInlineClass =
InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
int myArgI = 0;
int argVar = 0;
Type receiverType = typeMapper.mapType(descriptor);
KotlinType interfaceKotlinType = ((ClassDescriptor) inheritedFun.getContainingDeclaration()).getDefaultType();
StackValue.local(argVar, receiverType.getType(), receiverType.getKotlinType())
StackValue.local(argVar, receiverType, descriptor.getDefaultType())
.put(OBJECT_TYPE, interfaceKotlinType, iv);
if (isErasedInlineClass) myArgI++;
argVar += receiverType.getType().getSize();
argVar += receiverType.getSize();
int toArgI = 1;

View File

@@ -20,7 +20,6 @@ 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.SourceMapper;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
@@ -72,12 +71,12 @@ public interface ClassBuilder {
void visitSource(@NotNull String name, @Nullable String debug);
void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax);
void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc);
void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access);
@NotNull
String getThisName();
void addSMAP(FileMapping mapping);
}

View File

@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf;
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping;
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMappingKt;
import org.jetbrains.kotlin.metadata.jvm.deserialization.PackageParts;
import org.jetbrains.kotlin.metadata.serialization.StringTable;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtFile;
@@ -130,18 +129,15 @@ public class ClassFileFactory implements OutputFileCollection {
JvmModuleProtoBuf.Module.Builder builder = JvmModuleProtoBuf.Module.newBuilder();
String outputFilePath = getMappingFileName(state.getModuleName());
StringTableImpl stringTable = new StringTableImpl();
ClassFileUtilsKt.addDataFromCompiledModule(builder, packagePartRegistry, stringTable, state);
for (PackageParts part : ClassFileUtilsKt.addCompiledPartsAndSort(packagePartRegistry.getParts().values(), state)) {
part.addTo(builder);
}
List<String> experimental = state.getLanguageVersionSettings().getFlag(AnalysisFlags.getExperimental());
if (!experimental.isEmpty()) {
writeExperimentalMarkers(state.getModule(), builder, experimental, stringTable);
writeExperimentalMarkers(state.getModule(), builder, experimental);
}
Pair<ProtoBuf.StringTable, ProtoBuf.QualifiedNameTable> tables = stringTable.buildProto();
builder.setStringTable(tables.getFirst());
builder.setQualifiedNameTable(tables.getSecond());
JvmModuleProtoBuf.Module moduleProto = builder.build();
generators.put(outputFilePath, new OutAndSourceFileList(CollectionsKt.toList(sourceFiles)) {
@@ -164,9 +160,9 @@ public class ClassFileFactory implements OutputFileCollection {
private static void writeExperimentalMarkers(
@NotNull ModuleDescriptor module,
@NotNull JvmModuleProtoBuf.Module.Builder builder,
@NotNull List<String> experimental,
@NotNull StringTable stringTable
@NotNull List<String> experimental
) {
StringTableImpl stringTable = new StringTableImpl();
for (String fqName : experimental) {
ClassDescriptor descriptor =
DescriptorUtilKt.resolveClassByFqName(module, new FqName(fqName), NoLookupLocation.FOR_ALREADY_TRACKED);
@@ -179,6 +175,9 @@ public class ClassFileFactory implements OutputFileCollection {
}
}
}
Pair<ProtoBuf.StringTable, ProtoBuf.QualifiedNameTable> tables = stringTable.buildProto();
builder.setStringTable(tables.getFirst());
builder.setQualifiedNameTable(tables.getSecond());
}
@NotNull

View File

@@ -12,8 +12,8 @@ import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.ClosureContext;
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.JvmAbi;
@@ -31,11 +32,9 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
import org.jetbrains.kotlin.metadata.ProtoBuf;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.SimpleType;
@@ -51,9 +50,9 @@ import java.util.Collections;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.CallableReferenceUtilKt.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
@@ -65,16 +64,12 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
private final SamType samType;
private final KotlinType superClassType;
private final List<KotlinType> superInterfaceTypes;
private final ResolvedCall<FunctionDescriptor> functionReferenceCall;
private final FunctionDescriptor functionReferenceTarget;
private final FunctionGenerationStrategy strategy;
protected final CalculatedClosure closure;
protected final Type asmType;
protected final int visibilityFlag;
private final boolean shouldHaveBoundReferenceReceiver;
private final boolean isLegacyFunctionReference;
private final boolean isOptimizedFunctionReference;
private final boolean isAdaptedFunctionReference;
private Method constructor;
protected Type superClassAsmType;
@@ -84,7 +79,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
@NotNull KtElement element,
@Nullable SamType samType,
@NotNull ClosureContext context,
@Nullable ResolvedCall<FunctionDescriptor> functionReferenceCall,
@Nullable FunctionDescriptor functionReferenceTarget,
@NotNull FunctionGenerationStrategy strategy,
@NotNull MemberCodegen<?> parentCodegen,
@NotNull ClassBuilder classBuilder
@@ -94,8 +89,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
this.funDescriptor = context.getFunctionDescriptor();
this.classDescriptor = context.getContextDescriptor();
this.samType = samType;
this.functionReferenceCall = functionReferenceCall;
this.functionReferenceTarget = functionReferenceCall != null ? functionReferenceCall.getResultingDescriptor() : null;
this.functionReferenceTarget = functionReferenceTarget;
this.strategy = strategy;
if (samType == null) {
@@ -126,17 +120,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
this.shouldHaveBoundReferenceReceiver = CallableReferenceUtilKt.isForBoundCallableReference(closure);
ClassifierDescriptor superClassDescriptor = superClassType.getConstructor().getDeclarationDescriptor();
this.isLegacyFunctionReference =
functionReferenceTarget != null &&
superClassDescriptor == state.getJvmRuntimeTypes().getFunctionReference();
this.isOptimizedFunctionReference =
functionReferenceTarget != null &&
superClassDescriptor == state.getJvmRuntimeTypes().getFunctionReferenceImpl();
this.isAdaptedFunctionReference =
functionReferenceTarget != null &&
superClassDescriptor == state.getJvmRuntimeTypes().getAdaptedFunctionReference();
this.asmType = typeMapper.mapClass(classDescriptor);
visibilityFlag = AsmUtil.getVisibilityAccessFlagForClass(classDescriptor);
@@ -169,7 +152,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
superInterfaceAsmTypes
);
initDefaultSourceMappingIfNeeded();
initDefaultSourceMappingIfNeeded(context, this, state);
v.visitSource(element.getContainingFile().getName(), null);
}
@@ -185,12 +168,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
generateBridges();
generateClosureBody();
if (samType != null) {
SamWrapperCodegen.generateDelegatesToDefaultImpl(
asmType, classDescriptor, samType.getClassDescriptor(), functionCodegen, state
);
}
this.constructor = generateConstructor();
if (isConst(closure)) {
@@ -203,7 +180,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
protected void generateClosureBody() {
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(element, funDescriptor), funDescriptor, strategy);
if (isLegacyFunctionReference) {
if (functionReferenceTarget != null) {
generateFunctionReferenceMethods(functionReferenceTarget);
}
@@ -249,9 +226,9 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
CallableMemberDescriptor.Kind.DECLARATION, descriptor.getSource());
descriptorForBridges
.initialize(erasedInterfaceFunction.getExtensionReceiverParameter(), erasedInterfaceFunction.getDispatchReceiverParameter(),
erasedInterfaceFunction.getTypeParameters(), erasedInterfaceFunction.getValueParameters(),
erasedInterfaceFunction.getReturnType(), Modality.OPEN, erasedInterfaceFunction.getVisibility());
.initialize(null, erasedInterfaceFunction.getDispatchReceiverParameter(), erasedInterfaceFunction.getTypeParameters(),
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(),
Modality.OPEN, erasedInterfaceFunction.getVisibility());
descriptorForBridges.setSuspend(descriptor.isSuspend());
@@ -265,9 +242,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
assert method != null : "No method for " + frontendFunDescriptor;
FunctionDescriptor freeLambdaDescriptor = FakeDescriptorsForReferencesKt.createFreeFakeLambdaDescriptor(
frontendFunDescriptor, state.getTypeApproximator()
);
FunctionDescriptor freeLambdaDescriptor = FakeDescriptorsForReferencesKt.createFreeFakeLambdaDescriptor(frontendFunDescriptor);
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
DescriptorSerializer serializer =
@@ -310,7 +285,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
);
}
private void generateBridge(
protected void generateBridge(
@NotNull Method bridge,
@NotNull List<KotlinType> bridgeParameterKotlinTypes,
@Nullable KotlinType bridgeReturnType,
@@ -414,13 +389,58 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
if (generateBody) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
CallableReferenceUtilKt.generateFunctionReferenceSignature(iv, descriptor, state);
PropertyReferenceCodegen.generateCallableReferenceSignature(iv, descriptor, state);
iv.areturn(JAVA_STRING_TYPE);
FunctionCodegen.endVisit(iv, "function reference getSignature", element);
}
}
}
public static void generateCallableReferenceDeclarationContainer(
@NotNull InstructionAdapter iv,
@NotNull CallableDescriptor descriptor,
@NotNull GenerationState state
) {
KotlinTypeMapper typeMapper = state.getTypeMapper();
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
// TODO: would it work for arrays?
SimpleType containerKotlinType = ((ClassDescriptor) container).getDefaultType();
Type containerType = typeMapper.mapClass((ClassDescriptor) container);
putJavaLangClassInstance(iv, containerType, containerKotlinType, typeMapper);
}
else if (container instanceof PackageFragmentDescriptor) {
iv.aconst(typeMapper.mapOwner(descriptor));
}
else if (descriptor instanceof VariableDescriptorWithAccessors) {
iv.aconst(state.getBindingContext().get(
CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, ((VariableDescriptorWithAccessors) descriptor)
));
}
else {
iv.aconst(null);
return;
}
boolean isContainerPackage =
descriptor instanceof LocalVariableDescriptor
? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) == null
: container instanceof PackageFragmentDescriptor;
if (isContainerPackage) {
// Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead,
// but there's no nice API to obtain that name here yet
// TODO: write the referenced declaration's module name and use it in reflection
iv.aconst(state.getModuleName());
iv.invokestatic(REFLECTION, "getOrCreateKotlinPackage",
Type.getMethodDescriptor(K_DECLARATION_CONTAINER_TYPE, getType(Class.class), getType(String.class)), false);
}
else {
wrapJavaClassIntoKClass(iv);
}
}
@NotNull
protected Method generateConstructor() {
List<FieldInfo> args = calculateConstructorParameters(typeMapper, state.getLanguageVersionSettings(), closure, asmType);
@@ -456,40 +476,24 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
iv.load(0, superClassAsmType);
List<Type> superCtorArgTypes = new ArrayList<>();
if (superClassAsmType.equals(LAMBDA) || functionReferenceTarget != null ||
CoroutineCodegenUtilKt.isCoroutineSuperClass(state.getLanguageVersionSettings(), superClassAsmType.getInternalName())
) {
iv.iconst(CodegenUtilKt.getArity(funDescriptor));
superCtorArgTypes.add(Type.INT_TYPE);
String superClassConstructorDescriptor;
if (superClassAsmType.equals(LAMBDA) || superClassAsmType.equals(FUNCTION_REFERENCE) ||
CoroutineCodegenUtilKt.isCoroutineSuperClass(state.getLanguageVersionSettings(), superClassAsmType.getInternalName())) {
int arity = calculateArity();
iv.iconst(arity);
if (shouldHaveBoundReferenceReceiver) {
CallableReferenceUtilKt.loadBoundReferenceReceiverParameter(
iv, boundReceiverParameterIndex, boundReceiverType, boundReceiverKotlinType
);
superCtorArgTypes.add(OBJECT_TYPE);
CallableReferenceUtilKt.loadBoundReferenceReceiverParameter(iv, boundReceiverParameterIndex, boundReceiverType, boundReceiverKotlinType);
superClassConstructorDescriptor = "(ILjava/lang/Object;)V";
}
if (isOptimizedFunctionReference || isAdaptedFunctionReference) {
assert functionReferenceTarget != null : "No function reference target: " + funDescriptor;
generateCallableReferenceDeclarationContainerClass(iv, functionReferenceTarget, state);
iv.aconst(functionReferenceTarget.getName().asString());
CallableReferenceUtilKt.generateFunctionReferenceSignature(iv, functionReferenceTarget, state);
int flags =
getCallableReferenceTopLevelFlag(functionReferenceTarget) +
(calculateFunctionReferenceFlags(functionReferenceCall, funDescriptor) << 1);
iv.aconst(flags);
superCtorArgTypes.add(JAVA_CLASS_TYPE);
superCtorArgTypes.add(JAVA_STRING_TYPE);
superCtorArgTypes.add(JAVA_STRING_TYPE);
superCtorArgTypes.add(Type.INT_TYPE);
else {
superClassConstructorDescriptor = "(I)V";
}
}
else {
assert !shouldHaveBoundReferenceReceiver : "Unexpected bound reference with supertype " + superClassAsmType;
superClassConstructorDescriptor = "()V";
}
iv.invokespecial(
superClassAsmType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, superCtorArgTypes.toArray(new Type[0])), false
);
iv.invokespecial(superClassAsmType.getInternalName(), "<init>", superClassConstructorDescriptor, false);
iv.visitInsn(RETURN);
@@ -498,39 +502,11 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
return constructor;
}
private static int calculateFunctionReferenceFlags(
@NotNull ResolvedCall<?> call,
@NotNull FunctionDescriptor anonymousAdapterFunction
) {
boolean hasVarargMappedToElement = false;
FunctionDescriptor target = (FunctionDescriptor) call.getResultingDescriptor();
int shift =
(call.getDispatchReceiver() instanceof TransientReceiver ? 1 : 0) +
(call.getExtensionReceiver() instanceof TransientReceiver ? 1 : 0);
for (int i = shift;
i < anonymousAdapterFunction.getValueParameters().size() && i - shift < target.getValueParameters().size();
i++) {
ValueParameterDescriptor targetParameter = target.getValueParameters().get(i - shift);
ValueParameterDescriptor adaptedParameter = anonymousAdapterFunction.getValueParameters().get(i);
// Vararg to element conversion is happening if the target parameter is vararg (e.g. `vararg xs: Int`),
// but the adapted parameter's type is not equal to the target parameter's type (which is `IntArray`).
if (targetParameter.getVarargElementType() != null &&
!targetParameter.getType().equals(adaptedParameter.getType())) {
hasVarargMappedToElement = true;
break;
}
}
//noinspection ConstantConditions
boolean hasCoercionToUnit = KotlinBuiltIns.isUnit(anonymousAdapterFunction.getReturnType()) &&
!KotlinBuiltIns.isUnit(target.getReturnType());
boolean hasSuspendConversion = !target.isSuspend() && anonymousAdapterFunction.isSuspend();
return (hasVarargMappedToElement ? 1 : 0) +
(hasSuspendConversion ? 2 : 0) +
((hasCoercionToUnit ? 1 : 0) << 2);
protected int calculateArity() {
int arity = funDescriptor.getValueParameters().size();
if (funDescriptor.getExtensionReceiverParameter() != null) arity++;
if (funDescriptor.getDispatchReceiverParameter() != null) arity++;
return arity;
}
@NotNull

View File

@@ -153,18 +153,18 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
signature.genericsSignature,
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper)
)
val skipNullabilityAnnotations = flags and Opcodes.ACC_PRIVATE != 0 || flags and Opcodes.ACC_SYNTHETIC != 0
AnnotationCodegen.forMethod(mv, memberCodegen, state, skipNullabilityAnnotations)
.genAnnotations(functionDescriptor, signature.returnType, functionDescriptor.returnType)
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(
functionDescriptor,
signature.returnType,
functionDescriptor.returnType
)
if (state.classBuilderMode == ClassBuilderMode.KAPT3) {
mv.visitAnnotation(ANNOTATION_TYPE_DESCRIPTOR_FOR_JVM_OVERLOADS_GENERATED_METHODS, false)
}
FunctionCodegen.generateParameterAnnotations(
functionDescriptor, mv, signature, remainingParameters, memberCodegen, state, skipNullabilityAnnotations
)
FunctionCodegen.generateParameterAnnotations(functionDescriptor, mv, signature, remainingParameters, memberCodegen, state)
if (!state.classBuilderMode.generateBodies) {
FunctionCodegen.generateLocalVariablesForParameters(

View File

@@ -20,7 +20,6 @@ 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.SourceMapper;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
@@ -99,11 +98,6 @@ public abstract class DelegatingClassBuilder implements ClassBuilder {
getDelegate().visitSource(name, debug);
}
@Override
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
getDelegate().visitSMAP(smap, backwardsCompatibleSyntax);
}
@Override
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
getDelegate().visitOuterClass(owner, name, desc);
@@ -119,4 +113,9 @@ public abstract class DelegatingClassBuilder implements ClassBuilder {
public String getThisName() {
return getDelegate().getThisName();
}
@Override
public void addSMAP(FileMapping mapping) {
getDelegate().addSMAP(mapping);
}
}

View File

@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
@@ -50,17 +49,11 @@ public class DelegationFieldsInfo {
public final Type type;
public final String name;
public final boolean generateField;
public final String genericSignature;
private Field(Type type, String name, boolean generateField, String genericSignature) {
private Field(Type type, String name, boolean generateField) {
this.type = type;
this.name = name;
this.generateField = generateField;
this.genericSignature = genericSignature;
}
private Field(Type type, String name, boolean generateField) {
this(type, name, generateField, null);
}
@NotNull
@@ -82,8 +75,8 @@ public class DelegationFieldsInfo {
new DelegationFieldsInfo.Field(typeMapper.mapType(propertyDescriptor), propertyDescriptor.getName().asString(), false));
}
private void addField(KtDelegatedSuperTypeEntry specifier, Type type, String name, String genericSignature) {
fields.put(specifier, new DelegationFieldsInfo.Field(type, name, true, genericSignature));
private void addField(KtDelegatedSuperTypeEntry specifier, Type type, String name) {
fields.put(specifier, new DelegationFieldsInfo.Field(type, name, true));
}
@NotNull
@@ -104,15 +97,13 @@ public class DelegationFieldsInfo {
else {
KotlinType expressionType = bindingContext.getType(expression);
ClassDescriptor superClass = JvmCodegenUtil.getSuperClass(specifier, state, bindingContext);
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
Type asmType =
expressionType != null ? typeMapper.mapType(expressionType, sw) :
superClass != null ? typeMapper.mapType(superClass.getDefaultType(), sw) : null;
expressionType != null ? typeMapper.mapType(expressionType) :
superClass != null ? typeMapper.mapType(superClass) : null;
if (asmType == null) continue;
String genericSignature = sw.makeJavaGenericSignature();
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, DELEGATE_SUPER_FIELD_PREFIX + n, genericSignature);
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, DELEGATE_SUPER_FIELD_PREFIX + n);
}
n++;
}

View File

@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenForLambda;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.codegen.coroutines.ResolvedCallWithRealDescriptor;
import org.jetbrains.kotlin.codegen.coroutines.SuspensionPointKind;
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.kotlin.codegen.inline.*;
import org.jetbrains.kotlin.codegen.intrinsics.*;
@@ -52,6 +51,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.kotlin.MethodSignatureMappingKt;
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
import org.jetbrains.kotlin.name.Name;
@@ -76,7 +76,6 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor;
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
import org.jetbrains.kotlin.types.*;
@@ -219,11 +218,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return parentCodegen;
}
@NotNull
public KotlinTypeMapper getTypeMapper() {
return typeMapper;
}
@NotNull
public ObjectLiteralResult generateObjectLiteral(@NotNull KtObjectLiteralExpression literal) {
KtObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
@@ -753,9 +747,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
Label label = isBreak ? loopBlockStackElement.breakLabel : loopBlockStackElement.continueLabel;
return StackValue.operation(
Type.VOID_TYPE,
getNothingType(),
adapter -> {
Type.VOID_TYPE, adapter -> {
PseudoInsnsKt.fixStackAndJump(v, label);
v.mark(afterBreakContinueLabel);
return Unit.INSTANCE;
@@ -1015,7 +1007,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull
private StackValue genClosure(KtDeclarationWithBody declaration, @Nullable SamType samType) {
FunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
FunctionDescriptor descriptor = bindingContext.get(FUNCTION, declaration);
assert descriptor != null : "Function is not resolved to descriptor: " + declaration.getText();
return genClosure(
@@ -1029,7 +1021,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull FunctionDescriptor descriptor,
@NotNull FunctionGenerationStrategy strategy,
@Nullable SamType samType,
@Nullable ResolvedCall<FunctionDescriptor> functionReferenceCall,
@Nullable FunctionDescriptor functionReferenceTarget,
@Nullable StackValue functionReferenceReceiver
) {
ClassBuilder cv = state.getFactory().newVisitor(
@@ -1039,19 +1031,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
);
ClosureCodegen coroutineCodegen = CoroutineCodegenForLambda.create(this, descriptor, declaration, cv);
ClosureContext closureContext =
descriptor.isSuspend()
? this.context.intoCoroutineClosure(
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(descriptor, state),
descriptor, this, state.getTypeMapper()
)
: this.context.intoClosure(descriptor, this, typeMapper);
ClosureCodegen closureCodegen =
coroutineCodegen != null
? coroutineCodegen
: new ClosureCodegen(
state, declaration, samType, closureContext, functionReferenceCall, strategy, parentCodegen, cv
);
ClosureContext closureContext = descriptor.isSuspend() ? this.context.intoCoroutineClosure(
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(descriptor, state),
descriptor, this, state.getTypeMapper()
) : this.context.intoClosure(descriptor, this, typeMapper);
ClosureCodegen closureCodegen = coroutineCodegen != null ? coroutineCodegen : new ClosureCodegen(
state, declaration, samType, closureContext,
functionReferenceTarget, strategy, parentCodegen, cv
);
closureCodegen.generate();
@@ -1585,7 +1572,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assert topOfStack == tryWithFinallyBlockStackElement : "Top element of stack doesn't equals processing finally block";
KtTryExpression jetTryExpression = tryWithFinallyBlockStackElement.expression;
Label finallyStart = linkedLabel();
Label finallyStart = new Label();
v.mark(finallyStart);
tryWithFinallyBlockStackElement.addGapLabel(finallyStart);
addGapLabelsForNestedTryCatchWithoutFinally(state, nestedTryBlocksWithoutFinally, finallyStart);
@@ -1633,13 +1620,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
private KotlinType getNothingType() {
return state.getModule().getBuiltIns().getNothingType();
}
@Override
public StackValue visitReturnExpression(@NotNull KtReturnExpression expression, StackValue receiver) {
return StackValue.operation(Type.VOID_TYPE, getNothingType(), adapter -> {
return StackValue.operation(Type.VOID_TYPE, adapter -> {
KtExpression returnedExpression = expression.getReturnedExpression();
CallableMemberDescriptor descriptor = getContext().getContextDescriptor();
NonLocalReturnInfo nonLocalReturn = getNonLocalReturnInfo(descriptor, expression);
@@ -1659,7 +1642,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
else {
returnType = this.returnType;
returnKotlinType = typeMapper.getReturnValueType(this.context.getFunctionDescriptor());
returnKotlinType = this.context.getFunctionDescriptor().getReturnType();
}
StackValue valueToReturn = returnedExpression != null ? gen(returnedExpression) : StackValue.none();
@@ -1667,7 +1650,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Label afterReturnLabel = new Label();
generateFinallyBlocksIfNeeded(returnType, returnKotlinType, afterReturnLabel);
markLineNumber(expression, false);
if (isNonLocalReturn) {
generateGlobalReturnFlag(v, nonLocalReturn.labelName);
v.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
@@ -1712,10 +1695,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
//FIRST_FUN_LABEL to prevent clashing with existing labels
return new NonLocalReturnInfo(
new JvmKotlinType(
typeMapper.mapReturnType(containingFunction),
typeMapper.getReturnValueType(containingFunction)
),
new JvmKotlinType(typeMapper.mapReturnType(containingFunction), containingFunction.getReturnType()),
FIRST_FUN_LABEL
);
} else {
@@ -1753,9 +1733,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
: returnType;
KotlinType kotlinTypeForExpression =
isBlockedNamedFunction || isVoidCoroutineLambda
? null
: typeMapper.getReturnValueType(context.getFunctionDescriptor());
isBlockedNamedFunction || isVoidCoroutineLambda ? null : context.getFunctionDescriptor().getReturnType();
gen(expr, typeForExpression, kotlinTypeForExpression);
@@ -1764,7 +1742,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (!endsWithReturn(expr)) {
if (isLambdaVoidBody(expr, typeForExpression)) {
markLineNumber((KtFunctionLiteral) expr.getParent(), true);
} else if (!isLambdaBody(expr)){
}
else {
markLineNumber(expr, true);
}
@@ -1786,14 +1765,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
private static boolean isLambdaVoidBody(@NotNull KtElement bodyExpression, @NotNull Type returnType) {
return isLambdaBody(bodyExpression) && Type.VOID_TYPE.equals(returnType);
}
private static boolean isLambdaBody(@NotNull KtElement bodyExpression) {
if (bodyExpression instanceof KtBlockExpression) {
PsiElement parent = bodyExpression.getParent();
return parent instanceof KtFunctionLiteral;
if (parent instanceof KtFunctionLiteral) {
return Type.VOID_TYPE.equals(returnType);
}
}
return false;
}
@@ -2566,19 +2544,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return intrinsic.toCallable(fd, superCall, resolvedCall, this);
}
fd = SamCodegenUtil.resolveSamAdapter(fd);
if (ArgumentGeneratorKt.shouldInvokeDefaultArgumentsStub(resolvedCall)) {
// When we invoke a function with some arguments mapped as defaults,
// we later reroute this call to an overridden function in a base class that processes the default arguments.
// If the base class is generic, this overridden function can have a different Kotlin signature
// (see KT-38681 and related issues).
// Here we replace a function with a corresponding overridden function,
// and the rest is figured out by argument generation and type mapper.
fd = ArgumentGeneratorKt.getFunctionWithDefaultArguments(fd);
}
return typeMapper.mapToCallableMethod(fd, superCall, null, resolvedCall);
return typeMapper.mapToCallableMethod(SamCodegenUtil.resolveSamAdapter(fd), superCall, null, resolvedCall);
}
public void invokeMethodWithArguments(
@@ -2610,12 +2576,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return;
}
SuspensionPointKind suspensionPointKind =
CoroutineCodegenUtilKt.isSuspensionPoint(resolvedCall, this, state.getLanguageVersionSettings());
boolean maybeSuspensionPoint = suspensionPointKind != SuspensionPointKind.NEVER;
boolean isSuspendNoInlineCall =
CoroutineCodegenUtilKt.isSuspendNoInlineCall(resolvedCall, this, state.getLanguageVersionSettings());
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
if (!(callableMethod instanceof IntrinsicWithSpecialReceiver)) {
putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, maybeSuspensionPoint, isConstructor);
putReceiverAndInlineMarkerIfNeeded(callableMethod, resolvedCall, receiver, isSuspendNoInlineCall, isConstructor);
}
callGenerator.processAndPutHiddenParameters(false);
@@ -2649,27 +2614,22 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
if (maybeSuspensionPoint) {
addSuspendMarker(v, true, suspensionPointKind == SuspensionPointKind.NOT_INLINE);
if (isSuspendNoInlineCall) {
addSuspendMarker(v, true);
}
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
if (maybeSuspensionPoint) {
if (isSuspendNoInlineCall) {
addReturnsUnitMarkerIfNecessary(v, resolvedCall);
addSuspendMarker(v, false, suspensionPointKind == SuspensionPointKind.NOT_INLINE);
addSuspendMarker(v, false);
addInlineMarker(v, false);
}
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
if (state.getUseKotlinNothingValueException()) {
v.anew(Type.getObjectType("kotlin/KotlinNothingValueException"));
v.dup();
v.invokespecial("kotlin/KotlinNothingValueException", "<init>", "()V", false);
} else {
v.aconst(null);
}
v.aconst(null);
v.athrow();
}
}
@@ -2837,7 +2797,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
KotlinType approximatedType =
CapturedTypeConstructorKt.isCaptured(type) ?
(KotlinType) approximator.approximateToSuperType(
type, TypeApproximatorConfiguration.InternalTypesApproximation.INSTANCE
type, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation.INSTANCE
) : null;
return approximatedType != null ? approximatedType : type;
} else {
@@ -3165,16 +3125,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
List<ValueArgument> arguments = valueArgument.getArguments();
int size = arguments.size();
// Named arguments in vararg are treated as having an implicit spread operator.
// There can be only single such argument for a given vararg parameter, but here it doesn't really matter:
// we'll just build a copy of array as if an array argument was passed as positional with an explicit spread operator.
boolean hasSpreadOperator =
state.getLanguageVersionSettings()
.supportsFeature(LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions)
? arguments.stream().anyMatch(argument -> argument.getSpreadElement() != null || argument.isNamed())
: arguments.stream().anyMatch(argument -> argument.getSpreadElement() != null);
boolean hasSpread = false;
for (int i = 0; i != size; ++i) {
if (arguments.get(i).getSpreadElement() != null) {
hasSpread = true;
break;
}
}
if (hasSpreadOperator) {
if (hasSpread) {
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
if (size == 1) {
Type arrayType = getArrayType(arrayOfReferences ? AsmTypes.OBJECT_TYPE : elementType);
@@ -3291,13 +3250,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@Override
@SuppressWarnings("unchecked")
public StackValue visitCallableReferenceExpression(@NotNull KtCallableReferenceExpression expression, StackValue data) {
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression.getCallableReference(), bindingContext);
StackValue receiver = generateCallableReferenceReceiver(resolvedCall);
FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, expression);
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
if (functionDescriptor != null) {
FunctionReferenceGenerationStrategy strategy = new FunctionReferenceGenerationStrategy(
state, functionDescriptor, resolvedCall,
@@ -3305,7 +3263,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
null, false
);
return genClosure(expression, functionDescriptor, strategy, null, (ResolvedCall<FunctionDescriptor>) resolvedCall, receiver);
return genClosure(
expression, functionDescriptor, strategy, null,
(FunctionDescriptor) resolvedCall.getResultingDescriptor(), receiver
);
}
return generatePropertyReference(
@@ -3430,7 +3391,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
StackValue result;
if (!isPrimitive(expressionType(expression.getReceiverExpression()))) {
result = new StackValue.SafeFallback(type, kotlinType, ifnull, newReceiver);
result = new StackValue.SafeFallback(type, ifnull, newReceiver);
} else {
result = newReceiver;
}
@@ -4289,7 +4250,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return StackValue.operation(base.type, base.kotlinType, v -> {
base.put(base.type, base.kotlinType, v);
v.dup();
if (state.getUnifiedNullChecks()) {
if (state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_4) >= 0) {
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkNotNull", "(Ljava/lang/Object;)V", false);
} else {
Label ok = new Label();
@@ -4394,6 +4355,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return StackValue.none();
}
@Override
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
return initializeDestructuringDeclaration(multiDeclaration, false);
@@ -4625,16 +4587,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// We can use the $$delegatedProperties array as in non-inline functions and upon inlining, detect elements at what indices
// of that array are used in the inline function body, load the corresponding initializing bytecode from <clinit> of the
// container class (where the PropertyReferenceNImpl instance is created), copy and adapt it at the call site
StackValue value;
if (PropertyCodegen.isDelegatedPropertyWithOptimizedMetadata(variableDescriptor, bindingContext)) {
value = PropertyCodegen.getOptimizedDelegatedPropertyMetadataValue();
} else if (context.getFunctionDescriptor().isInline()) {
//noinspection ConstantConditions
value = generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null);
}
else {
value = PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
}
//noinspection ConstantConditions
StackValue value = context.getFunctionDescriptor().isInline()
? generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null)
: PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
value.put(K_PROPERTY_TYPE, null, v);
metadataVar.storeSelector(K_PROPERTY_TYPE, null, v);
}
@@ -4832,7 +4788,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@Override
public StackValue visitThrowExpression(@NotNull KtThrowExpression expression, StackValue receiver) {
return StackValue.operation(Type.VOID_TYPE, getNothingType(), adapter -> {
return StackValue.operation(Type.VOID_TYPE, adapter -> {
gen(expression.getThrownExpression(), JAVA_THROWABLE_TYPE);
v.athrow();
return Unit.INSTANCE;

View File

@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy;
import org.jetbrains.kotlin.codegen.coroutines.SuspendInlineFunctionGenerationStrategy;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
@@ -32,9 +33,12 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
@@ -44,7 +48,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineOnlyKt;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
@@ -65,8 +68,8 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.stream.Collectors;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.generateBridgeForMainFunctionIfNecessary;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
@@ -74,11 +77,14 @@ import static org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.isAccessor;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION;
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
import static org.jetbrains.kotlin.load.java.JvmAbi.LOCAL_VARIABLE_INLINE_ARGUMENT_SYNTHETIC_LINE_NUMBER;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -118,14 +124,27 @@ public class FunctionCodegen {
if (owner.getContextKind() != OwnerKind.DEFAULT_IMPLS || function.hasBody()) {
FunctionGenerationStrategy strategy;
if (functionDescriptor.isSuspend()) {
strategy = new SuspendFunctionGenerationStrategy(
state,
CoroutineCodegenUtilKt.<FunctionDescriptor>unwrapInitialDescriptorForSuspendFunction(functionDescriptor),
function,
v.getThisName(),
state.getConstructorCallNormalizationMode(),
this
);
if (isEffectivelyInlineOnly(functionDescriptor)) {
strategy = new FunctionGenerationStrategy.FunctionDefault(state, function);
} else if (!functionDescriptor.isInline()) {
strategy = new SuspendFunctionGenerationStrategy(
state,
CoroutineCodegenUtilKt.<FunctionDescriptor>unwrapInitialDescriptorForSuspendFunction(functionDescriptor),
function,
v.getThisName(),
state.getConstructorCallNormalizationMode(),
this
);
} else {
strategy = new SuspendInlineFunctionGenerationStrategy(
state,
CoroutineCodegenUtilKt.<FunctionDescriptor>unwrapInitialDescriptorForSuspendFunction(functionDescriptor),
function,
v.getThisName(),
state.getConstructorCallNormalizationMode(),
this
);
}
} else {
strategy = new FunctionGenerationStrategy.FunctionDefault(state, function);
}
@@ -190,10 +209,6 @@ public class FunctionCodegen {
if (origin.getOriginKind() == JvmDeclarationOriginKind.SAM_DELEGATION) {
flags |= ACC_SYNTHETIC;
}
boolean isCompatibilityStubInDefaultImpls = isCompatibilityStubInDefaultImpls(functionDescriptor, methodContext, state.getJvmDefaultMode());
if (isCompatibilityStubInDefaultImpls) {
flags |= ACC_DEPRECATED;
}
if (functionDescriptor.isExternal() && owner instanceof MultifileClassFacadeContext) {
// Native methods are only defined in facades and do not need package part implementations
@@ -202,13 +217,12 @@ public class FunctionCodegen {
MethodVisitor mv =
strategy.wrapMethodVisitor(
newMethod(
origin,
flags,
asmMethod.getName(),
asmMethod.getDescriptor(),
strategy.skipGenericSignature() ? null : jvmSignature.getGenericsSignature(),
getThrownExceptions(functionDescriptor, typeMapper)
newMethod(origin,
flags,
asmMethod.getName(),
asmMethod.getDescriptor(),
strategy.skipGenericSignature() ? null : jvmSignature.getGenericsSignature(),
getThrownExceptions(functionDescriptor, typeMapper)
),
flags, asmMethod.getName(),
asmMethod.getDescriptor()
@@ -216,14 +230,8 @@ public class FunctionCodegen {
recordMethodForFunctionIfAppropriate(functionDescriptor, asmMethod);
boolean skipNullabilityAnnotations =
(flags & ACC_PRIVATE) != 0 || (flags & ACC_SYNTHETIC) != 0 ||
InlineClassDescriptorResolver.isSpecializedEqualsMethod(functionDescriptor);
generateMethodAnnotationsIfRequired(
functionDescriptor, asmMethod, jvmSignature, mv,
isCompatibilityStubInDefaultImpls ? Collections.singletonList(Deprecated.class) : Collections.emptyList(),
skipNullabilityAnnotations
);
generateMethodAnnotationsIfRequired(functionDescriptor, asmMethod, jvmSignature, mv);
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
if (contextKind != OwnerKind.ERASED_INLINE_CLASS) {
@@ -284,9 +292,7 @@ public class FunctionCodegen {
@NotNull FunctionDescriptor functionDescriptor,
@NotNull Method asmMethod,
@NotNull JvmMethodGenericSignature jvmSignature,
@NotNull MethodVisitor mv,
@NotNull List<Class<?>> additionalNoArgAnnotations,
boolean skipNullabilityAnnotations
@NotNull MethodVisitor mv
) {
FunctionDescriptor annotationsOwner;
if (shouldHideConstructorDueToInlineClassTypeValueParameters(functionDescriptor)) {
@@ -301,14 +307,10 @@ public class FunctionCodegen {
annotationsOwner = functionDescriptor;
}
AnnotationCodegen.forMethod(mv, memberCodegen, state, skipNullabilityAnnotations)
.genAnnotations(annotationsOwner, asmMethod.getReturnType(), functionDescriptor.getReturnType(), null, additionalNoArgAnnotations);
AnnotationCodegen.forMethod(mv, memberCodegen, state)
.genAnnotations(annotationsOwner, asmMethod.getReturnType(), functionDescriptor.getReturnType());
generateParameterAnnotations(
annotationsOwner, mv, jvmSignature,
annotationsOwner.getValueParameters(),
memberCodegen, state, skipNullabilityAnnotations
);
generateParameterAnnotations(annotationsOwner, mv, jvmSignature, memberCodegen, state);
}
@NotNull
@@ -459,7 +461,7 @@ public class FunctionCodegen {
) {
OwnerKind contextKind = methodContext.getContextKind();
if (!state.getClassBuilderMode().generateBodies
|| isAbstractMethod(functionDescriptor, contextKind, state.getJvmDefaultMode())
|| isAbstractMethod(functionDescriptor, contextKind)
|| shouldSkipMethodBodyInAbiMode(state.getClassBuilderMode(), origin)
) {
generateLocalVariableTable(
@@ -502,14 +504,25 @@ public class FunctionCodegen {
return descriptor != null && !InlineUtil.isInlineOrContainingInline(descriptor);
}
public static void generateParameterAnnotations(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmSignature,
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state
) {
generateParameterAnnotations(
functionDescriptor, mv, jvmSignature, functionDescriptor.getValueParameters(), innerClassConsumer, state
);
}
public static void generateParameterAnnotations(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmSignature,
@NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull MemberCodegen<?> memberCodegen,
@NotNull GenerationState state,
boolean skipNullabilityAnnotations
@NotNull InnerClassConsumer innerClassConsumer,
@NotNull GenerationState state
) {
if (isAccessor(functionDescriptor)) return;
@@ -519,7 +532,6 @@ public class FunctionCodegen {
Asm7UtilKt.visitAnnotableParameterCount(mv, kotlinParameterTypes.size() - syntheticParameterCount);
boolean isDefaultImpl = OwnerKind.DEFAULT_IMPLS == memberCodegen.context.getContextKind();
for (int i = 0; i < kotlinParameterTypes.size(); i++) {
JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
JvmMethodParameterKind kind = parameterSignature.getKind();
@@ -532,18 +544,13 @@ public class FunctionCodegen {
? iterator.next()
: kind == JvmMethodParameterKind.RECEIVER
? JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter()
: kind == JvmMethodParameterKind.THIS && isDefaultImpl
? JvmCodegenUtil.getDirectMember(functionDescriptor).getDispatchReceiverParameter()
: null;
: null;
if (annotated != null) {
//noinspection ConstantConditions
int parameterIndex = i - syntheticParameterCount;
AnnotationCodegen
.forParameter(parameterIndex, mv, memberCodegen, state, skipNullabilityAnnotations)
.genAnnotations(
annotated, parameterSignature.getAsmType(), annotated.getReturnType(), functionDescriptor,
Collections.emptyList()
);
AnnotationCodegen.forParameter(parameterIndex, mv, innerClassConsumer, state)
.genAnnotations(annotated, parameterSignature.getAsmType(), annotated.getReturnType());
}
}
}
@@ -599,6 +606,7 @@ public class FunctionCodegen {
Label methodEnd;
int functionFakeIndex = -1;
int lambdaFakeIndex = -1;
if (context.getParentContext() instanceof MultifileClassFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
@@ -615,7 +623,7 @@ public class FunctionCodegen {
true, mv,
method.getAsmMethod(),
method.getOwner().getInternalName(),
true, signature.getReturnType());
true);
methodEnd = new Label();
}
else {
@@ -629,8 +637,20 @@ public class FunctionCodegen {
ValueParameterDescriptor continuationValueDescriptor = view.getValueParameters().get(view.getValueParameters().size() - 1);
frameMap.enter(continuationValueDescriptor, typeMapper.mapType(continuationValueDescriptor));
}
if (context.isInlineMethodContext() || context instanceof InlineLambdaContext) {
functionFakeIndex = newFakeTempIndex(mv, frameMap);
if (context.isInlineMethodContext()) {
functionFakeIndex = newFakeTempIndex(mv, frameMap, -1);
}
if (context instanceof InlineLambdaContext) {
int lineNumber = -1;
if (strategy instanceof ClosureGenerationStrategy) {
KtDeclarationWithBody declaration = ((ClosureGenerationStrategy) strategy).getDeclaration();
BindingContext bindingContext = typeMapper.getBindingContext();
if (declaration instanceof KtFunctionLiteral && isLambdaPassedToInlineOnly((KtFunction) declaration, bindingContext)) {
lineNumber = LOCAL_VARIABLE_INLINE_ARGUMENT_SYNTHETIC_LINE_NUMBER;
}
}
lambdaFakeIndex = newFakeTempIndex(mv, frameMap, lineNumber);
}
methodEntry = new Label();
@@ -659,7 +679,7 @@ public class FunctionCodegen {
generateLocalVariableTable(
mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), parentCodegen.state,
(functionFakeIndex >= 0 ? 1 : 0)
(functionFakeIndex >= 0 ? 1 : 0) + (lambdaFakeIndex >= 0 ? 1 : 0)
);
//TODO: it's best to move all below logic to 'generateLocalVariableTable' method
@@ -670,7 +690,9 @@ public class FunctionCodegen {
Type.INT_TYPE.getDescriptor(), null,
methodEntry, methodEnd,
functionFakeIndex);
} else if (context instanceof InlineLambdaContext && thisType != null && functionFakeIndex != -1) {
}
if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
String internalName = thisType.getInternalName();
String lambdaLocalName = StringsKt.substringAfterLast(internalName, '/', internalName);
@@ -688,7 +710,7 @@ public class FunctionCodegen {
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + "-" + functionName + "-" + lambdaLocalName,
Type.INT_TYPE.getDescriptor(), null,
methodEntry, methodEnd,
functionFakeIndex);
lambdaFakeIndex);
}
}
@@ -706,8 +728,13 @@ public class FunctionCodegen {
return false;
}
private static int newFakeTempIndex(@NotNull MethodVisitor mv, @NotNull FrameMap frameMap) {
private static int newFakeTempIndex(@NotNull MethodVisitor mv, @NotNull FrameMap frameMap, int lineNumber) {
int fakeIndex = frameMap.enterTemp(Type.INT_TYPE);
if (lineNumber >= 0) {
Label label = new Label();
mv.visitLabel(label);
mv.visitLineNumber(lineNumber, label);
}
mv.visitLdcInsn(0);
mv.visitVarInsn(ISTORE, fakeIndex);
return fakeIndex;
@@ -719,8 +746,8 @@ public class FunctionCodegen {
@NotNull JvmDefaultMode jvmDefaultMode
) {
return OwnerKind.DEFAULT_IMPLS == context.getContextKind() &&
jvmDefaultMode.isCompatibility() &&
JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(functionDescriptor, jvmDefaultMode);
hasJvmDefaultAnnotation(functionDescriptor) &&
jvmDefaultMode.isCompatibility();
}
private static void generateLocalVariableTable(
@@ -856,8 +883,7 @@ public class FunctionCodegen {
@NotNull Method asmMethod,
@NotNull String classToDelegateTo,
int opcode,
boolean isInterface,
@NotNull Type returnType
boolean isInterface
) {
InstructionAdapter iv = new InstructionAdapter(mv);
Type[] argTypes = asmMethod.getArgumentTypes();
@@ -879,8 +905,7 @@ public class FunctionCodegen {
paramIndex += argType.getSize();
}
iv.visitMethodInsn(opcode, classToDelegateTo, asmMethod.getName(), asmMethod.getDescriptor(), isInterface);
StackValue.onStack(asmMethod.getReturnType()).coerceTo(returnType, null, iv);
iv.areturn(returnType);
iv.areturn(asmMethod.getReturnType());
}
private static void generateDelegateToStaticErasedVersion(
@@ -919,19 +944,7 @@ public class FunctionCodegen {
@NotNull String classToDelegateTo,
boolean isInterfaceMethodCall
) {
generateDelegateToStaticMethodBody(isStatic, mv, asmMethod, classToDelegateTo, isInterfaceMethodCall, asmMethod.getReturnType());
}
private static void generateDelegateToStaticMethodBody(
boolean isStatic,
@NotNull MethodVisitor mv,
@NotNull Method asmMethod,
@NotNull String classToDelegateTo,
boolean isInterfaceMethodCall,
@NotNull Type returnType
) {
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall, returnType);
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall);
}
private static boolean needIndexForVar(JvmMethodParameterKind kind) {
@@ -1001,14 +1014,14 @@ public class FunctionCodegen {
public void generateBridges(@NotNull FunctionDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) return;
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(descriptor, state.getJvmDefaultMode())) return;
if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(descriptor)) return;
// equals(Any?), hashCode(), toString() never need bridges
if (isMethodOfAny(descriptor)) return;
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
Set<Bridge<Method, DescriptorBasedFunctionHandleForJvm>> bridgesToGenerate;
Set<Bridge<Method>> bridgesToGenerate;
if (!isSpecial) {
bridgesToGenerate =
JvmBridgesImplKt.generateBridgesForFunctionDescriptorForJvm(descriptor, typeMapper::mapAsmMethod, state);
@@ -1017,27 +1030,26 @@ public class FunctionCodegen {
boolean isSpecialBridge =
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) != null;
for (Bridge<Method, DescriptorBasedFunctionHandleForJvm> bridge : bridgesToGenerate) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo(), getBridgeReturnType(bridge), isSpecialBridge, false);
for (Bridge<Method> bridge : bridgesToGenerate) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo(), isSpecialBridge, false);
}
}
}
else {
Set<BridgeForBuiltinSpecial<Method>> specials =
BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(descriptor, typeMapper::mapAsmMethod, state);
Set<BridgeForBuiltinSpecial<Method>> specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
descriptor, typeMapper::mapAsmMethod, state
);
if (!specials.isEmpty()) {
PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
for (BridgeForBuiltinSpecial<Method> bridge : specials) {
generateBridge(
origin, descriptor, bridge.getFrom(), bridge.getTo(),
descriptor.getReturnType(), // TODO
bridge.isSpecial(), bridge.isDelegateToSuper()
);
bridge.isSpecial(), bridge.isDelegateToSuper());
}
}
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION, state.getJvmDefaultMode())) {
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
assert overridden != null;
@@ -1050,32 +1062,6 @@ public class FunctionCodegen {
}
}
private KotlinType getBridgeReturnType(Bridge<Method, DescriptorBasedFunctionHandleForJvm> bridge) {
// Return type for the bridge affects inline class values boxing/unboxing in bridge.
// Here we take 1st available return type for the bridge.
// In correct cases it doesn't matter what particular return type to use,
// since either all return types are inline class itself,
// or all return types are supertypes of inline class (and can't be inline classes).
for (DescriptorBasedFunctionHandleForJvm handle : bridge.getOriginalFunctions()) {
return state.getTypeMapper().getReturnValueType(handle.getDescriptor());
}
if (state.getClassBuilderMode().mightBeIncorrectCode) {
// Don't care, 'Any?' would suffice.
return state.getModule().getBuiltIns().getNullableAnyType();
} else if (bridge.getOriginalFunctions().isEmpty()) {
throw new AssertionError("No overridden functions for the bridge method '" + bridge.getTo() + "'");
} else {
throw new AssertionError(
"No return type for the bridge method '" + bridge.getTo() + "' found in the following overridden functions:\n" +
bridge.getOriginalFunctions().stream()
.map(handle -> handle.getDescriptor().toString())
.collect(Collectors.joining("\n"))
);
}
}
public static boolean isThereOverriddenInKotlinClass(@NotNull CallableMemberDescriptor descriptor) {
return CollectionsKt.any(
getAllOverriddenDescriptors(descriptor),
@@ -1084,6 +1070,18 @@ public class FunctionCodegen {
);
}
public static boolean isMethodOfAny(@NotNull FunctionDescriptor descriptor) {
String name = descriptor.getName().asString();
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
if (parameters.isEmpty()) {
return name.equals("hashCode") || name.equals("toString");
}
else if (parameters.size() == 1 && name.equals("equals")) {
return isNullableAny(parameters.get(0).getType());
}
return false;
}
@NotNull
public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull KotlinTypeMapper typeMapper) {
return ArrayUtil.toStringArray(CollectionsKt.map(
@@ -1102,7 +1100,7 @@ public class FunctionCodegen {
return Collections.emptyList();
}
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(AnnotationUtilKt.JVM_THROWS_ANNOTATION_FQ_NAME);
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.jvm.Throws"));
if (annotation == null) return Collections.emptyList();
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
@@ -1209,10 +1207,6 @@ public class FunctionCodegen {
@NotNull MemberCodegen<?> parentCodegen,
@NotNull Method defaultMethod
) {
if (methodContext instanceof ConstructorContext) {
((ConstructorContext) methodContext).setThisInitialized(false);
}
GenerationState state = parentCodegen.state;
JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
@@ -1378,7 +1372,6 @@ public class FunctionCodegen {
@NotNull FunctionDescriptor descriptor,
@NotNull Method bridge,
@NotNull Method delegateTo,
@NotNull KotlinType bridgeReturnType,
boolean isSpecialBridge,
boolean isStubDeclarationWithDelegationToSuper
) {
@@ -1446,8 +1439,7 @@ public class FunctionCodegen {
iv.invokespecial(parentInternalName, delegateTo.getName(), delegateTo.getDescriptor(), false);
}
else {
if (isInterface(descriptor.getContainingDeclaration()) &&
JvmAnnotationUtilKt.isCompiledToJvmDefault(descriptor, state.getJvmDefaultMode())) {
if (hasJvmDefaultAnnotation(descriptor)) {
iv.invokeinterface(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor());
}
else {
@@ -1455,8 +1447,8 @@ public class FunctionCodegen {
}
}
KotlinType returnValueType = state.getTypeMapper().getReturnValueType(descriptor);
StackValue.coerce(delegateTo.getReturnType(), returnValueType, bridge.getReturnType(), bridgeReturnType, iv);
KotlinType returnType = descriptor.getReturnType();
StackValue.coerce(delegateTo.getReturnType(), returnType, bridge.getReturnType(), returnType, iv);
iv.areturn(bridge.getReturnType());
endVisit(mv, "bridge method", origin);
@@ -1572,34 +1564,19 @@ public class FunctionCodegen {
@NotNull MethodContext context,
@NotNull MemberCodegen<?> parentCodegen
) {
Method delegateMethod = typeMapper.mapAsmMethod(delegateFunction);
Type[] argTypes = delegateMethod.getArgumentTypes();
List<KotlinType> argKotlinTypes = getKotlinTypesForJvmParameters(delegateFunction);
Method delegateToMethod = typeMapper.mapToCallableMethod(delegatedTo, /* superCall = */ false).getAsmMethod();
Method delegateMethod = typeMapper.mapAsmMethod(delegateFunction);
Type[] argTypes = delegateMethod.getArgumentTypes();
Type[] originalArgTypes = delegateToMethod.getArgumentTypes();
List<KotlinType> originalArgKotlinTypes = getKotlinTypesForJvmParameters(delegatedTo);
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, OBJECT_TYPE);
field.put(iv);
// When delegating to inline class, we invoke static implementation method
// that takes inline class underlying value as 1st argument.
int toArgsShift = toClass.isInline() ? 1 : 0;
int reg = 1;
for (int i = 0; i < argTypes.length; ++i) {
Type argType = argTypes[i];
KotlinType argKotlinType = argKotlinTypes.get(i);
Type toArgType = originalArgTypes[i + toArgsShift];
KotlinType toArgKotlinType = originalArgKotlinTypes.get(i);
StackValue.local(reg, argType, argKotlinType)
.put(toArgType, toArgKotlinType, iv);
reg += argType.getSize();
for (int i = 0, reg = 1; i < argTypes.length; i++) {
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i], iv);
//noinspection AssignmentToForLoopParameter
reg += argTypes[i].getSize();
}
String internalName = typeMapper.mapClass(toClass).getInternalName();
@@ -1613,7 +1590,6 @@ public class FunctionCodegen {
iv.invokevirtual(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor(), false);
}
//noinspection ConstantConditions
StackValue stackValue = AsmUtil.genNotNullAssertions(
state,
StackValue.onStack(delegateToMethod.getReturnType(), delegatedTo.getReturnType()),
@@ -1624,7 +1600,7 @@ public class FunctionCodegen {
)
);
stackValue.put(delegateMethod.getReturnType(), delegateFunction.getReturnType(), iv);
stackValue.put(delegateMethod.getReturnType(), delegatedTo.getReturnType(), iv);
iv.areturn(delegateMethod.getReturnType());
}
@@ -1638,28 +1614,6 @@ public class FunctionCodegen {
public boolean skipGenericSignature() {
return skipGenericSignature;
}
private List<KotlinType> getKotlinTypesForJvmParameters(@NotNull FunctionDescriptor functionDescriptor) {
List<KotlinType> kotlinTypes = new ArrayList<>();
ReceiverParameterDescriptor extensionReceiver = functionDescriptor.getExtensionReceiverParameter();
if (extensionReceiver != null) {
kotlinTypes.add(extensionReceiver.getType());
}
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
kotlinTypes.add(parameter.getType());
}
if (functionDescriptor.isSuspend()) {
// Suspend functions take continuation type as last argument.
// It's not an inline class, so we don't really care about exact KotlinType here.
// Just make sure argument types are counted properly.
kotlinTypes.add(null);
}
return kotlinTypes;
}
}
);
}
@@ -1675,11 +1629,9 @@ public class FunctionCodegen {
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
containingDeclaration;
if (JvmAnnotationUtilKt.isCompiledToJvmDefault(memberDescriptor, mode)) {
if (hasJvmDefaultAnnotation(memberDescriptor)) {
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
(kind == OwnerKind.DEFAULT_IMPLS &&
(isSynthetic || //TODO: move synthetic method generation into interface
(mode.isCompatibility() && !JvmAnnotationUtilKt.hasJvmDefaultNoCompatibilityAnnotation(containingDeclaration))));
(kind == OwnerKind.DEFAULT_IMPLS && (isSynthetic || mode.isCompatibility()));
} else {
switch (kind) {
case DEFAULT_IMPLS: return true;

View File

@@ -81,12 +81,7 @@ public abstract class FunctionGenerationStrategy {
@NotNull MemberCodegen<?> parentCodegen
) {
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), context, state, parentCodegen);
state.getGlobalInlineContext().enterDeclaration(context.getFunctionDescriptor());
try {
doGenerateBody(codegen, signature);
} finally {
state.getGlobalInlineContext().exitDeclaration();
}
doGenerateBody(codegen, signature);
}
@Override

View File

@@ -189,9 +189,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
result = codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType(), fakeResolvedCall);
}
else {
//noinspection ConstantConditions
Type constructedType = codegen.typeMapper.mapType(referencedFunction.getReturnType());
result = codegen.generateConstructorCall(fakeResolvedCall, constructedType);
result = codegen.generateConstructorCall(fakeResolvedCall, returnType);
}
}
else {
@@ -200,7 +198,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
InstructionAdapter v = codegen.v;
result.put(returnType, functionDescriptor.getReturnType(), v);
result.put(returnType, v);
v.areturn(returnType);
}

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