Skip to content

Commit

Permalink
context dependency injection
Browse files Browse the repository at this point in the history
  • Loading branch information
jerrevanveluw committed Jan 17, 2025
1 parent 3ee4c1d commit 69f8ca0
Show file tree
Hide file tree
Showing 38 changed files with 741 additions and 146 deletions.
3 changes: 2 additions & 1 deletion examples/gradle-ktor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import community.flock.wirespec.compiler.core.emit.shared.KotlinShared
import community.flock.wirespec.compiler.core.parse.AST
import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.compiler.utils.noLogger
import community.flock.wirespec.plugin.FileExtension
import community.flock.wirespec.plugin.Language
import community.flock.wirespec.plugin.gradle.CompileWirespecTask
Expand Down Expand Up @@ -80,7 +81,7 @@ tasks.register<CompileWirespecTask>("wirespec-typescript") {
languages = listOf(Language.TypeScript)
}

class KotlinSerializableEmitter : KotlinEmitter("community.flock.wirespec.generated.kotlin") {
class KotlinSerializableEmitter : KotlinEmitter("community.flock.wirespec.generated.kotlin", noLogger) {

override fun emit(type: Type, ast: AST): String = """
|@kotlinx.serialization.Serializable
Expand Down
512 changes: 512 additions & 0 deletions kotlin-js-store/yarn.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,40 @@ package community.flock.wirespec.compiler.core
import arrow.core.Either
import arrow.core.Nel
import arrow.core.NonEmptyList
import community.flock.wirespec.compiler.core.Reported.EMITTED
import community.flock.wirespec.compiler.core.Reported.PARSED
import community.flock.wirespec.compiler.core.Reported.TOKENIZED
import community.flock.wirespec.compiler.core.Reported.VALIDATED
import community.flock.wirespec.compiler.core.Stage.EMITTED
import community.flock.wirespec.compiler.core.Stage.PARSED
import community.flock.wirespec.compiler.core.Stage.TOKENIZED
import community.flock.wirespec.compiler.core.Stage.VALIDATED
import community.flock.wirespec.compiler.core.emit.common.Emitted
import community.flock.wirespec.compiler.core.emit.common.Emitter
import community.flock.wirespec.compiler.core.emit.common.HasEmitter
import community.flock.wirespec.compiler.core.exceptions.WirespecException
import community.flock.wirespec.compiler.core.parse.AST
import community.flock.wirespec.compiler.core.parse.Parser
import community.flock.wirespec.compiler.core.tokenize.tokenize
import community.flock.wirespec.compiler.core.validate.validate
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.compiler.utils.HasLogger

fun LanguageSpec.parse(source: String): (Logger) -> Either<NonEmptyList<WirespecException>, AST> =
{ logger ->
tokenize(source)
.also((TOKENIZED::report)(logger))
.let(Parser(logger)::parse)
.also((PARSED::report)(logger))
.map { it.validate() }
.also((VALIDATED::report)(logger))
}
interface CompilationContext : ParseContext, HasEmitter

fun LanguageSpec.compile(source: String): (Logger) -> (Emitter) -> Either<Nel<WirespecException>, List<Emitted>> =
{ logger ->
{ emitter ->
parse(source)(logger)
.map(emitter::emit)
.also((EMITTED::report)(logger))
}
}
fun CompilationContext.compile(source: String): Either<Nel<WirespecException>, List<Emitted>> =
parse(source)
.map(emitter::emit)
.also(EMITTED::log)

interface ParseContext : HasLanguageSpec, HasLogger

fun ParseContext.parse(source: String): Either<NonEmptyList<WirespecException>, AST> =
spec.tokenize(source)
.also(TOKENIZED::log)
.let(Parser(logger)::parse)
.also(PARSED::log)
.map { it.validate() }
.also(VALIDATED::log)

private enum class Reported {
private enum class Stage {
TOKENIZED, PARSED, VALIDATED, EMITTED;

fun report(logger: Logger): (Any) -> Unit = {
fun log(it: Any): HasLogger.() -> Unit = {
logger.info("********** $name **********\n$it\n########## $name ##########")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ interface LanguageSpec {
val orderedMatchers: List<TokenMatcher>
}

interface HasLanguageSpec {
val spec: LanguageSpec get() = WirespecSpec
}

object WirespecSpec : LanguageSpec {
override val customType = WsCustomType
override val orderedMatchers = listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.compiler.core.parse.Union
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.compiler.utils.noLogger

open class JavaEmitter(
val packageName: String = DEFAULT_GENERATED_PACKAGE_STRING,
logger: Logger = noLogger,
logger: Logger,
) : DefinitionModelEmitter, Emitter(logger, true) {

open val import = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.compiler.core.parse.Union
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.compiler.utils.noLogger

open class KotlinEmitter(
private val packageName: String = DEFAULT_GENERATED_PACKAGE_STRING,
logger: Logger = noLogger,
logger: Logger,
) : DefinitionModelEmitter, Emitter(logger, false) {

open val import = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.compiler.core.parse.Union
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.compiler.utils.noLogger

open class ScalaEmitter(
private val packageName: String = DEFAULT_GENERATED_PACKAGE_STRING,
logger: Logger = noLogger
logger: Logger,
) : DefinitionModelEmitter, Emitter(logger) {

open val import = """
Expand Down Expand Up @@ -79,14 +78,16 @@ open class ScalaEmitter(
is Reference.Custom -> value
is Reference.Primitive -> when (type) {
is Reference.Primitive.Type.String -> "String"
is Reference.Primitive.Type.Integer -> when(type.precision){
is Reference.Primitive.Type.Integer -> when (type.precision) {
Reference.Primitive.Type.Precision.P32 -> "Int"
Reference.Primitive.Type.Precision.P64 -> "Long"
}
is Reference.Primitive.Type.Number -> when(type.precision){

is Reference.Primitive.Type.Number -> when (type.precision) {
Reference.Primitive.Type.Precision.P32 -> "Float"
Reference.Primitive.Type.Precision.P64 -> "Double"
}

is Reference.Primitive.Type.Boolean -> "Boolean"
is Reference.Primitive.Type.Bytes -> "Array[Byte]"
}
Expand All @@ -99,7 +100,15 @@ open class ScalaEmitter(
"""
|sealed abstract class ${emitName()}(val label: String)
|object ${emit(identifier)} {
|${entries.joinToString("\n") { """${Spacer}final case object ${it.sanitize().uppercase()} extends ${emit(identifier)}(label = "$it")""" }}
|${
entries.joinToString("\n") {
"""${Spacer}final case object ${it.sanitize().uppercase()} extends ${
emit(
identifier
)
}(label = "$it")"""
}
}
|}
|""".trimMargin()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.compiler.core.parse.Union
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.compiler.utils.noLogger

open class TypeScriptEmitter(logger: Logger = noLogger) : DefinitionModelEmitter, Emitter(logger) {
open class TypeScriptEmitter(logger: Logger) : DefinitionModelEmitter, Emitter(logger) {

override fun Definition.emitName(): String = when (this) {
is Endpoint -> emit(identifier)
Expand Down Expand Up @@ -149,7 +148,9 @@ open class TypeScriptEmitter(logger: Logger = noLogger) : DefinitionModelEmitter
""".trimIndent()

private fun Endpoint.Request.emitFunction(endpoint: Endpoint) = """
|${Spacer}export const request = (${paramList(endpoint).takeIf { it.isNotEmpty() }?.let { "props: ${it.joinToObject { it.emit() }}" }.orEmpty()}): Request => ({
|${Spacer}export const request = (${
paramList(endpoint).takeIf { it.isNotEmpty() }?.let { "props: ${it.joinToObject { it.emit() }}" }.orEmpty()
}): Request => ({
|${Spacer(2)}path: ${endpoint.pathParams.joinToObject { "${emit(it.identifier)}: props.${emit(it.identifier)}" }},
|${Spacer(2)}method: "${endpoint.method}",
|${Spacer(2)}queries: ${endpoint.queries.joinToObject { "${emit(it.identifier)}: props.${emit(it.identifier)}" }},
Expand All @@ -159,7 +160,9 @@ open class TypeScriptEmitter(logger: Logger = noLogger) : DefinitionModelEmitter
""".trimIndent()

private fun Endpoint.Response.emitFunction(endpoint: Endpoint) = """
|${Spacer}export const response${status.firstToUpper()} = (${paramList().takeIf { it.isNotEmpty() }?.let { "props: ${it.joinToObject { it.emit() }}" }.orEmpty()}): Response${status.firstToUpper()} => ({
|${Spacer}export const response${status.firstToUpper()} = (${
paramList().takeIf { it.isNotEmpty() }?.let { "props: ${it.joinToObject { it.emit() }}" }.orEmpty()
}): Response${status.firstToUpper()} => ({
|${Spacer(2)}status: ${status},
|${Spacer(2)}headers: ${endpoint.headers.joinToObject { "${emit(it.identifier)}: props.${emit(it.identifier)}" }},
|${Spacer(2)}body: ${content?.let { "props.body" } ?: "undefined"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.compiler.core.parse.Union
import community.flock.wirespec.compiler.utils.Logger
import community.flock.wirespec.compiler.utils.noLogger

open class WirespecEmitter(logger: Logger = noLogger) : DefinitionModelEmitter, Emitter(logger) {
open class WirespecEmitter(logger: Logger) : DefinitionModelEmitter, Emitter(logger) {

override fun Definition.emitName(): String = when (this) {
is Endpoint -> emit(identifier)
Expand All @@ -46,9 +45,11 @@ open class WirespecEmitter(logger: Logger = noLogger) : DefinitionModelEmitter,

override fun Field.emit() = "${emit(identifier)}: ${reference.emit()}${if (isNullable) "?" else ""}"

override fun emit(identifier: Identifier) = when(identifier){
is DefinitionIdentifier -> identifier.run { if (value in reservedKeywords) value.addBackticks() else value }
is FieldIdentifier -> identifier.run { if (value in reservedKeywords || value.first().isUpperCase()) value.addBackticks() else value }
override fun emit(identifier: Identifier) = when (identifier) {
is DefinitionIdentifier -> identifier.run { if (value in reservedKeywords) value.addBackticks() else value }
is FieldIdentifier -> identifier.run {
if (value in reservedKeywords || value.first().isUpperCase()) value.addBackticks() else value
}
}

override fun emit(channel: Channel): String =
Expand All @@ -62,11 +63,12 @@ open class WirespecEmitter(logger: Logger = noLogger) : DefinitionModelEmitter,
is Reference.Primitive.Type.String -> "String"
is Reference.Primitive.Type.Boolean -> "Boolean"
is Reference.Primitive.Type.Bytes -> "Bytes"
is Reference.Primitive.Type.Integer -> when(type.precision){
is Reference.Primitive.Type.Integer -> when (type.precision) {
Reference.Primitive.Type.Precision.P32 -> "Integer32"
Reference.Primitive.Type.Precision.P64 -> "Integer"
}
is Reference.Primitive.Type.Number -> when(type.precision){

is Reference.Primitive.Type.Number -> when (type.precision) {
Reference.Primitive.Type.Precision.P32 -> "Number32"
Reference.Primitive.Type.Precision.P64 -> "Number"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,7 @@ abstract class Emitter(
)
}
}

interface HasEmitter {
val emitter: Emitter
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ open class Logger(logLevel: Level?) {
}
}

interface HasLogger {
val logger: Logger
}

val noLogger = object : Logger(logLevel = null) {}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CompileChannelTest {
|
""".trimMargin()

compiler(KotlinEmitter()) shouldBeRight kotlin
compiler { KotlinEmitter(logger = it) } shouldBeRight kotlin
}

@Test
Expand All @@ -39,7 +39,7 @@ class CompileChannelTest {
|
""".trimMargin()

compiler(JavaEmitter()) shouldBeRight java
compiler { JavaEmitter(logger = it) } shouldBeRight java
}

@Test
Expand All @@ -51,7 +51,7 @@ class CompileChannelTest {
|
""".trimMargin()

compiler(ScalaEmitter()) shouldBeRight scala
compiler { ScalaEmitter(logger = it) } shouldBeRight scala
}

@Test
Expand All @@ -61,7 +61,7 @@ class CompileChannelTest {
|
""".trimMargin()

compiler(TypeScriptEmitter()) shouldBeRight ts
compiler { TypeScriptEmitter(logger = it) } shouldBeRight ts
}

@Test
Expand All @@ -70,6 +70,6 @@ class CompileChannelTest {
|channel Queue -> String
""".trimMargin()

compiler(WirespecEmitter()) shouldBeRight wirespec
compiler { WirespecEmitter(logger = it) } shouldBeRight wirespec
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class CompileEnumTest {
|
""".trimMargin()

compiler(KotlinEmitter()) shouldBeRight kotlin
compiler { KotlinEmitter(logger = it) } shouldBeRight kotlin
}

@Test
Expand Down Expand Up @@ -67,7 +67,7 @@ class CompileEnumTest {
|
""".trimMargin()

compiler(JavaEmitter()) shouldBeRight java
compiler { JavaEmitter(logger = it) } shouldBeRight java
}

@Test
Expand All @@ -87,7 +87,7 @@ class CompileEnumTest {
|
""".trimMargin()

compiler(ScalaEmitter()) shouldBeRight scala
compiler { ScalaEmitter(logger = it) } shouldBeRight scala
}

@Test
Expand All @@ -97,7 +97,7 @@ class CompileEnumTest {
|
""".trimMargin()

compiler(TypeScriptEmitter()) shouldBeRight ts
compiler { TypeScriptEmitter(logger = it) } shouldBeRight ts
}

@Test
Expand All @@ -109,6 +109,6 @@ class CompileEnumTest {
|
""".trimMargin()

compiler(WirespecEmitter()) shouldBeRight wirespec
compiler { WirespecEmitter(logger = it) } shouldBeRight wirespec
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class CompileFullEndpointTest {
|
""".trimMargin()

compiler(KotlinEmitter()) shouldBeRight kotlin
compiler { KotlinEmitter(logger = it) } shouldBeRight kotlin
}

@Test
Expand Down Expand Up @@ -292,7 +292,7 @@ class CompileFullEndpointTest {
|
""".trimMargin()

compiler(JavaEmitter()) shouldBeRight java
compiler { JavaEmitter(logger = it) } shouldBeRight java
}

@Test
Expand Down Expand Up @@ -326,7 +326,7 @@ class CompileFullEndpointTest {
|
""".trimMargin()

compiler(ScalaEmitter()) shouldBeRight scala
compiler { ScalaEmitter(logger = it) } shouldBeRight scala
}

@Test
Expand Down Expand Up @@ -476,7 +476,7 @@ class CompileFullEndpointTest {
|
""".trimMargin()

compiler(TypeScriptEmitter()) shouldBeRight ts
compiler { TypeScriptEmitter(logger = it) } shouldBeRight ts
}

@Test
Expand Down Expand Up @@ -509,6 +509,6 @@ class CompileFullEndpointTest {
|
""".trimMargin()

compiler(WirespecEmitter()) shouldBeRight wirespec
compiler { WirespecEmitter(logger = it) } shouldBeRight wirespec
}
}
Loading

0 comments on commit 69f8ca0

Please sign in to comment.