Improve new stdlib generator DSL
- Add Kotlin/Native platform. - Rename classes. - Introduce TemplateGroup and TemplateGroupBase to group template values. - MemberBuilder: add support for more properties.
This commit is contained in:
@@ -6,6 +6,7 @@ sourceSets {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$bootstrapKotlinVersion"
|
compile "org.jetbrains.kotlin:kotlin-stdlib:$bootstrapKotlinVersion"
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-reflect:$bootstrapKotlinVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
|
|||||||
@@ -83,7 +83,14 @@ enum class Inline {
|
|||||||
enum class Platform {
|
enum class Platform {
|
||||||
Common,
|
Common,
|
||||||
JVM,
|
JVM,
|
||||||
JS
|
JS,
|
||||||
|
Native;
|
||||||
|
|
||||||
|
val fullName get() = "Kotlin/$name"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val values = values().toList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class SequenceClass {
|
enum class SequenceClass {
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ class MemberBuilder(
|
|||||||
var operator: Boolean = false; private set
|
var operator: Boolean = false; private set
|
||||||
val typeParams = mutableListOf<String>()
|
val typeParams = mutableListOf<String>()
|
||||||
var customReceiver: String? = null; private set
|
var customReceiver: String? = null; private set
|
||||||
var receiverAsterisk: Boolean = false; private set
|
var receiverAsterisk: Boolean = false // TODO: rename to genericStarProjection
|
||||||
var toNullableT: Boolean = false; private set
|
var toNullableT: Boolean = false
|
||||||
|
|
||||||
var returns: String? = null; private set
|
var returns: String? = null; private set
|
||||||
var body: String? = null; private set
|
var body: String? = null; private set
|
||||||
@@ -72,8 +72,8 @@ class MemberBuilder(
|
|||||||
fun sourceFile(file: SourceFile) { sourceFile = file }
|
fun sourceFile(file: SourceFile) { sourceFile = file }
|
||||||
|
|
||||||
fun deprecate(value: Deprecation) { deprecate = value }
|
fun deprecate(value: Deprecation) { deprecate = value }
|
||||||
fun deprecate(value: String) { deprecate = Deprecation(value)
|
fun deprecate(value: String) { deprecate = Deprecation(value) }
|
||||||
}
|
fun since(value: String) { since = value }
|
||||||
fun platformName(name: String) { platformName = name }
|
fun platformName(name: String) { platformName = name }
|
||||||
|
|
||||||
fun visibility(value: String) { visibility = value }
|
fun visibility(value: String) { visibility = value }
|
||||||
@@ -87,10 +87,11 @@ class MemberBuilder(
|
|||||||
annotation("""@Suppress("NOTHING_TO_INLINE")""")
|
annotation("""@Suppress("NOTHING_TO_INLINE")""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun inlineOnly() { inline = Inline.Only
|
fun inlineOnly() { inline = Inline.Only }
|
||||||
}
|
|
||||||
|
|
||||||
fun receiver(value: String) { customReceiver = value }
|
fun receiver(value: String) { customReceiver = value }
|
||||||
|
@Deprecated("Use receiver()", ReplaceWith("receiver(value)"))
|
||||||
|
fun customReceiver(value: String) = receiver(value)
|
||||||
fun signature(value: String) { signature = value }
|
fun signature(value: String) { signature = value }
|
||||||
fun returns(type: String) { returns = type }
|
fun returns(type: String) { returns = type }
|
||||||
|
|
||||||
@@ -113,6 +114,12 @@ class MemberBuilder(
|
|||||||
fun body(valueBuilder: () -> String) {
|
fun body(valueBuilder: () -> String) {
|
||||||
body = valueBuilder()
|
body = valueBuilder()
|
||||||
}
|
}
|
||||||
|
fun body(f: Family, valueBuilder: () -> String) {
|
||||||
|
specialFor(f) { body(valueBuilder) }
|
||||||
|
}
|
||||||
|
fun body(vararg families: Family, valueBuilder: () -> String) {
|
||||||
|
specialFor(*families) { body(valueBuilder) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun on(platform: Platform, action: () -> Unit) {
|
fun on(platform: Platform, action: () -> Unit) {
|
||||||
@@ -128,6 +135,11 @@ class MemberBuilder(
|
|||||||
if (family == f)
|
if (family == f)
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
|
fun specialFor(vararg families: Family, action: () -> Unit) {
|
||||||
|
require(families.isNotEmpty())
|
||||||
|
if (family in families)
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun build(builder: Appendable) {
|
fun build(builder: Appendable) {
|
||||||
@@ -296,8 +308,8 @@ class MemberBuilder(
|
|||||||
|
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
visibility ?: "public",
|
visibility ?: "public",
|
||||||
"header".takeIf { headerOnly },
|
"expect".takeIf { headerOnly },
|
||||||
"impl".takeIf { isImpl },
|
"actual".takeIf { isImpl },
|
||||||
"external".takeIf { external },
|
"external".takeIf { external },
|
||||||
"inline".takeIf { inline.isInline() },
|
"inline".takeIf { inline.isInline() },
|
||||||
"infix".takeIf { infix },
|
"infix".takeIf { infix },
|
||||||
@@ -325,7 +337,7 @@ class MemberBuilder(
|
|||||||
|
|
||||||
val body = (body ?:
|
val body = (body ?:
|
||||||
deprecate?.replaceWith?.let { "return $it" } ?:
|
deprecate?.replaceWith?.let { "return $it" } ?:
|
||||||
throw RuntimeException("No body specified for $signature for ${family to primitive}")
|
throw RuntimeException("$signature for ${platform.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
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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 templates
|
||||||
|
|
||||||
|
import kotlin.coroutines.experimental.buildSequence
|
||||||
|
import kotlin.reflect.KTypeProjection
|
||||||
|
import kotlin.reflect.full.createType
|
||||||
|
import kotlin.reflect.full.isSubtypeOf
|
||||||
|
|
||||||
|
|
||||||
|
typealias TemplateGroup = () -> Sequence<MemberTemplate>
|
||||||
|
|
||||||
|
fun templateGroupOf(vararg templates: MemberTemplate): TemplateGroup = { templates.asSequence() }
|
||||||
|
|
||||||
|
abstract class TemplateGroupBase : TemplateGroup {
|
||||||
|
|
||||||
|
override fun invoke(): Sequence<MemberTemplate> = buildSequence {
|
||||||
|
with(this@TemplateGroupBase) {
|
||||||
|
this::class.members.filter { it.name.startsWith("f_") }.forEach {
|
||||||
|
require(it.parameters.size == 1) { "Member $it violates naming convention" }
|
||||||
|
when {
|
||||||
|
it.returnType.isSubtypeOf(typeMemberTemplate) ->
|
||||||
|
yield(it.call(this) as MemberTemplate)
|
||||||
|
it.returnType.isSubtypeOf(typeIterableOfMemberTemplates) ->
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
yieldAll(it.call(this) as Iterable<MemberTemplate>)
|
||||||
|
else ->
|
||||||
|
error("Member $it violates naming convention")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.run {
|
||||||
|
if (defaultActions.isEmpty()) this else onEach { t -> defaultActions.forEach(t::builder) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val defaultActions = mutableListOf<MemberBuildAction>()
|
||||||
|
|
||||||
|
fun defaultBuilder(builderAction: MemberBuildAction) {
|
||||||
|
defaultActions += builderAction
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val typeMemberTemplate = MemberTemplate::class.createType()
|
||||||
|
private val typeIterableOfMemberTemplates = Iterable::class.createType(arguments = listOf(KTypeProjection.invariant(typeMemberTemplate)))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
import kotlin.coroutines.experimental.buildSequence
|
import kotlin.coroutines.experimental.*
|
||||||
|
|
||||||
@DslMarker
|
@DslMarker
|
||||||
annotation class TemplateDsl
|
annotation class TemplateDsl
|
||||||
@@ -37,26 +37,26 @@ private fun def(signature: String, memberKind: Keyword): MemberBuildAction = {
|
|||||||
|
|
||||||
fun fn(defaultSignature: String): MemberBuildAction = def(defaultSignature, Keyword.Function)
|
fun fn(defaultSignature: String): MemberBuildAction = def(defaultSignature, Keyword.Function)
|
||||||
|
|
||||||
fun fn(defaultSignature: String, setup: FamilyPrimitiveMemberDsl.() -> Unit): MemberTemplate =
|
fun fn(defaultSignature: String, setup: FamilyPrimitiveMemberDefinition.() -> Unit): FamilyPrimitiveMemberDefinition =
|
||||||
FamilyPrimitiveMemberDsl().apply {
|
FamilyPrimitiveMemberDefinition().apply {
|
||||||
builder(fn(defaultSignature))
|
builder(fn(defaultSignature))
|
||||||
setup()
|
setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MemberBuildAction.byTwoPrimitives(setup: PairPrimitiveMemberDsl.() -> Unit): MemberTemplate =
|
fun MemberBuildAction.byTwoPrimitives(setup: PairPrimitiveMemberDefinition.() -> Unit): PairPrimitiveMemberDefinition =
|
||||||
PairPrimitiveMemberDsl().apply {
|
PairPrimitiveMemberDefinition().apply {
|
||||||
builder(this@byTwoPrimitives)
|
builder(this@byTwoPrimitives)
|
||||||
setup()
|
setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pval(name: String, setup: FamilyPrimitiveMemberDsl.() -> Unit): MemberTemplate =
|
fun pval(name: String, setup: FamilyPrimitiveMemberDefinition.() -> Unit): FamilyPrimitiveMemberDefinition =
|
||||||
FamilyPrimitiveMemberDsl().apply {
|
FamilyPrimitiveMemberDefinition().apply {
|
||||||
builder(def(name, Keyword.Value))
|
builder(def(name, Keyword.Value))
|
||||||
setup()
|
setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pvar(name: String, setup: FamilyPrimitiveMemberDsl.() -> Unit): MemberTemplate =
|
fun pvar(name: String, setup: FamilyPrimitiveMemberDefinition.() -> Unit): FamilyPrimitiveMemberDefinition =
|
||||||
FamilyPrimitiveMemberDsl().apply {
|
FamilyPrimitiveMemberDefinition().apply {
|
||||||
builder(def(name, Keyword.Variable))
|
builder(def(name, Keyword.Variable))
|
||||||
setup()
|
setup()
|
||||||
}
|
}
|
||||||
@@ -66,14 +66,16 @@ interface MemberTemplate {
|
|||||||
/** Specifies which platforms this member template should be generated for */
|
/** Specifies which platforms this member template should be generated for */
|
||||||
fun platforms(vararg platforms: Platform)
|
fun platforms(vararg platforms: Platform)
|
||||||
|
|
||||||
fun instantiate(): Sequence<MemberBuilder>
|
fun instantiate(platforms: List<Platform> = Platform.values): Sequence<MemberBuilder>
|
||||||
|
|
||||||
/** Registers parameterless member builder function */
|
/** Registers parameterless member builder function */
|
||||||
fun builder(b: MemberBuildAction)
|
fun builder(b: MemberBuildAction)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class GenericMemberDsl<TParam> : MemberTemplate {
|
infix fun <MT: MemberTemplate> MT.builder(b: MemberBuildAction): MT = apply { builder(b) }
|
||||||
|
infix fun <TParam, MT : MemberTemplateDefinition<TParam>> MT.builderWith(b: MemberBuildActionP<TParam>): MT = apply { builderWith(b) }
|
||||||
|
|
||||||
|
abstract class MemberTemplateDefinition<TParam> : MemberTemplate {
|
||||||
|
|
||||||
sealed class BuildAction {
|
sealed class BuildAction {
|
||||||
class Generic(val action: MemberBuildAction) : BuildAction() {
|
class Generic(val action: MemberBuildAction) : BuildAction() {
|
||||||
@@ -87,7 +89,7 @@ abstract class GenericMemberDsl<TParam> : MemberTemplate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val buildActions = mutableListOf<BuildAction>()
|
private val buildActions = mutableListOf<BuildAction>()
|
||||||
|
|
||||||
private var targetPlatforms = setOf(*Platform.values())
|
private var targetPlatforms = setOf(*Platform.values())
|
||||||
override fun platforms(vararg platforms: Platform) {
|
override fun platforms(vararg platforms: Platform) {
|
||||||
@@ -116,13 +118,15 @@ abstract class GenericMemberDsl<TParam> : MemberTemplate {
|
|||||||
} ?: this
|
} ?: this
|
||||||
|
|
||||||
|
|
||||||
override fun instantiate(): Sequence<MemberBuilder> {
|
override fun instantiate(platforms: List<Platform>): Sequence<MemberBuilder> {
|
||||||
val specificPlatforms by lazy { targetPlatforms - Platform.Common }
|
val resultingPlatforms = platforms.intersect(targetPlatforms)
|
||||||
|
val specificPlatforms by lazy { resultingPlatforms - Platform.Common }
|
||||||
|
|
||||||
fun platformMemberBuilders(family: Family, p: TParam) =
|
fun platformMemberBuilders(family: Family, p: TParam) =
|
||||||
if (Platform.Common in targetPlatforms) {
|
if (Platform.Common in targetPlatforms) {
|
||||||
val commonMemberBuilder = createMemberBuilder(Platform.Common, family, p)
|
val commonMemberBuilder = createMemberBuilder(Platform.Common, family, p)
|
||||||
mutableListOf(commonMemberBuilder).also { builders ->
|
mutableListOf<MemberBuilder>().also { builders ->
|
||||||
|
if (Platform.Common in resultingPlatforms) builders.add(commonMemberBuilder)
|
||||||
if (commonMemberBuilder.hasPlatformSpecializations) {
|
if (commonMemberBuilder.hasPlatformSpecializations) {
|
||||||
specificPlatforms.mapTo(builders) {
|
specificPlatforms.mapTo(builders) {
|
||||||
createMemberBuilder(it, family, p)
|
createMemberBuilder(it, family, p)
|
||||||
@@ -130,7 +134,7 @@ abstract class GenericMemberDsl<TParam> : MemberTemplate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targetPlatforms.map { createMemberBuilder(it, family, p) }
|
resultingPlatforms.map { createMemberBuilder(it, family, p) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return parametrize()
|
return parametrize()
|
||||||
@@ -152,17 +156,20 @@ abstract class GenericMemberDsl<TParam> : MemberTemplate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun defaultPrimitives(f: Family): Set<PrimitiveType> =
|
private fun defaultPrimitives(f: Family): Set<PrimitiveType> =
|
||||||
if (f.isPrimitiveSpecialization) PrimitiveType.defaultPrimitives else emptySet()
|
if (f.isPrimitiveSpecialization) PrimitiveType.defaultPrimitives else emptySet()
|
||||||
|
|
||||||
@TemplateDsl
|
@TemplateDsl
|
||||||
class FamilyPrimitiveMemberDsl : GenericMemberDsl<PrimitiveType?>() {
|
class FamilyPrimitiveMemberDefinition : MemberTemplateDefinition<PrimitiveType?>() {
|
||||||
|
|
||||||
private val familyPrimitives = mutableMapOf<Family, Set<PrimitiveType>>()
|
private val familyPrimitives = mutableMapOf<Family, Set<PrimitiveType?>>()
|
||||||
|
|
||||||
fun include(vararg fs: Family) {
|
fun include(vararg fs: Family) {
|
||||||
for (f in fs) familyPrimitives[f] = defaultPrimitives(f)
|
for (f in fs) familyPrimitives[f] = defaultPrimitives(f)
|
||||||
}
|
}
|
||||||
|
@Deprecated("Use include()", ReplaceWith("include(*fs)"))
|
||||||
|
fun only(vararg fs: Family) = include(*fs)
|
||||||
|
|
||||||
fun include(fs: Collection<Family>) {
|
fun include(fs: Collection<Family>) {
|
||||||
for (f in fs) familyPrimitives[f] = defaultPrimitives(f)
|
for (f in fs) familyPrimitives[f] = defaultPrimitives(f)
|
||||||
@@ -172,7 +179,7 @@ class FamilyPrimitiveMemberDsl : GenericMemberDsl<PrimitiveType?>() {
|
|||||||
include(Family.defaultFamilies)
|
include(Family.defaultFamilies)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun include(f: Family, primitives: Set<PrimitiveType>) {
|
fun include(f: Family, primitives: Set<PrimitiveType?>) {
|
||||||
familyPrimitives[f] = primitives
|
familyPrimitives[f] = primitives
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +205,7 @@ class FamilyPrimitiveMemberDsl : GenericMemberDsl<PrimitiveType?>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@TemplateDsl
|
@TemplateDsl
|
||||||
class PairPrimitiveMemberDsl : GenericMemberDsl<Pair<PrimitiveType, PrimitiveType>>() {
|
class PairPrimitiveMemberDefinition : MemberTemplateDefinition<Pair<PrimitiveType, PrimitiveType>>() {
|
||||||
|
|
||||||
private val familyPrimitives = mutableMapOf<Family, Set<Pair<PrimitiveType, PrimitiveType>>>()
|
private val familyPrimitives = mutableMapOf<Family, Set<Pair<PrimitiveType, PrimitiveType>>>()
|
||||||
|
|
||||||
@@ -217,77 +224,9 @@ class PairPrimitiveMemberDsl : GenericMemberDsl<Pair<PrimitiveType, PrimitiveTyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
val t_copyOfResized = MemberTemplatePar<DefaultParametrization>().apply {
|
Replacement pattern:
|
||||||
parametrization = buildSequence<DefaultParametrization> {
|
templates add f\(\"(\w+)(\(.*)
|
||||||
val allPlatforms = setOf(*Platform.values())
|
val f_$1 = fn("$1$2
|
||||||
yield(DefaultParametrization(InvariantArraysOfObjects, platforms = allPlatforms))
|
|
||||||
yieldAll(PrimitiveType.defaultPrimitives.map { DefaultParametrization(ArraysOfPrimitives, it, platforms = allPlatforms) })
|
|
||||||
}
|
|
||||||
builder = { p, platform, builder ->
|
|
||||||
builder.family = if (p.family == InvariantArraysOfObjects && platform == Platform.JS)
|
|
||||||
ArraysOfObjects else p.family
|
|
||||||
|
|
||||||
if (platform == Platform.JVM)
|
|
||||||
builder.inline = Inline.Only
|
|
||||||
|
|
||||||
builder.doc = "Returns new array which is a copy of the original array."
|
|
||||||
builder.returns = "SELF"
|
|
||||||
if (platform == Platform.JS && p.family == ArraysOfObjects)
|
|
||||||
builder.returns = "Array<T>"
|
|
||||||
|
|
||||||
if (platform == Platform.JVM) {
|
|
||||||
builder.body = "return java.util.Arrays.copyOf(this, size)"
|
|
||||||
} else if (platform == Platform.JS) {
|
|
||||||
when (p.primitive) {
|
|
||||||
null ->
|
|
||||||
builder.body = "return this.asDynamic().slice()"
|
|
||||||
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
|
||||||
builder.body = "return withType(\"${p.primitive}Array\", this.asDynamic().slice())"
|
|
||||||
else -> {
|
|
||||||
builder.annotations += """@Suppress("NOTHING_TO_INLINE")"""
|
|
||||||
builder.inline = Inline.Yes
|
|
||||||
builder.body = "return this.asDynamic().slice()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
interface MemberTemplate {
|
|
||||||
|
|
||||||
fun instantiate(): Sequence<MemberInstance>
|
|
||||||
}
|
|
||||||
|
|
||||||
class MemberTemplatePar<TParametrization : Parametrization> : MemberTemplate {
|
|
||||||
|
|
||||||
val keyword: String = "fun"
|
|
||||||
|
|
||||||
lateinit var parametrization: Sequence<TParametrization>
|
|
||||||
lateinit var builder: (TParametrization, Platform, MemberBuilder) -> Unit
|
|
||||||
|
|
||||||
override fun instantiate(): Sequence<MemberInstance> =
|
|
||||||
parametrization.flatMap {
|
|
||||||
it.platforms.asSequence().map { p ->
|
|
||||||
val memberBuilder = MemberBuilder().apply {
|
|
||||||
builder(it, p, this)
|
|
||||||
}
|
|
||||||
MemberInstance(memberBuilder::build, PlatformSourceFile(p, memberBuilder.sourceFile))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
class MemberInstance(
|
|
||||||
val textBuilder: (Appendable) -> Unit,
|
|
||||||
val platformSourceFile: PlatformSourceFile)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ data class PlatformSourceFile(
|
|||||||
fun Sequence<MemberTemplate>.groupByFileAndWrite(
|
fun Sequence<MemberTemplate>.groupByFileAndWrite(
|
||||||
fileNameBuilder: (PlatformSourceFile) -> File
|
fileNameBuilder: (PlatformSourceFile) -> File
|
||||||
) {
|
) {
|
||||||
val groupedMembers = map { it.instantiate() }.flatten().groupBy {
|
val groupedMembers = map { it.instantiate(Platform.values - Platform.Native) }.flatten().groupBy {
|
||||||
PlatformSourceFile(it.platform, it.sourceFile)
|
PlatformSourceFile(it.platform, it.sourceFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user