neo_doxygen: Import parameters.
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Sun, 2 Nov 2014 21:32:55 +0000 (16:32 -0500)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Tue, 4 Nov 2014 17:16:09 +0000 (12:16 -0500)
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

contrib/neo_doxygen/src/doxml/compounddef.nit
contrib/neo_doxygen/src/doxml/entitydef.nit
contrib/neo_doxygen/src/doxml/language_specific.nit
contrib/neo_doxygen/src/doxml/memberdef.nit
contrib/neo_doxygen/src/model/linked_text.nit

index 21d8d3c..10f289f 100644 (file)
@@ -113,9 +113,7 @@ class CompoundDefListener
        end
 
        redef fun end_dox_element(local_name: String) do
-               if local_name == "compounddef" then
-                       compound.put_in_graph
-               else if local_name == "compoundname" then
+               if local_name == "compoundname" then
                        compound.full_name = text.to_s
                else if local_name == "innerclass" then
                        compound.declare_class(refid, text.to_s)
index fd9ae68..9bad28a 100644 (file)
@@ -75,3 +75,48 @@ abstract class EntityDefListener
                return location
        end
 end
+
+# Processes the content of a `<param>` element.
+abstract class ParamListener[T: Parameter]
+       super EntityDefListener
+
+       # The current parameter.
+       var parameter: T is noinit
+
+       private var type_listener: TypeListener is noinit
+
+       init do
+               super
+               type_listener = new TypeListener(reader, self)
+       end
+
+       redef fun entity do return parameter
+
+       redef fun listen_until(uri, local_name) do
+               super
+               parameter = create_parameter
+       end
+
+       # Create a new parameter.
+       protected fun create_parameter: T is abstract
+
+       redef fun start_dox_element(local_name: String, atts: Attributes) do
+               if "declname" == local_name then
+                       text.listen_until(dox_uri, local_name)
+               else if "type" == local_name then
+                       type_listener.listen_until(dox_uri, local_name)
+               else
+                       super
+               end
+       end
+
+       redef fun end_dox_element(local_name: String) do
+               if "declname" == local_name then
+                       parameter.name = text.to_s
+               else if "type" == local_name then
+                       source_language.apply_parameter_type(parameter, type_listener.linked_text)
+               else
+                       super
+               end
+       end
+end
index b5afa8e..b4faea9 100644 (file)
@@ -29,6 +29,15 @@ abstract class SourceLanguage
                end
        end
 
+       # Apply the information deduced from `type_text` to `parameter`.
+       #
+       # `type_text` is the content of the `<type>` element.
+       fun apply_parameter_type(parameter: Parameter, type_text: RawType) do
+               if type_text["text"] != null then
+                       parameter.static_type = type_text
+               end
+       end
+
        # Extract the specified keyword at the beginning of the specified text.
        #
        # If the keyword is at the beginning of the specified text, return `true`
@@ -85,6 +94,57 @@ abstract class SourceLanguage
                end
                return found
        end
+
+       # Extract the specified suffix in the specified text.
+       #
+       # If the suffix is at the end of the specified text, return `true`
+       # and remove the suffix. Else, return false.
+       #
+       # Used to extract stuff like `...` that Doxygen puts in the type.
+       #
+       #     class DummySource
+       #       super JavaSource
+       #     #
+       #       fun test(text: LinkedText, s: String): Bool do
+       #               return extract_suffix(text, s)
+       #       end
+       #     end
+       #     #
+       #     var text = new RawType(new ProjectGraph(""))
+       #     var dummy = new DummySource
+       #     var res: Bool
+       #     #
+       #     text.add_part("Object...+++", "")
+       #     res = dummy.test(text, "...")
+       #     assert not res
+       #     res = dummy.test(text, "+++")
+       #     assert res
+       #     assert "Object..." == text["text"].as(JsonArray).first
+       #     res = dummy.test(text, "...")
+       #     assert res
+       #     assert "Object" == text["text"].as(JsonArray).first
+       protected fun extract_suffix(text: LinkedText, suffix: String): Bool do
+               var text_array = text["text"]
+               if text_array == null then return false
+               assert text_array isa JsonArray
+               if text_array.is_empty then return false
+
+               var content = text_array.last.as(String).r_trim
+               var link = text.links.first
+               var found = false
+
+               if link == null and content.has_suffix(suffix) then
+                       content = content.substring(0, content.length - suffix.length).r_trim
+                       if "" == content then
+                               text.pop_part
+                       else
+                               text.set_part(0, content, "")
+                       end
+                       return true
+               else
+                       return false
+               end
+       end
 end
 
 # Importation logics for Java.
@@ -101,4 +161,13 @@ class JavaSource
                # TODO Avoid using `RawType` when possible. Only use `RawType` as a fallback.
                super
        end
+
+       redef fun apply_parameter_type(parmeter, type_text) do
+               # We assume that Doxygen do not put annotations in the type (it seems to
+               # be the case).
+               # TODO final
+               # TODO Avoid using `RawType` when possible. Only use `RawType` as a fallback.
+               parmeter.is_vararg = extract_suffix(type_text, "...")
+               super
+       end
 end
index 3a5100b..5249404 100644 (file)
@@ -23,11 +23,14 @@ class MemberDefListener
 
        # The current member.
        var member: Member is writable, noinit
+
        private var type_listener: TypeListener is noinit
+       private var param_listener: MemberParamListener is noinit
 
        init do
                super
                type_listener = new TypeListener(reader, self)
+               param_listener = new MemberParamListener(reader, self)
        end
 
        redef fun entity do return member
@@ -39,20 +42,29 @@ class MemberDefListener
                        member.reimplement(get_required(atts, "refid"))
                else if "type" == local_name then
                        type_listener.listen_until(dox_uri, local_name)
+               else if "param" == local_name then
+                       param_listener.listen_until(dox_uri, local_name)
                else
                        super
                end
        end
 
        redef fun end_dox_element(local_name: String) do
-               if "memberdef" == local_name then
-                       member.put_in_graph
-               else if "name" == local_name then
+               if "name" == local_name then
                        member.name = text.to_s
                else if "type" == local_name then
                        source_language.apply_member_type(member, type_listener.linked_text)
+               else if "param" == local_name then
+                       member.add_parameter(param_listener.parameter)
                else
                        super
                end
        end
 end
+
+# Processes the content of a `<param>` element in a `<memberdef>` element.
+class MemberParamListener
+       super ParamListener[MemberParameter]
+
+       redef fun create_parameter do return new MemberParameter(graph)
+end
index e35adde..bfdf6a5 100644 (file)
@@ -146,7 +146,19 @@ abstract class Link
        # * `refid` : `model_id` of the linked entity.
        var refid: String
 
+       init do
+               super
+               self["rank"] = -1
+       end
+
        redef fun put_edges do
                graph.add_edge(self, "TARGET", graph.by_id[refid])
        end
+
+       # Specify the rank (index) of the parameter in the signature.
+       #
+       # Called by `LinkedText.put_edges`.
+       private fun rank=(rank: Int) do
+               self["rank"] = rank
+       end
 end