nitc :: RestfulPhase :: defaultinit
private class RestfulPhase
super Phase
# Classes with methods marked with the `restful` annotation
var restful_classes = new HashSet[MClassDef]
redef fun process_annotated_node(node, nat)
do
# Skip if we are not interested
var text = nat.n_atid.n_id.text
if text != "restful" then return
if not node isa AMethPropdef then
toolcontext.error(nat.location,
"Syntax Error: `restful` can only be applied on method definitions")
return
end
var mpropdef = node.mpropdef
if mpropdef == null then return
var mproperty = mpropdef.mproperty
var mclassdef = mpropdef.mclassdef
var mmodule = mclassdef.mmodule
var http_resources = new Array[String]
var http_methods = new Array[String]
for arg in nat.n_args do
var str = arg.as_string
var id = arg.collect_text
if str != null then
# String -> rename resource
http_resources.add str
else if arg isa ATypeExpr and not id.chars.has("[") then
# Class id -> HTTP method
http_methods.add id
else if id == "async" then
mproperty.restful_async = true
else
toolcontext.error(nat.location,
"Syntax Error: `restful` expects String literals or ids as arguments.")
return
end
end
# Test subclass of `RestfulAction`
var sup_class_name = "RestfulAction"
var sup_class = toolcontext.modelbuilder.try_get_mclass_by_name(
nat, mmodule, sup_class_name)
var in_hierarchy = mclassdef.in_hierarchy
if in_hierarchy == null or sup_class == null then return
var sup_classes = in_hierarchy.greaters
if not sup_classes.has(sup_class.intro) then
toolcontext.error(nat.location,
"Syntax Error: `restful` is only valid within subclasses of `{sup_class_name}`")
return
end
# Register the property
mclassdef.restful_methods.add mproperty
restful_classes.add mclassdef
if http_resources.not_empty then mproperty.restful_resources = http_resources
mproperty.restful_verbs = http_methods
end
end
src/nitrestful.nit:22,1--86,3