Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interfaces #7

Merged
merged 6 commits into from
Apr 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Kotlin/graphql-simple-bindings-boot-shell/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>community.flock</groupId>
<artifactId>graphql-simple-bindings</artifactId>
<version>0.2.0</version>
<version>0.3.0</version>
</parent>

<artifactId>graphql-simple-bindings-boot-shell</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
interface Account {
id: ID!
lastLogin: DateTime!
}

type AccountPassword implements Account{
id: ID!
lastLogin: DateTime!
}

type AccountKey implements Account {
id: ID!
lastLogin: DateTime!
key: String!
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
scalar Date
scalar DateTime
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
type Product {
title: String
}
stock: Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package community.flock.graphqlsimplebindings
import community.flock.graphqlsimplebindings.generated.Date
import community.flock.graphqlsimplebindings.generated.Product
import community.flock.graphqlsimplebindings.generated.User
import community.flock.graphqlsimplebindings.generated.Account

data class Root(
val date: Date,
val product: Product,
val user: User
val user: User,
val accounts: List<Account>
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package community.flock.graphqlsimplebindings

import community.flock.graphqlsimplebindings.generated.Product
import community.flock.graphqlsimplebindings.generated.Type
import community.flock.graphqlsimplebindings.generated.User
import community.flock.graphqlsimplebindings.generated.*
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import java.time.LocalDate
Expand All @@ -13,12 +11,23 @@ class RootEndpoint {
@GetMapping
fun getRoot() = Root(
date = LocalDate.now(),
product = Product("My Awesome Product"),
product = Product("My Awesome Product", 10),
user = User(
id = "0",
firstName = "Ernie",
lastName = "Sesamstraat",
type = Type.A
),
accounts = listOf(
AccountPassword(
id = "0",
lastLogin = DateTime.now()
),
AccountKey(
id = "0",
key = "123",
lastLogin = DateTime.now()
)
)
)

Expand Down
2 changes: 1 addition & 1 deletion Kotlin/graphql-simple-bindings-emitter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>community.flock</groupId>
<artifactId>graphql-simple-bindings</artifactId>
<version>0.2.0</version>
<version>0.3.0</version>
</parent>

<artifactId>graphql-simple-bindings-emitter</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
package community.flock.graphqlsimplebindings.emitter

import community.flock.graphqlsimplebindings.exceptions.ScalarTypeDefinitionEmitterException
import community.flock.graphqlsimplebindings.emitter.meta.Emitter
import community.flock.graphqlsimplebindings.exceptions.ScalarTypeDefinitionEmitterException
import graphql.language.*

const val SPACES = " "

class KotlinEmitter(private val packageName: String = "community.flock.graphqlsimplebindings.generated") : Emitter() {



override fun emitDocument(document: Document): String = super.emitDocument(document)
.let { "package $packageName\n\n$it" }

override fun ObjectTypeDefinition.emitObjectTypeDefinition() = "data class $name(\n${fieldDefinitions.emitDefinitionFields()}\n)\n"
override fun ObjectTypeDefinition.emitObjectTypeDefinition(document: Document) = "data class $name(\n${emitFields(document)}\n)${emitInterfaces()}\n"

override fun List<FieldDefinition>.emitDefinitionFields() = joinToString(",\n") { it.emitDefinitionField() }
override fun FieldDefinition.emitDefinitionField() = "${SPACES}${SPACES}val $name: ${type.emitType()}"
private fun ObjectTypeDefinition.emitInterfaces(): String? = if(implements.isNotEmpty()){
":" + (implements as List<TypeName>).joinToString(",") { it.name }
} else{
""
}

override fun InputObjectTypeDefinition.emitInputObjectTypeDefinition() = "data class ${name}(\n${inputValueDefinitions.emitInputFields()}\n)\n"
override fun List<InputValueDefinition>.emitInputFields() = joinToString(",\n") { it.emitInputField() }
override fun InputValueDefinition.emitInputField() = "${SPACES}${SPACES}val $name: ${type.emitType()}"
override fun ObjectTypeDefinition.emitFields(document: Document) = fieldDefinitions.joinToString(",\n") { SPACES + SPACES + it.emitOverwrite(this, document) + it.emitDefinitionField() }
private fun FieldDefinition.emitOverwrite(definition: ObjectTypeDefinition, document: Document) = document.definitions
.filterIsInstance(InterfaceTypeDefinition::class.java)
.filter { definition.implements
.map { (it as TypeName).name }
.contains(it.name) }
.flatMap { it.fieldDefinitions }
.filter { it.name == this.name }
.any()
.let { if(it) "override " else "" }

override fun FieldDefinition.emitDefinitionField() = "val $name: ${type.emitType()}"

override fun InterfaceTypeDefinition.emitInterfaceTypeDefinition() = throw NotImplementedError()
override fun InterfaceTypeDefinition.emitInterfaceTypeDefinition() = "interface ${name}{\n${emitFields()}\n}\n"
override fun InterfaceTypeDefinition.emitFields() = fieldDefinitions.joinToString("\n") { SPACES + SPACES + it.emitField() }
override fun FieldDefinition.emitField() = "val $name: ${type.emitType()}"

override fun InputObjectTypeDefinition.emitInputObjectTypeDefinition() = "data class ${name}(\n${inputValueDefinitions.emitInputFields()}\n)\n"
override fun List<InputValueDefinition>.emitInputFields() = joinToString(",\n") { SPACES + SPACES + it.emitInputField() }
override fun InputValueDefinition.emitInputField() = "val $name: ${type.emitType()}"

override fun ScalarTypeDefinition.emitScalarTypeDefinition(): String? = when (name) {
"Date" -> "typealias Date = java.time.LocalDate\n"
Expand All @@ -28,14 +49,14 @@ class KotlinEmitter(private val packageName: String = "community.flock.graphqlsi
}

override fun EnumTypeDefinition.emitEnumTypeDefinition(): String = "enum class $name{\n${enumValueDefinitions.emitEnumFields()}\n}\n"
override fun List<EnumValueDefinition>.emitEnumFields() = joinToString(",\n") { it.emitEnumField() }
override fun EnumValueDefinition.emitEnumField() = "${SPACES}$name"
override fun List<EnumValueDefinition>.emitEnumFields() = joinToString(",\n") { SPACES + it.emitEnumField() }
override fun EnumValueDefinition.emitEnumField() = name

override fun nullableListOf(type: Type<Type<*>>): String = nonNullableListOf(type).toNullable()
override fun nonNullableListOf(type: Type<Type<*>>): String = "List<${type.emitType()}>"
override fun String.toNullable(): String = "${toNonNullable()}?"
override fun String.toNonNullable(): String = when{
this == "ID" -> "String"
override fun String.toNonNullable(): String = when(this){
"ID" -> "String"
else -> this
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
package community.flock.graphqlsimplebindings.emitter

import community.flock.graphqlsimplebindings.emitter.TypeScriptEmitter.emitDefinitionField
import community.flock.graphqlsimplebindings.emitter.TypeScriptEmitter.emitDefinitionFields
import community.flock.graphqlsimplebindings.emitter.meta.Emitter
import community.flock.graphqlsimplebindings.exceptions.InputObjectTypeDefinitionEmitterException
import community.flock.graphqlsimplebindings.exceptions.ScalarTypeDefinitionEmitterException
import graphql.language.*

object TypeScriptEmitter : Emitter() {

override fun ObjectTypeDefinition.emitObjectTypeDefinition() = "export interface $name {\n${fieldDefinitions.emitDefinitionFields()};\n}\n"
override fun ObjectTypeDefinition.emitObjectTypeDefinition(document: Document) = "export interface $name {\n${emitFields(document)};\n}\n"

override fun List<FieldDefinition>.emitDefinitionFields() = joinToString(";\n") { it.emitDefinitionField() }
override fun ObjectTypeDefinition.emitFields(document: Document) = fieldDefinitions.joinToString(";\n") { it.emitDefinitionField() }
override fun FieldDefinition.emitDefinitionField() = " $name${type.emitType()}"

override fun InputObjectTypeDefinition.emitInputObjectTypeDefinition() = "export interface $name {\n${inputValueDefinitions.emitInputFields()};\n}\n"
override fun List<InputValueDefinition>.emitInputFields() = joinToString(";\n") { it.emitInputField() }
override fun InputValueDefinition.emitInputField() = " $name${type.emitType()}"

override fun InterfaceTypeDefinition.emitInterfaceTypeDefinition() = throw NotImplementedError()
override fun InterfaceTypeDefinition.emitInterfaceTypeDefinition() = "// Not implemented: $name"
override fun InterfaceTypeDefinition.emitFields() = throw NotImplementedError()
override fun FieldDefinition.emitField() = throw NotImplementedError()

override fun ScalarTypeDefinition.emitScalarTypeDefinition(): String? = when (name) {
"Date" -> null
"DateTime" -> null
else -> throw ScalarTypeDefinitionEmitterException(this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import graphql.language.*

internal interface DefinitionEmitter {

fun ObjectTypeDefinition.emitObjectTypeDefinition(): String
fun ObjectTypeDefinition.emitObjectTypeDefinition(document: Document): String

fun ScalarTypeDefinition.emitScalarTypeDefinition(): String?

fun InterfaceTypeDefinition.emitInterfaceTypeDefinition(): String

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import community.flock.graphqlsimplebindings.exceptions.TypeEmitterException
import graphql.language.*
import graphql.schema.idl.TypeInfo

abstract class Emitter : DefinitionEmitter, EnumEmitter, InputEmitter, FieldDefinitionEmitter, TypeEmitter {
abstract class Emitter : DefinitionEmitter, EnumEmitter, InputEmitter, InterfaceEmitter, FieldDefinitionEmitter, TypeEmitter {

open fun emitDocument(document: Document): String = document.definitions
.mapNotNull { it.emitDefinition() }
.mapNotNull { it.emitDefinition(document) }
.joinToString("\n")

private fun Definition<Definition<*>>.emitDefinition() = when (this) {
is ObjectTypeDefinition -> emitObjectTypeDefinition()
private fun Definition<Definition<*>>.emitDefinition(document: Document) = when (this) {
is ObjectTypeDefinition -> emitObjectTypeDefinition(document)
is ScalarTypeDefinition -> emitScalarTypeDefinition()
is InputObjectTypeDefinition -> emitInputObjectTypeDefinition()
is EnumTypeDefinition -> emitEnumTypeDefinition()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package community.flock.graphqlsimplebindings.emitter.meta

import graphql.language.Document
import graphql.language.FieldDefinition
import graphql.language.ObjectTypeDefinition

internal interface FieldDefinitionEmitter {

fun List<FieldDefinition>.emitDefinitionFields(): String
fun ObjectTypeDefinition.emitFields(document: Document): String

fun FieldDefinition.emitDefinitionField(): String

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package community.flock.graphqlsimplebindings.emitter.meta

import graphql.language.FieldDefinition
import graphql.language.InterfaceTypeDefinition
import graphql.language.ObjectTypeDefinition

internal interface InterfaceEmitter {

fun InterfaceTypeDefinition.emitInterfaceTypeDefinition(): String

fun InterfaceTypeDefinition.emitFields(): String

fun FieldDefinition.emitField(): String

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ internal class KotlinEmitterTest {
@Test
fun testInputTypes() = run("input")

@Test
fun testInterfaceTypes() = run("interface")

private fun run(name:String){
val schemaFile = javaClass.classLoader.getResource("$name.graphql")
val snapshotFile = javaClass.classLoader.getResource("$name.graphql.kt.snapshot")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
interface A {
hello1: String

}

interface B {
hello2: String
}

type C implements A{
hello1: String,
hello2: String,
world: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package community.flock.graphqlsimplebindings.generated

interface A{
val hello1: String?
}

interface B{
val hello2: String?
}

data class C(
override val hello1: String?,
val hello2: String?,
val world: String?
):A
2 changes: 1 addition & 1 deletion Kotlin/graphql-simple-bindings-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>community.flock</groupId>
<artifactId>graphql-simple-bindings</artifactId>
<version>0.2.0</version>
<version>0.3.0</version>
</parent>

<artifactId>graphql-simple-bindings-maven-plugin</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion Kotlin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</parent>
<groupId>community.flock</groupId>
<artifactId>graphql-simple-bindings</artifactId>
<version>0.2.0</version>
<version>0.3.0</version>
<name>graphql-simple-bindings</name>
<description>Generate Kotlin data classes and TypeScript interfaces from GraphQL schema's</description>

Expand Down