-
Notifications
You must be signed in to change notification settings - Fork 8
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
feat: introduce verb visibility modifiers #1326
Conversation
29c78f4
to
e27112e
Compare
e27112e
to
8b383ae
Compare
8b383ae
to
fbde13a
Compare
fbde13a
to
d8a7858
Compare
val path: String? | ||
) | ||
|
||
private fun extractExportAnnotation(verb: KtNamedFunction, bindingContext: BindingContext): ExportAnnotation { |
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.
nit- i think this can be accomplished without any member data and so it can be a static function declared in the companion object
below, like the following:
private fun KtAnnotationEntry.toExportAnnotation(): ExportAnnotation {
var visibility: Visibility? = null
var ingress: Ingress? = null
var method: Method? = null
var path: String? = null
exportAnnotation?.valueArguments?.forEach { arg ->
when {
arg.getArgumentName()?.asName?.asString() == "visibility" || arg.getArgumentExpression()?.getType(bindingContext)?.fqNameOrNull()?.asString() == Visibility::class.qualifiedName -> {
visibility = kotlin.runCatching { Visibility.valueOf(arg.getArgumentExpression()?.text?.substringAfterLast('.') ?: "") }.getOrNull()
}
arg.getArgumentName()?.asName?.asString() == "ingress" || arg.getArgumentExpression()?.getType(bindingContext)?.fqNameOrNull()?.asString() == Ingress::class.qualifiedName -> {
ingress = kotlin.runCatching { Ingress.valueOf(arg.getArgumentExpression()?.text?.substringAfterLast('.') ?: "") }.getOrNull()
}
arg.getArgumentName()?.asName?.asString() == "method" || arg.getArgumentExpression()?.getType(bindingContext)?.fqNameOrNull()?.asString() == Method::class.qualifiedName -> {
method = kotlin.runCatching { Method.valueOf(arg.getArgumentExpression()?.text?.substringAfterLast('.') ?: "") }.getOrNull()
}
arg.getArgumentName()?.asName?.asString() == "path" || arg.getArgumentExpression()?.getType(bindingContext)?.fqNameOrNull()?.asString() == String::class.qualifiedName -> {
path = arg.getArgumentExpression()?.text?.trim('"')
}
}
}
return ExportAnnotation(visibility, ingress, method, path)
}
then to use it, you'd do annotationEntry.toExportAnnotation()
return verb.annotationEntries.firstOrNull { | ||
bindingContext.get(BindingContext.ANNOTATION, it)?.fqName?.asString() == HttpIngress::class.qualifiedName | ||
bindingContext.get(BindingContext.ANNOTATION, it)?.fqName?.asString() == Export::class.qualifiedName |
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.
since we get the ingress information from the export annotation now, how about we pass the full KtAnnotationEntry
instead of ExportAnnotation
? then we won't need to derive it again and we can lift everything out of the let
below. we can use annotationEntry.toExportAnnotation()
to get the export fields
Request: &schema.Ref{Name: "EchoRequest"}, | ||
Response: &schema.Ref{Name: "EchoResponse"}, | ||
Name: "echo", | ||
Visibility: "internal", |
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.
Use the constants here and elsewhere rather than literals - it will result in a compiler error if they get renamed, unlike the literals which will silently add invalid data.
|
||
Export bool `parser:"@'export'"` | ||
Visibility schema.Visibility `parser:"@('public' | 'internal' | 'private')"` |
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.
Can we somehow catch //ftl:export
(probably not here) and return an error indicating to use these now?
isVerb = true | ||
if pctx.module.Name == "" { | ||
pctx.module.Name = pctx.pkg.Name | ||
} else if pctx.module.Name != pctx.pkg.Name { | ||
pctx.errors.add(errorf(node, "function export directive must be in the module package")) | ||
pctx.errors.add(errorf(node, "function visibility directive must be in the module package")) |
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 does this error mean exctly? Must be in the root module package?
Fixes #1324
This adds the new schema changes and parser implementations. Once this PR lands, we'll need to update all the other repos to make sure they work with these breaking changes.