Skip to content

Commit

Permalink
refactor: emit identifier (#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
jerrevanveluw authored Nov 12, 2024
1 parent ac583c3 commit e928cfe
Show file tree
Hide file tree
Showing 21 changed files with 385 additions and 374 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import community.flock.wirespec.compiler.core.parse.Endpoint;
import community.flock.wirespec.compiler.core.parse.Enum;
import community.flock.wirespec.compiler.core.parse.Field;
import community.flock.wirespec.compiler.core.parse.Identifier;
import community.flock.wirespec.compiler.core.parse.Node;
import community.flock.wirespec.compiler.core.parse.Reference;
import community.flock.wirespec.compiler.core.parse.Refined;
Expand All @@ -27,7 +28,7 @@ public CustomEmitter(@NotNull Logger logger, boolean split) {
@NotNull
@Override
public String emitName(@NotNull Definition definition) {
return definition.getIdentifier() + "Custom";
return emit(definition.getIdentifier()) + "Custom";
}

@NotNull
Expand Down Expand Up @@ -67,7 +68,7 @@ public String emit(@NotNull Enum anEnum) {

@NotNull
@Override
public String emit(@NotNull Union aUnion) {
public String emit(@NotNull Union union) {
return notYetImplemented();
}

Expand Down Expand Up @@ -106,4 +107,10 @@ public String emit(@NotNull Field field) {
public String emit(@NotNull Reference reference) {
return notYetImplemented();
}

@NotNull
@Override
public String emit(@NotNull Identifier identifier) {
return identifier.getValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import community.flock.wirespec.compiler.core.orNull
import community.flock.wirespec.compiler.core.parse.AST
import community.flock.wirespec.compiler.core.parse.Channel
import community.flock.wirespec.compiler.core.parse.Definition
import community.flock.wirespec.compiler.core.parse.DefinitionIdentifier
import community.flock.wirespec.compiler.core.parse.Endpoint
import community.flock.wirespec.compiler.core.parse.Enum
import community.flock.wirespec.compiler.core.parse.Field
import community.flock.wirespec.compiler.core.parse.FieldIdentifier
import community.flock.wirespec.compiler.core.parse.Identifier
import community.flock.wirespec.compiler.core.parse.Identifier.Type.*
import community.flock.wirespec.compiler.core.parse.Reference
import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
Expand All @@ -36,12 +37,12 @@ open class JavaEmitter(
""".trimMargin()

override fun Definition.emitName(): String = when (this) {
is Endpoint -> "${identifier.emit(Class)}Endpoint"
is Channel -> "${identifier.emit(Class)}Channel"
is Enum -> identifier.emit(Class)
is Refined -> identifier.emit(Class)
is Type -> identifier.emit(Class)
is Union -> identifier.emit(Class)
is Endpoint -> "${emit(identifier)}Endpoint"
is Channel -> "${emit(identifier)}Channel"
is Enum -> emit(identifier)
is Refined -> emit(identifier)
is Type -> emit(identifier)
is Union -> emit(identifier)
}

override fun notYetImplemented() =
Expand Down Expand Up @@ -80,7 +81,7 @@ open class JavaEmitter(
override fun Type.Shape.emit() = value.joinToString("\n") { "${Spacer}${it.emit()}," }.dropLast(1)

override fun Field.emit() =
"${if (isNullable) "java.util.Optional<${reference.emit()}>" else reference.emit()} ${identifier.emit(Field)}"
"${if (isNullable) "java.util.Optional<${reference.emit()}>" else reference.emit()} ${emit(identifier)}"

override fun Reference.emit() = emitType()
.let { if (isIterable) "java.util.List<$it>" else it }
Expand All @@ -107,13 +108,13 @@ open class JavaEmitter(
Reference.Primitive.Type.Boolean -> "Boolean"
}

override fun Identifier.emit(type: Identifier.Type) = when (type) {
Class -> value.sanitizeSymbol().firstToUpper()
Field -> value.sanitizeSymbol().firstToLower().sanitizeKeywords()
override fun emit(identifier: Identifier) = when (identifier) {
is DefinitionIdentifier -> identifier.value.sanitizeSymbol().firstToUpper()
is FieldIdentifier -> identifier.value.sanitizeSymbol().firstToLower().sanitizeKeywords()
}

override fun emit(refined: Refined) = """
|public record ${refined.identifier.emit(Class)} (String value) implements Wirespec.Refined {
|public record ${emit(refined.identifier)} (String value) implements Wirespec.Refined {
|${Spacer}@Override
|${Spacer}public String toString() { return value; }
|${Spacer}public static boolean validate(${refined.emitName()} record) {
Expand All @@ -129,10 +130,10 @@ open class JavaEmitter(
"""${Spacer}return java.util.regex.Pattern.compile("${expression.replace("\\", "\\\\")}").matcher(record.value).find();"""

override fun emit(enum: Enum) = """
|public enum ${enum.identifier.emit(Class)} implements Wirespec.Enum {
|public enum ${emit(enum.identifier)} implements Wirespec.Enum {
|${enum.entries.joinToString(",\n") { "${it.sanitizeEnum().sanitizeKeywords()}(\"$it\")" }.spacer()};
|${Spacer}public final String label;
|${Spacer}${enum.identifier.emit(Class)}(String label) {
|${Spacer}${emit(enum.identifier)}(String label) {
|${Spacer(2)}this.label = label;
|${Spacer}}
|${Spacer}@Override
Expand All @@ -153,14 +154,14 @@ open class JavaEmitter(
""".trimMargin()

override fun emit(channel: Channel) = """
|interface ${channel.identifier.emit(Class)}Channel {
|interface ${emit(channel.identifier)}Channel {
| void invoke(${channel.reference.emitWrap(channel.isNullable)} message)
|}
|
""".trimMargin()

override fun emit(endpoint: Endpoint) = """
|public interface ${endpoint.identifier.emit(Class)}Endpoint extends Wirespec.Endpoint {
|public interface ${emit(endpoint.identifier)}Endpoint extends Wirespec.Endpoint {
|${endpoint.pathParams.emitObject("Path", "Wirespec.Path") { it.emit() }}
|
|${endpoint.queries.emitObject("Queries", "Wirespec.Queries") { it.emit() }}
Expand Down Expand Up @@ -214,7 +215,7 @@ open class JavaEmitter(
""".trimMargin()

open fun emitHandleFunction(endpoint: Endpoint) =
"java.util.concurrent.CompletableFuture<Response<?>> ${endpoint.identifier.emit(Field)}(Request request);"
"java.util.concurrent.CompletableFuture<Response<?>> ${emit(endpoint.identifier).firstToLower()}(Request request);"

private fun Endpoint.emitStatusInterfaces() = responses
.map { it.status.first() }
Expand Down Expand Up @@ -274,7 +275,7 @@ open class JavaEmitter(
).joinToString()
}) implements Response${status.first()}XX<${content.emit()}>, Response${content.emit().concatGenerics()} {
|${Spacer(2)}@Override public int getStatus() { return ${status.fixStatus()}; }
|${Spacer(2)}${headers.joinToString { it.identifier.emit(Field) }.let { "@Override public Headers getHeaders() { return new Headers($it); }" }}
|${Spacer(2)}${headers.joinToString { emit(it.identifier) }.let { "@Override public Headers getHeaders() { return new Headers($it); }" }}
|${Spacer(2)}@Override public ${content.emit()} getBody() { return ${if(content == null) "null" else "body"}; }
|${Spacer(1)}${headers.emitObject("Headers", "Wirespec.Response.Headers") { it.emit() }}
|${Spacer}}
Expand All @@ -290,10 +291,10 @@ open class JavaEmitter(
).joinToString()
}) {\n${Spacer(3)}${
listOfNotNull(
endpoint.pathParams.joinToString { it.identifier.emit(Field) }.let { "this.path = new Path($it);" },
endpoint.pathParams.joinToString { emit(it.identifier) }.let { "this.path = new Path($it);" },
"this.method = Wirespec.Method.${endpoint.method.name};",
endpoint.queries.joinToString { it.identifier.emit(Field) }.let { "this.queries = new Queries($it);" },
endpoint.headers.joinToString { it.identifier.emit(Field) }
endpoint.queries.joinToString { emit(it.identifier) }.let { "this.queries = new Queries($it);" },
endpoint.headers.joinToString { emit(it.identifier) }
.let { "this.headers = new RequestHeaders($it);" },
"this.body = ${content?.let { "body" } ?: "null"};"
).joinToString("\n${Spacer(3)}")
Expand All @@ -318,7 +319,7 @@ open class JavaEmitter(
"""${Spacer(4)}case $status -> new Response${status.firstToUpper()}(${this.emitDeserializedParams()});"""

private fun Field.emitSerialized(fields: String) =
"""java.util.Map.entry("${identifier.value}", serialization.serialize(request.$fields.${identifier.emit(Field)}, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable})))"""
"""java.util.Map.entry("${identifier.value}", serialization.serialize(request.$fields.${emit(identifier)}, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable})))"""

private fun IndexedValue<Endpoint.Segment.Param>.emitDeserialized() =
"""${Spacer(4)}serialization.<${value.reference.emit()}>deserialize(request.path().get(${index}), Wirespec.getType(${value.reference.emitType()}.class, ${value.reference.isIterable}))"""
Expand All @@ -327,21 +328,20 @@ open class JavaEmitter(
"""${Spacer(4)}java.util.Optional.ofNullable(request.$fields().get("${identifier.value}")).map(it -> serialization.<${reference.emit()}>deserialize(it, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable})))${if(!isNullable) ".get()" else ""}"""

private fun Field.emitSerializedMap(fields: String) =
"""java.util.Map.entry("${identifier.value}", serialization.serialize(response.$fields.${identifier.emit(Field)}, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable})))"""
"""java.util.Map.entry("${identifier.value}", serialization.serialize(response.$fields.${emit(identifier)}, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable})))"""

private fun Endpoint.Segment.Param.emitIdentifier() = "serialization.serialize(request.path.${identifier.emit(Field).firstToLower()}, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable}))"
private fun Endpoint.Segment.Param.emitIdentifier() = "serialization.serialize(request.path.${emit(identifier).firstToLower()}, Wirespec.getType(${reference.emitType()}.class, ${reference.isIterable}))"

private fun Endpoint.Content?.emitType() = this?.reference?.emitType() ?: "Void"
private fun Endpoint.Content?.emit() = this?.reference?.emit() ?: "Void"

private fun Endpoint.Segment.Param.emit() = "${reference.emit()} ${identifier.emit(Field)}"
private fun Endpoint.Segment.Param.emit() = "${reference.emit()} ${emit(identifier)}"

private fun Reference.emitWrap(isNullable: Boolean): String = value
.let { if (isIterable) "java.util.Optional<$it>" else it }
.let { if (isNullable) "java.util.List<$it>" else it }
.let { if (isNullable) "java.util.Optional<$it>" else it }
.let { if (isIterable) "java.util.List<$it>" else it }
.let { if (isDictionary) "java.util.Map<String, $it>" else it }


private fun String.fixStatus(): String = when (this) {
"default" -> "200"
else -> this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import community.flock.wirespec.compiler.core.orNull
import community.flock.wirespec.compiler.core.parse.AST
import community.flock.wirespec.compiler.core.parse.Channel
import community.flock.wirespec.compiler.core.parse.Definition
import community.flock.wirespec.compiler.core.parse.DefinitionIdentifier
import community.flock.wirespec.compiler.core.parse.Endpoint
import community.flock.wirespec.compiler.core.parse.Enum
import community.flock.wirespec.compiler.core.parse.Field
import community.flock.wirespec.compiler.core.parse.FieldIdentifier
import community.flock.wirespec.compiler.core.parse.Identifier
import community.flock.wirespec.compiler.core.parse.Identifier.Type.*
import community.flock.wirespec.compiler.core.parse.Reference
import community.flock.wirespec.compiler.core.parse.Refined
import community.flock.wirespec.compiler.core.parse.Type
Expand All @@ -38,12 +39,12 @@ open class KotlinEmitter(
""".trimMargin()

override fun Definition.emitName(): String = when (this) {
is Endpoint -> "${identifier.emit(Class)}Endpoint"
is Channel -> "${identifier.emit(Class)}Channel"
is Enum -> identifier.emit(Class)
is Refined -> identifier.emit(Class)
is Type -> identifier.emit(Class)
is Union -> identifier.emit(Class)
is Endpoint -> "${emit(identifier)}Endpoint"
is Channel -> "${emit(identifier)}Channel"
is Enum -> emit(identifier)
is Refined -> emit(identifier)
is Type -> emit(identifier)
is Union -> emit(identifier)
}

override fun notYetImplemented() =
Expand Down Expand Up @@ -74,7 +75,7 @@ open class KotlinEmitter(

override fun Type.Shape.emit() = value.joinToString("\n") { "${Spacer}val ${it.emit()}," }.dropLast(1)

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

override fun Reference.emit() = when (this) {
is Reference.Unit -> "Unit"
Expand All @@ -90,9 +91,9 @@ open class KotlinEmitter(
.let { if (isIterable) "List<$it>" else it }
.let { if (isDictionary) "Map<String, $it>" else it }

override fun Identifier.emit(type: Identifier.Type) = when(type){
Class -> value.sanitizeSymbol().firstToUpper()
Field -> value.sanitizeSymbol().firstToLower().sanitizeKeywords()
override fun emit(identifier: Identifier) = when (identifier) {
is DefinitionIdentifier -> identifier.value.sanitizeSymbol().firstToUpper()
is FieldIdentifier -> identifier.value.sanitizeSymbol().firstToLower().sanitizeKeywords()
}

override fun emit(refined: Refined) = """
Expand Down Expand Up @@ -122,14 +123,14 @@ open class KotlinEmitter(
""".trimMargin()

override fun emit(channel: Channel) = """
|interface ${channel.identifier.emit(Class)}Channel {
|interface ${emit(channel.identifier)}Channel {
| operator fun invoke(message: ${channel.reference.emitWrap(channel.isNullable)})
|}
|
""".trimMargin()

override fun emit(endpoint: Endpoint) = """
|object ${endpoint.identifier.emit(Class)}Endpoint : Wirespec.Endpoint {
|object ${emit(endpoint.identifier)}Endpoint : Wirespec.Endpoint {
|${endpoint.pathParams.emitObject("Path", "Wirespec.Path") { it.emit() }}
|
|${endpoint.queries.emitObject("Queries", "Wirespec.Queries") { it.emit() }}
Expand Down Expand Up @@ -177,7 +178,7 @@ open class KotlinEmitter(
""".trimMargin()

open fun emitHandleFunction(endpoint: Endpoint): String =
"suspend fun ${endpoint.identifier.emit(Class).firstToLower()}(request: Request): Response<*>"
"suspend fun ${emit(endpoint.identifier).firstToLower()}(request: Request): Response<*>"

private fun Endpoint.emitStatusInterfaces() = responses
.map { it.status[0] }
Expand All @@ -199,10 +200,10 @@ open class KotlinEmitter(

fun Endpoint.Request.emit(endpoint: Endpoint) = """
|${Spacer}${emitConstructor(endpoint)}
|${Spacer(2)}override val path = Path${endpoint.pathParams.joinToString { it.identifier.emit(Field) }.brace()}
|${Spacer(2)}override val path = Path${endpoint.pathParams.joinToString { emit(it.identifier) }.brace()}
|${Spacer(2)}override val method = Wirespec.Method.${endpoint.method.name}
|${Spacer(2)}override val queries = Queries${endpoint.queries.joinToString { it.identifier.emit(Field) }.brace()}
|${Spacer(2)}override val headers = Headers${endpoint.headers.joinToString { it.identifier.emit(Field) }.brace()}${if (content == null) "\n${Spacer(2)}override val body = Unit" else ""}
|${Spacer(2)}override val queries = Queries${endpoint.queries.joinToString { emit(it.identifier) }.brace()}
|${Spacer(2)}override val headers = Headers${endpoint.headers.joinToString { emit(it.identifier) }.brace()}${if (content == null) "\n${Spacer(2)}override val body = Unit" else ""}
|${Spacer}}
|
|${Spacer}fun toRequest(serialization: Wirespec.Serializer<String>, request: Request): Wirespec.RawRequest =
Expand Down Expand Up @@ -256,23 +257,23 @@ open class KotlinEmitter(
""".trimMargin()

private fun Field.emitSerialized(fields: String) =
"""request.$fields.${identifier.emit(Field)}?.let{"${identifier.value}" to serialization.serialize(it, typeOf<${reference.emit()}>())}"""
"""request.$fields.${emit(identifier)}?.let{"${identifier.value}" to serialization.serialize(it, typeOf<${reference.emit()}>())}"""

private fun IndexedValue<Endpoint.Segment.Param>.emitDeserialized() =
"""${Spacer(3)}${value.identifier.emit(Field)} = serialization.deserialize(request.path[${index}], typeOf<${value.reference.emit()}>())"""
"""${Spacer(3)}${emit(value.identifier)} = serialization.deserialize(request.path[${index}], typeOf<${value.reference.emit()}>())"""

private fun Field.emitDeserialized(fields: String) =
if (isNullable)
"""${Spacer(3)}${identifier.emit(Field)} = request.$fields["${identifier.value}"]?.let{ serialization.deserialize(it, typeOf<${reference.emit()}>()) }"""
"""${Spacer(3)}${emit(identifier)} = request.$fields["${identifier.value}"]?.let{ serialization.deserialize(it, typeOf<${reference.emit()}>()) }"""
else
"""${Spacer(3)}${identifier.emit(Field)} = serialization.deserialize(requireNotNull(request.$fields["${identifier.value}"]) { "${identifier.emit(Field)} is null" }, typeOf<${reference.emit()}>())"""
"""${Spacer(3)}${emit(identifier)} = serialization.deserialize(requireNotNull(request.$fields["${identifier.value}"]) { "${emit(identifier)} is null" }, typeOf<${reference.emit()}>())"""

private fun Endpoint.Segment.Param.emitIdentifier() =
"request.path.${identifier.emit(Field)}.let{serialization.serialize(it, typeOf<${reference.emit()}>())}"
"request.path.${emit(identifier)}.let{serialization.serialize(it, typeOf<${reference.emit()}>())}"

private fun Endpoint.Content?.emit() = this?.reference?.emit() ?: "Unit"

private fun Endpoint.Segment.Param.emit() = "${identifier.emit(Field)}: ${reference.emit()}"
private fun Endpoint.Segment.Param.emit() = "${emit(identifier)}: ${reference.emit()}"

private fun String.brace() = wrap("(", ")")
private fun String.wrap(prefix: String, postfix: String) = if (isEmpty()) "" else "$prefix$this$postfix"
Expand Down
Loading

0 comments on commit e928cfe

Please sign in to comment.