From 06515268c8ad2da8d1aef9906c5380705e670612 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 19 Jun 2017 13:03:04 -0400 Subject: [PATCH] frontend: introduce `parse_annotations` phase Signed-off-by: Alexandre Terrasa --- src/frontend/frontend.nit | 1 + src/frontend/parse_annotations.nit | 117 ++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 src/frontend/parse_annotations.nit diff --git a/src/frontend/frontend.nit b/src/frontend/frontend.nit index 19490b3..042cfc1 100644 --- a/src/frontend/frontend.nit +++ b/src/frontend/frontend.nit @@ -24,6 +24,7 @@ import div_by_zero import serialization_phase import deriving import check_annotation +import parse_annotations import glsl_validation import parallelization_phase import i18n_phase diff --git a/src/frontend/parse_annotations.nit b/src/frontend/parse_annotations.nit new file mode 100644 index 0000000..b2a9687 --- /dev/null +++ b/src/frontend/parse_annotations.nit @@ -0,0 +1,117 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Simple annotation parsing +# +# This phase collects all the annotations found on AModuleDecl, AClassdef and +# APropdef and stores them in the related MEntity. +# +# Once the phase has been applied, annotations names are available in +# `AnnotatedMEntity::annotations`. +# One can then ask to the mentity if it holds the annnotation in its source code. +# +# Example: +# ~~~nitish +# fun is_annotated_with_foo(mentity: AnnotatedMEntity): Bool do +# return mentity.has_annotation("foo") +# end +# ~~~ +# +# Note that only the names of the annotations are stored, if one wants to access +# the annotations arguments, the traditional annotations framework is recommanded. +module parse_annotations + +import phase +import modelize_class +import modelize_property +private import annotation + +redef class ToolContext + # Parse the annotations on modules, classdefs and propdefs + var parse_annotations_phase: Phase = new ParseAnnotationsPhase(self, + [modelize_class_phase, modelize_property_phase]) +end + +# Parse annotations from modules, classdefs and propdefs +# +# Found annotations names are stored in `AnnotatedMEntity::annotations`. +private class ParseAnnotationsPhase + super Phase + + # Lookup for `nmodule` annotations + redef fun process_nmodule(nmodule) do + var mmodule = nmodule.mmodule + if mmodule == null then return + + var nmoduledecl = nmodule.n_moduledecl + if nmoduledecl == null then return + + var nannots = nmoduledecl.n_annotations + if nannots == null then return + + for nannot in nannots.n_items do + mmodule.annotations.add nannot.n_atid.n_id.text + end + end + + # Lookup for `nclassdef` annotations + redef fun process_nclassdef(nclassdef) do + var mclassdef = nclassdef.mclassdef + if mclassdef == null then return + + for npropdef in nclassdef.n_propdefs do + if not npropdef isa AAnnotPropdef then continue + mclassdef.annotations.add npropdef.n_atid.n_id.text + end + end + + # Lookup for `npropdef` annotations + redef fun process_npropdef(npropdef) do + var mpropdef = npropdef.mpropdef + if mpropdef == null then return + + var nannots = npropdef.n_annotations + if nannots == null then return + + for nannot in nannots.n_items do + mpropdef.annotations.add nannot.n_atid.n_id.text + end + end +end + +# A MEntity that can hold annotations from it's source code +# +# We do not introduce these services in MEntity to avoid semantics confusion. +# At this stage, the annotation concept is only relevant to source code related +# mentities such as MModules, MClassDefs and MPropdefs. +abstract class AnnotatedMEntity + + # Names of the annotations found on `self` declaration + var annotations: Set[String] = new HashSet[String] + + # Does `self` contains `annotation` in its declaration? + fun has_annotation(annotation: String): Bool do return annotations.has(annotation) +end + +redef class MModule + super AnnotatedMEntity +end + +redef class MClassDef + super AnnotatedMEntity +end + +redef class MPropDef + super AnnotatedMEntity +end -- 1.7.9.5