Support Native target platform in kotlin-stdlib-gen
- Allow to select target platform and target directory to generate source for - Put copyright profile to resources to have it in the resulting jar - Output error for missing bodies, but do not stop generation on the first error
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
apply plugin: 'kotlin'
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.kotlin.srcDir 'src'
|
main {
|
||||||
|
kotlin.srcDir 'src'
|
||||||
|
resources.srcDir "$buildDir/copyright"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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) {
|
task run(type: JavaExec) {
|
||||||
group 'application'
|
group 'application'
|
||||||
main 'generators.GenerateStandardLibKt'
|
main 'generators.GenerateStandardLibKt'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package generators
|
|||||||
|
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import templates.*
|
import templates.*
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates methods in the standard library which are mostly identical
|
* Generates methods in the standard library which are mostly identical
|
||||||
@@ -34,28 +35,46 @@ fun main(args: Array<String>) {
|
|||||||
ComparableOps
|
ComparableOps
|
||||||
)
|
)
|
||||||
|
|
||||||
require(args.size == 1) { "Expecting Kotlin project home path as an argument" }
|
COPYRIGHT_NOTICE = readCopyrightNoticeFromProfile { Thread.currentThread().contextClassLoader.getResourceAsStream("apache.xml").reader() }
|
||||||
val baseDir = File(args.first())
|
|
||||||
|
|
||||||
COPYRIGHT_NOTICE = readCopyrightNoticeFromProfile(baseDir.resolve(".idea/copyright/apache.xml"))
|
val targetBaseDirs = mutableMapOf<KotlinTarget, File>()
|
||||||
|
|
||||||
fun File.resolveExistingDir(subpath: String) = resolve(subpath).also {
|
when (args.size) {
|
||||||
require(it.isDirectory) { "Directory $it doesn't exist"}
|
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:
|
||||||
|
<kotlin-base-dir> - generates sources for common, jvm, js, ir-js targets using paths derived from specified base path
|
||||||
|
<target> <target-dir> - generates source for the specified target in the specified target directory
|
||||||
|
""")
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonDir = baseDir.resolveExistingDir("libraries/stdlib/common/src/generated")
|
templateGroups.groupByFileAndWrite(targetsToGenerate = targetBaseDirs.keys.toList()) { (target, source) ->
|
||||||
val jvmDir = baseDir.resolveExistingDir("libraries/stdlib/jvm/src/generated")
|
val targetDir = targetBaseDirs[target] ?: error("Target $target directory is not configured")
|
||||||
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")
|
|
||||||
when (target) {
|
when (target) {
|
||||||
KotlinTarget.Common -> commonDir.resolve("_${source.name.capitalize()}.kt")
|
KotlinTarget.Common -> targetDir.resolve("_${source.name.capitalize()}.kt")
|
||||||
KotlinTarget.JVM -> jvmDir.resolve("_${source.name.capitalize()}Jvm.kt")
|
KotlinTarget.JVM -> targetDir.resolve("_${source.name.capitalize()}Jvm.kt")
|
||||||
KotlinTarget.JS -> jsDir.resolve("_${source.name.capitalize()}Js.kt")
|
KotlinTarget.JS -> targetDir.resolve("_${source.name.capitalize()}Js.kt")
|
||||||
KotlinTarget.JS_IR -> jsIrDir.resolve("_${source.name.capitalize()}Js.kt")
|
KotlinTarget.JS_IR -> targetDir.resolve("_${source.name.capitalize()}Js.kt")
|
||||||
KotlinTarget.Native -> error("Native is unsupported yet")
|
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"}
|
||||||
|
}
|
||||||
@@ -381,7 +381,7 @@ class MemberBuilder(
|
|||||||
|
|
||||||
val body = (body ?:
|
val body = (body ?:
|
||||||
deprecate?.replaceWith?.let { "return $it" } ?:
|
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')
|
).trim('\n')
|
||||||
val indent: Int = body.takeWhile { it == ' ' }.length
|
val indent: Int = body.takeWhile { it == ' ' }.length
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package templates
|
|||||||
import org.xml.sax.InputSource
|
import org.xml.sax.InputSource
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileWriter
|
import java.io.FileWriter
|
||||||
|
import java.io.Reader
|
||||||
import javax.xml.xpath.XPathFactory
|
import javax.xml.xpath.XPathFactory
|
||||||
|
|
||||||
val COMMON_AUTOGENERATED_WARNING: String = """//
|
val COMMON_AUTOGENERATED_WARNING: String = """//
|
||||||
@@ -17,8 +18,10 @@ val COMMON_AUTOGENERATED_WARNING: String = """//
|
|||||||
|
|
||||||
lateinit var COPYRIGHT_NOTICE: String
|
lateinit var COPYRIGHT_NOTICE: String
|
||||||
|
|
||||||
fun readCopyrightNoticeFromProfile(copyrightProfile: File): String {
|
fun readCopyrightNoticeFromProfile(copyrightProfile: File): String = readCopyrightNoticeFromProfile { copyrightProfile.reader() }
|
||||||
val template = copyrightProfile.reader().use { reader ->
|
|
||||||
|
fun readCopyrightNoticeFromProfile(getCopyrightReader: () -> Reader): String {
|
||||||
|
val template = getCopyrightReader().use { reader ->
|
||||||
XPathFactory.newInstance().newXPath().evaluate("/component/copyright/option[@name='notice']/@value", InputSource(reader))
|
XPathFactory.newInstance().newXPath().evaluate("/component/copyright/option[@name='notice']/@value", InputSource(reader))
|
||||||
}
|
}
|
||||||
val yearTemplate = "$today.year"
|
val yearTemplate = "$today.year"
|
||||||
@@ -34,10 +37,9 @@ data class TargetedSourceFile(
|
|||||||
val sourceFile: SourceFile
|
val sourceFile: SourceFile
|
||||||
)
|
)
|
||||||
|
|
||||||
private val targetsToGenerate = KotlinTarget.values - KotlinTarget.Native
|
|
||||||
|
|
||||||
@JvmName("groupByFileAndWriteGroups")
|
@JvmName("groupByFileAndWriteGroups")
|
||||||
fun Sequence<TemplateGroup>.groupByFileAndWrite(
|
fun Sequence<TemplateGroup>.groupByFileAndWrite(
|
||||||
|
targetsToGenerate: List<KotlinTarget>,
|
||||||
fileNameBuilder: (TargetedSourceFile) -> File
|
fileNameBuilder: (TargetedSourceFile) -> File
|
||||||
) {
|
) {
|
||||||
flatMap { group ->
|
flatMap { group ->
|
||||||
@@ -49,6 +51,7 @@ fun Sequence<TemplateGroup>.groupByFileAndWrite(
|
|||||||
|
|
||||||
@JvmName("groupByFileAndWriteTemplates")
|
@JvmName("groupByFileAndWriteTemplates")
|
||||||
fun Sequence<MemberTemplate>.groupByFileAndWrite(
|
fun Sequence<MemberTemplate>.groupByFileAndWrite(
|
||||||
|
targetsToGenerate: List<KotlinTarget>,
|
||||||
fileNameBuilder: (TargetedSourceFile) -> File
|
fileNameBuilder: (TargetedSourceFile) -> File
|
||||||
) {
|
) {
|
||||||
flatMap { it.instantiate(targetsToGenerate) }
|
flatMap { it.instantiate(targetsToGenerate) }
|
||||||
|
|||||||
Reference in New Issue
Block a user