diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect.txt b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect/module-info.java b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect/module-info.java new file mode 100644 index 00000000000..199102b2065 --- /dev/null +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect/module-info.java @@ -0,0 +1,3 @@ +module namedWithIndirectDependencyViaOtherModule { + requires kotlin.reflect; +} diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect/test.kt b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect/test.kt new file mode 100644 index 00000000000..879c4b9d885 --- /dev/null +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaReflect/test.kt @@ -0,0 +1,6 @@ +import kotlin.text.Regex + +fun f1(): List = emptyList() +fun f2(): Array> = arrayOf() +fun f3(map: Map): Collection = + map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values diff --git a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt index d8b8903d233..8e40ce99626 100644 --- a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt @@ -37,6 +37,7 @@ class CodeConformanceTest : TestCase() { "libraries/stdlib/js/.gradle", "libraries/stdlib/js/build", "libraries/reflect/build", + "libraries/reflect/api/src/java9/java/kotlin/reflect/jvm/internal/impl", "libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools", "dependencies", "js/js.translator/qunit/qunit.js", diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt index 2035687ab14..5fc0ed19a93 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt @@ -229,6 +229,7 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { module("unnamed") module("namedWithExplicitDependency") module("namedWithoutExplicitDependency") + module("namedWithIndirectDependencyViaReflect", listOf(ForTestCompileRuntime.reflectJarForTests())) } fun testDependencyOnStdlibJdk78() { diff --git a/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsLoaderImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsLoaderImpl.kt index ba88e630319..68774177bd0 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsLoaderImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsLoaderImpl.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream class BuiltInsLoaderImpl : BuiltInsLoader { - private val classLoader = this::class.java.classLoader + private val resourceLoader = BuiltInsResourceLoader() override fun createPackageFragmentProvider( storageManager: StorageManager, @@ -45,10 +45,9 @@ class BuiltInsLoaderImpl : BuiltInsLoader { KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAMES, classDescriptorFactories, platformDependentDeclarationFilter, - additionalClassPartsProvider - ) { path -> - classLoader?.getResourceAsStream(path) ?: ClassLoader.getSystemResourceAsStream(path) - } + additionalClassPartsProvider, + resourceLoader::loadResource + ) } fun createBuiltInPackageFragmentProvider( diff --git a/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsResourceLoader.kt b/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsResourceLoader.kt new file mode 100644 index 00000000000..6f4a1922dd6 --- /dev/null +++ b/core/deserialization/src/org/jetbrains/kotlin/builtins/BuiltInsResourceLoader.kt @@ -0,0 +1,26 @@ +/* + * 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.builtins + +import java.io.InputStream + +class BuiltInsResourceLoader { + fun loadResource(path: String): InputStream? { + return this::class.java.classLoader?.getResourceAsStream(path) + ?: ClassLoader.getSystemResourceAsStream(path) + } +} diff --git a/libraries/reflect/api/build.gradle b/libraries/reflect/api/build.gradle index 2d04340cac1..aadf1aa861f 100644 --- a/libraries/reflect/api/build.gradle +++ b/libraries/reflect/api/build.gradle @@ -10,10 +10,11 @@ sourceSets { srcDir "${rootDir}/core/reflection.jvm/src" } } + java9 } dependencies { - compileOnly project(':kotlin-stdlib') + compile project(':kotlin-stdlib') compileOnly project(':core:descriptors') compileOnly project(':core:descriptors.jvm') compileOnly project(':core:deserialization') @@ -21,6 +22,8 @@ dependencies { compileOnly project(':core:util.runtime') } +createCompileJava9Task(project, "compileJava9", "kotlin.reflect", [configurations.compileOnly]) + compileKotlin { kotlinOptions { freeCompilerArgs = ["-version", @@ -34,3 +37,14 @@ compileKotlin { jar { manifestAttributes(manifest, project, "internal") } + +task java9Jar(type: Jar) { + dependsOn(compileJava9) + classifier = "java9" + from sourceSets.java9.output +} + +artifacts { + archives java9Jar + runtime java9Jar +} diff --git a/libraries/reflect/api/src/java9/java/kotlin/reflect/jvm/internal/impl/builtins/BuiltInsResourceLoader.java b/libraries/reflect/api/src/java9/java/kotlin/reflect/jvm/internal/impl/builtins/BuiltInsResourceLoader.java new file mode 100644 index 00000000000..b71de6dd4cb --- /dev/null +++ b/libraries/reflect/api/src/java9/java/kotlin/reflect/jvm/internal/impl/builtins/BuiltInsResourceLoader.java @@ -0,0 +1,29 @@ +/* + * 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 kotlin.reflect.jvm.internal.impl.builtins; + +import kotlin.Unit; + +import java.io.IOException; +import java.io.InputStream; + +public class BuiltInsResourceLoader { + public InputStream loadResource(String path) throws IOException { + Module stdlib = Unit.class.getModule(); + return stdlib != null ? stdlib.getResourceAsStream(path) : null; + } +} diff --git a/libraries/reflect/api/src/java9/java/module-info.java b/libraries/reflect/api/src/java9/java/module-info.java new file mode 100644 index 00000000000..23143dedc33 --- /dev/null +++ b/libraries/reflect/api/src/java9/java/module-info.java @@ -0,0 +1,18 @@ +module kotlin.reflect { + requires transitive kotlin.stdlib; + + exports kotlin.reflect.full; + exports kotlin.reflect.jvm; + + opens kotlin.reflect.jvm.internal to kotlin.stdlib; + + uses org.jetbrains.kotlin.builtins.BuiltInsLoader; + uses org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition; + uses org.jetbrains.kotlin.util.ModuleVisibilityHelper; + + provides org.jetbrains.kotlin.builtins.BuiltInsLoader with org.jetbrains.kotlin.builtins.BuiltInsLoaderImpl; + provides org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition with + org.jetbrains.kotlin.load.java.FieldOverridabilityCondition, + org.jetbrains.kotlin.load.java.ErasedOverridabilityCondition, + org.jetbrains.kotlin.load.java.JavaIncompatibilityRulesOverridabilityCondition; +} diff --git a/libraries/reflect/build.gradle.kts b/libraries/reflect/build.gradle.kts index 9d21b166dc7..70603320bd7 100644 --- a/libraries/reflect/build.gradle.kts +++ b/libraries/reflect/build.gradle.kts @@ -123,7 +123,7 @@ class KotlinModuleShadowTransformer(private val logger: Logger) : Transformer { val reflectShadowJar by task { classifier = "shadow" version = null - callGroovy("manifestAttributes", manifest, project, "Main") + callGroovy("manifestAttributes", manifest, project, "Main", true) from(the().sourceSets.getByName("main").output) from(project(":core:descriptors.jvm").the().sourceSets.getByName("main").resources) { @@ -154,18 +154,17 @@ val stripMetadata by tasks.creating { } } -val mainArchiveName = "${property("archivesBaseName")}-$version.jar" -val outputJarPath = "$libsDir/$mainArchiveName" +val proguardOutput = "$libsDir/${property("archivesBaseName")}-proguard.jar" val proguard by task { dependsOn(stripMetadata) inputs.files(stripMetadata.outputs.files) - outputs.file(outputJarPath) + outputs.file(proguardOutput) - injars(stripMetadata.outputs.files) - outjars(outputJarPath) + injars(mapOf("filter" to "!META-INF/versions/**"), stripMetadata.outputs.files) + outjars(proguardOutput) - libraryjars(proguardDeps) + libraryjars(mapOf("filter" to "!META-INF/versions/**"), proguardDeps) configuration("$core/reflection.jvm/reflection.pro") } @@ -203,20 +202,27 @@ val sourcesJar = sourcesJar(sourceSet = null) { from("$core/reflection.jvm/src") } -val result = proguard +val result by task { + dependsOn(proguard) + from(zipTree(file(proguardOutput))) + from(zipTree(reflectShadowJar.archivePath)) { + include("META-INF/versions/**") + } + callGroovy("manifestAttributes", manifest, project, "Main", true) +} val dexMethodCount by task { dependsOn(result) - jarFile = File(outputJarPath) + jarFile = result.outputs.files.single() ownPackages = listOf("kotlin.reflect") } tasks.getByName("check").dependsOn(dexMethodCount) artifacts { val artifactJar = mapOf( - "file" to File(outputJarPath), - "builtBy" to result, - "name" to property("archivesBaseName") + "file" to result.outputs.files.single(), + "builtBy" to result, + "name" to property("archivesBaseName") ) add(mainJar.name, artifactJar)