Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / frontend / parse_annotations.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Simple annotation parsing
16 #
17 # This phase collects all the annotations found on AModuleDecl, AClassdef and
18 # APropdef and stores them in the related MEntity.
19 #
20 # Once the phase has been applied, annotations names are available in
21 # `AnnotatedMEntity::annotations`.
22 # One can then ask to the mentity if it holds the annnotation in its source code.
23 #
24 # Example:
25 # ~~~nitish
26 # fun is_annotated_with_foo(mentity: AnnotatedMEntity): Bool do
27 # return mentity.has_annotation("foo")
28 # end
29 # ~~~
30 #
31 # Note that only the names of the annotations are stored, if one wants to access
32 # the annotations arguments, the traditional annotations framework is recommanded.
33 module parse_annotations
34
35 import phase
36 import modelize_class
37 import modelize_property
38 private import annotation
39
40 redef class ToolContext
41 # Parse the annotations on modules, classdefs and propdefs
42 var parse_annotations_phase: Phase = new ParseAnnotationsPhase(self,
43 [modelize_class_phase, modelize_property_phase])
44 end
45
46 # Parse annotations from modules, classdefs and propdefs
47 #
48 # Found annotations names are stored in `AnnotatedMEntity::annotations`.
49 private class ParseAnnotationsPhase
50 super Phase
51
52 # Lookup for `nmodule` annotations
53 redef fun process_nmodule(nmodule) do
54 var mmodule = nmodule.mmodule
55 if mmodule == null then return
56
57 var nmoduledecl = nmodule.n_moduledecl
58 if nmoduledecl == null then return
59
60 var nannots = nmoduledecl.n_annotations
61 if nannots == null then return
62
63 for nannot in nannots.n_items do
64 mmodule.annotations.add nannot.n_atid.n_id.text
65 end
66 end
67
68 # Lookup for `nclassdef` annotations
69 redef fun process_nclassdef(nclassdef) do
70 var mclassdef = nclassdef.mclassdef
71 if mclassdef == null then return
72
73 for npropdef in nclassdef.n_propdefs do
74 if not npropdef isa AAnnotPropdef then continue
75 mclassdef.annotations.add npropdef.n_atid.n_id.text
76 end
77 end
78
79 # Lookup for `npropdef` annotations
80 redef fun process_npropdef(npropdef) do
81 var mpropdef = npropdef.mpropdef
82 if mpropdef == null then return
83
84 var nannots = npropdef.n_annotations
85 if nannots == null then return
86
87 for nannot in nannots.n_items do
88 mpropdef.annotations.add nannot.n_atid.n_id.text
89 end
90 end
91 end
92
93 # A MEntity that can hold annotations from it's source code
94 #
95 # We do not introduce these services in MEntity to avoid semantics confusion.
96 # At this stage, the annotation concept is only relevant to source code related
97 # mentities such as MModules, MClassDefs and MPropdefs.
98 abstract class AnnotatedMEntity
99
100 # Names of the annotations found on `self` declaration
101 var annotations: Set[String] = new HashSet[String]
102
103 # Does `self` contains `annotation` in its declaration?
104 fun has_annotation(annotation: String): Bool do return annotations.has(annotation)
105 end
106
107 redef class MModule
108 super AnnotatedMEntity
109
110 redef var is_test is lazy do return has_annotation("test")
111 end
112
113 redef class MClassDef
114 super AnnotatedMEntity
115
116 redef var is_test is lazy do return has_annotation("test")
117 end
118
119 redef class MPropDef
120 super AnnotatedMEntity
121
122 redef var is_test is lazy do return has_annotation("test")
123
124 redef var is_before is lazy do return has_annotation("before")
125
126 redef var is_before_all is lazy do return has_annotation("before_all")
127
128 redef var is_after is lazy do return has_annotation("after")
129
130 redef var is_after_all is lazy do return has_annotation("after_all")
131 end