# Management and utilities on annotations
module annotation
-import parser
import modelbuilder
import literal
import model::mmodule_data
end
return res.first
end
-
- # Return all its annotations of a given name in the order of their declaration
- # Retun an empty array if no such an annotation.
- fun get_annotations(name: String): Array[AAnnotation]
- do
- var res = new Array[AAnnotation]
- var nas = n_annotations
- if nas == null then return res
- for na in nas.n_items do
- if na.name != name then continue
- res.add(na)
- end
- return res
- end
end
redef class AAnnotation
- # The name of the annotation
- fun name: String
- do
- return n_atid.n_id.text
- end
-
# Get the single argument of `self` as a `String`.
# Raise error and return null on any inconsistency.
fun arg_as_string(modelbuilder: ModelBuilder): nullable String
end
end
-redef class AAtArg
- # Get `self` as a `String`.
- # Return null if not a string.
- fun as_string: nullable String
- do
- if not self isa AExprAtArg then return null
- var nexpr = n_expr
- if not nexpr isa AStringFormExpr then return null
- return nexpr.value.as(not null)
- end
-
- # Get `self` as an `Int`.
- # Return null if not an integer.
- fun as_int: nullable Int
- do
- if not self isa AExprAtArg then return null
- var nexpr = n_expr
- if not nexpr isa AIntExpr then return null
- return nexpr.value.as(not null)
- end
-
- # Get `self` as a single identifier.
- # Return null if not a single identifier.
- fun as_id: nullable String
- do
- if not self isa AExprAtArg then return null
- var nexpr = n_expr
- if not nexpr isa ACallExpr then return null
- if not nexpr.n_expr isa AImplicitSelfExpr then return null
- if not nexpr.n_args.n_exprs.is_empty then return null
- return nexpr.n_id.text
- end
-end
-
redef class ModelBuilder
# Collect all annotations by `name` assocated to `mmodule` and its imported modules.
# Note that visibility is not considered.
do
var annotations = new Array[AAnnotation]
for mmod in mmodule.in_importation.greaters do
- if not mmodule2nmodule.keys.has(mmod) then continue
- var amod = mmodule2nmodule[mmod]
+ var amod = mmodule2node(mmod)
+ if amod == null then continue
var module_decl = amod.n_moduledecl
if module_decl == null then continue
var aas = module_decl.get_annotations(name)
# Obviously, if there is no ast associated to `mmodule`, then nothing is returned.
fun get_mmodule_annotation(name: String, mmodule: MModule): nullable AAnnotation
do
- if not mmodule2nmodule.keys.has(mmodule) then return null
- var amod = mmodule2nmodule[mmodule]
+ var amod = mmodule2node(mmodule)
+ if amod == null then return null
var module_decl = amod.n_moduledecl
if module_decl == null then return null
var res = module_decl.get_single_annotation(name, self)