-
-
Notifications
You must be signed in to change notification settings - Fork 251
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
Add Parser support for Type System Extensions #266
Add Parser support for Type System Extensions #266
Conversation
7247a3f
to
8fb5a59
Compare
8fb5a59
to
a818c15
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks very good! The only thing missing is the valid case where no field is provided but only directives/implements/etc. It'll make the parser a bit more complex unfortunately but we have to support all valid syntax 😄
@ghostdogpr Thanks for looking into this! And yeah, I totally missed the alternative cases, so I'll make sure to add them 😀 |
a75bf22
to
e0bb285
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is working well, I suggest modeling the parsers more strictly after the spec. In some cases (like object) it will be a little simpler, but the main benefit is that it's easier to find which code corresponds to which spec definition When specs will evolve in the future I think it might be easier to apply the changes if the code follows it closely. What do you think?
private def objectTypeExtension[_: P]: P[ObjectTypeExtension] = | ||
P( | ||
"extend type" ~/ ( | ||
objectTypeExtensionWithInterfacesAndOptionalFields | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can reduce to 3 cases:
- fields + optional interfaces + optional directives
- no fields + directives + optional interfaces
- no fields, no directives, interfaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ghostdogpr Yeah, actually my first attempt was modelling the Parser more strictly after the specs, like this:
private def objectTypeExtensionWithOptionalInterfacesOptionalDirectivesAndFields[_: P]: P[ObjectTypeExtension] =
P(name ~ implements.? ~ directives.? ~ "{" ~ fieldDefinition.rep ~ "}").map {
case (name, implements, directives, fields) =>
ObjectTypeExtension(
name,
implements.getOrElse(Nil),
directives.getOrElse(Nil),
fields.toList
)
}
private def objectTypeExtensionWithOptionalInterfacesAndDirectives[_: P]: P[ObjectTypeExtension] =
P(name ~ implements.? ~ directives).map {
case (name, implements, directives) =>
ObjectTypeExtension(
name,
implements.getOrElse(Nil),
directives,
Nil
)
}
private def objectTypeExtensionWithInterfaces[_: P]: P[ObjectTypeExtension] =
P(name ~ implements).map {
case (name, implements) =>
ObjectTypeExtension(
name,
implements,
Nil,
Nil
)
}
private def objectTypeExtension[_: P]: P[ObjectTypeExtension] =
P(
"extend type" ~/ (
objectTypeExtensionWithOptionalInterfacesOptionalDirectivesAndFields |
objectTypeExtensionWithOptionalInterfacesAndDirectives |
objectTypeExtensionWithInterfaces
)
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, that didn't work as expected, when running unit tests I've got failures for some cases. Here are the error messages I got (I've enabled verboseFailures temporally):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extend type with interfaces and directives
[info] Fiber failed.
[info] A checked error was not handled.
[info] Parsing Error: Expected document:1:1 / objectTypeExtension:1:1 / objectTypeExtensionWithOptionalInterfacesOptionalDirectivesAndFields:1:13 / "{":1:58, found ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extend type with directives
[info] Fiber failed.
[info] A checked error was not handled.
[info] Parsing Error: Expected document:1:1 / objectTypeExtension:1:1 / objectTypeExtensionWithOptionalInterfacesOptionalDirectivesAndFields:1:13 / "{":1:33, found ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried other combinations as well, but none of them worked for all cases, that's why I had to implement the parser rules in a different way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think @ghostdogpr? Maybe I'm missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm that’s strange indeed. I can’t see anything wrong with the code at first sight but tomorrow I’ll get your branch and try to figure it out in debug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And, I got similar issues when I tried to define parsers for the other type extension cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks for your help @ghostdogpr!
} | ||
|
||
private def schemaExtension[_: P]: P[SchemaExtension] = | ||
P("extend schema" ~/ (schemaExtensionWithDirectivesAndOptionalOperations | schemaExtensionWithOperations)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about sticking to the spec definitions and have:
- operations + optional directives
- no operations, directives
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly to the above case, my first version was more like the spec definitions:
private def schemaExtensionWithOptionalDirectivesAndOperations[_: P]: P[SchemaExtension] =
P(directives.? ~ "{" ~ rootOperationTypeDefinition.rep ~ "}").map {
case (directives, ops) =>
val opsMap = ops.toMap
SchemaExtension(
directives.getOrElse(Nil),
opsMap.get(OperationType.Query).map(_.name),
opsMap.get(OperationType.Mutation).map(_.name),
opsMap.get(OperationType.Subscription).map(_.name)
)
}
private def schemaExtensionWithDirectives[_: P]: P[SchemaExtension] =
P(directives).map(SchemaExtension(_, None, None, None))
private def schemaExtension[_: P]: P[SchemaExtension] =
P("extend schema" ~/ (schemaExtensionWithOptionalDirectivesAndOperations | schemaExtensionWithDirectives))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, this didn't work for all cases, I got an error for one of the unit tests:
extend schema with directives
[info] Fiber failed.
[info] A checked error was not handled.
[info] Parsing Error: Expected document:1:1 / schemaExtension:1:1 / schemaExtensionWithOptionalDirectivesAndOperations:1:15 / "{":1:30, found ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried other combinations that were more similar to the specs too, but none of them worked
@jorge-vasquez-2301 OK, I found the reason. You just need to change the |
Ohhhh, didn't realize that, thanks @ghostdogpr! I'll make the adjustments |
e0bb285
to
392af77
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good! Thanks for the contribution!
closes #238