diff --git a/libraries/tools/kotlin-stdlib-gen/build.gradle b/libraries/tools/kotlin-stdlib-gen/build.gradle index f5045841fef..134833fb25a 100644 --- a/libraries/tools/kotlin-stdlib-gen/build.gradle +++ b/libraries/tools/kotlin-stdlib-gen/build.gradle @@ -1,7 +1,10 @@ apply plugin: 'kotlin' sourceSets { - main.kotlin.srcDir 'src' + main { + kotlin.srcDir 'src' + resources.srcDir "$buildDir/copyright" + } } dependencies { @@ -15,6 +18,16 @@ compileKotlin { } } +task copyCopyrightProfile(type: Copy) { + from "$rootDir/.idea/copyright" + into "$buildDir/copyright" + include 'apache.xml' +} + +processResources { + dependsOn(copyCopyrightProfile) +} + task run(type: JavaExec) { group 'application' main 'generators.GenerateStandardLibKt' diff --git a/libraries/tools/kotlin-stdlib-gen/src/generators/GenerateStandardLib.kt b/libraries/tools/kotlin-stdlib-gen/src/generators/GenerateStandardLib.kt index 28e67f1928c..96857a98568 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/generators/GenerateStandardLib.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/generators/GenerateStandardLib.kt @@ -7,6 +7,7 @@ package generators import java.io.* import templates.* +import kotlin.system.exitProcess /** * Generates methods in the standard library which are mostly identical @@ -34,28 +35,46 @@ fun main(args: Array) { ComparableOps ) - require(args.size == 1) { "Expecting Kotlin project home path as an argument" } - val baseDir = File(args.first()) + COPYRIGHT_NOTICE = readCopyrightNoticeFromProfile { Thread.currentThread().contextClassLoader.getResourceAsStream("apache.xml").reader() } - COPYRIGHT_NOTICE = readCopyrightNoticeFromProfile(baseDir.resolve(".idea/copyright/apache.xml")) + val targetBaseDirs = mutableMapOf() - fun File.resolveExistingDir(subpath: String) = resolve(subpath).also { - require(it.isDirectory) { "Directory $it doesn't exist"} + when (args.size) { + 1 -> { + val baseDir = File(args.first()) + targetBaseDirs[KotlinTarget.Common] = baseDir.resolveExistingDir("libraries/stdlib/common/src/generated") + targetBaseDirs[KotlinTarget.JVM] = baseDir.resolveExistingDir("libraries/stdlib/jvm/src/generated") + targetBaseDirs[KotlinTarget.JS] = baseDir.resolveExistingDir("libraries/stdlib/js/src/generated") + targetBaseDirs[KotlinTarget.JS_IR] = baseDir.resolveExistingDir("libraries/stdlib/js/irRuntime/generated") + } + 2 -> { + val (targetName, targetDir) = args + val target = KotlinTarget.values.singleOrNull { it.name.equals(targetName, ignoreCase = true) } ?: error("Invalid target: $targetName") + targetBaseDirs[target] = File(targetDir).also { it.requireExistingDir() } + } + else -> { + println("""Parameters: + - generates sources for common, jvm, js, ir-js targets using paths derived from specified base path + - generates source for the specified target in the specified target directory +""") + exitProcess(1) + } } - val commonDir = baseDir.resolveExistingDir("libraries/stdlib/common/src/generated") - val jvmDir = baseDir.resolveExistingDir("libraries/stdlib/jvm/src/generated") - val jsDir = baseDir.resolveExistingDir("libraries/stdlib/js/src/generated") - val jsIrDir = baseDir.resolveExistingDir("libraries/stdlib/js/irRuntime/generated") - - templateGroups.groupByFileAndWrite { (target, source) -> - // File("build/out/$platform/$source.kt") + templateGroups.groupByFileAndWrite(targetsToGenerate = targetBaseDirs.keys.toList()) { (target, source) -> + val targetDir = targetBaseDirs[target] ?: error("Target $target directory is not configured") when (target) { - KotlinTarget.Common -> commonDir.resolve("_${source.name.capitalize()}.kt") - KotlinTarget.JVM -> jvmDir.resolve("_${source.name.capitalize()}Jvm.kt") - KotlinTarget.JS -> jsDir.resolve("_${source.name.capitalize()}Js.kt") - KotlinTarget.JS_IR -> jsIrDir.resolve("_${source.name.capitalize()}Js.kt") - KotlinTarget.Native -> error("Native is unsupported yet") + KotlinTarget.Common -> targetDir.resolve("_${source.name.capitalize()}.kt") + KotlinTarget.JVM -> targetDir.resolve("_${source.name.capitalize()}Jvm.kt") + KotlinTarget.JS -> targetDir.resolve("_${source.name.capitalize()}Js.kt") + KotlinTarget.JS_IR -> targetDir.resolve("_${source.name.capitalize()}Js.kt") + KotlinTarget.Native -> targetDir.resolve("_${source.name.capitalize()}Native.kt") } } } + +fun File.resolveExistingDir(subpath: String) = resolve(subpath).also { it.requireExistingDir() } + +fun File.requireExistingDir() { + require(isDirectory) { "Directory $this doesn't exist"} +} \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt index 53da9208aeb..8cf1b23c4fb 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt @@ -381,7 +381,7 @@ class MemberBuilder( val body = (body ?: deprecate?.replaceWith?.let { "return $it" } ?: - throw RuntimeException("$signature for ${target.fullName}: no body specified for ${family to primitive}") + """TODO("Body is not provided")""".also { System.err.println("ERROR: $signature for ${target.fullName}: no body specified for ${family to primitive}") } ).trim('\n') val indent: Int = body.takeWhile { it == ' ' }.length diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/Writers.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/Writers.kt index 35f43e7ed61..89c1bfbf764 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/Writers.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/Writers.kt @@ -8,6 +8,7 @@ package templates import org.xml.sax.InputSource import java.io.File import java.io.FileWriter +import java.io.Reader import javax.xml.xpath.XPathFactory val COMMON_AUTOGENERATED_WARNING: String = """// @@ -17,8 +18,10 @@ val COMMON_AUTOGENERATED_WARNING: String = """// lateinit var COPYRIGHT_NOTICE: String -fun readCopyrightNoticeFromProfile(copyrightProfile: File): String { - val template = copyrightProfile.reader().use { reader -> +fun readCopyrightNoticeFromProfile(copyrightProfile: File): String = readCopyrightNoticeFromProfile { copyrightProfile.reader() } + +fun readCopyrightNoticeFromProfile(getCopyrightReader: () -> Reader): String { + val template = getCopyrightReader().use { reader -> XPathFactory.newInstance().newXPath().evaluate("/component/copyright/option[@name='notice']/@value", InputSource(reader)) } val yearTemplate = "$today.year" @@ -34,10 +37,9 @@ data class TargetedSourceFile( val sourceFile: SourceFile ) -private val targetsToGenerate = KotlinTarget.values - KotlinTarget.Native - @JvmName("groupByFileAndWriteGroups") fun Sequence.groupByFileAndWrite( + targetsToGenerate: List, fileNameBuilder: (TargetedSourceFile) -> File ) { flatMap { group -> @@ -49,6 +51,7 @@ fun Sequence.groupByFileAndWrite( @JvmName("groupByFileAndWriteTemplates") fun Sequence.groupByFileAndWrite( + targetsToGenerate: List, fileNameBuilder: (TargetedSourceFile) -> File ) { flatMap { it.instantiate(targetsToGenerate) }