X-Git-Url: http://nitlanguage.org diff --git a/src/doc/vim_autocomplete.nit b/src/doc/vim_autocomplete.nit index edbc126..1e8a9fb 100644 --- a/src/doc/vim_autocomplete.nit +++ b/src/doc/vim_autocomplete.nit @@ -31,7 +31,7 @@ module vim_autocomplete import modelbuilder import phase import modelize::modelize_class -import model_utils +import model::model_collect redef class ToolContext # Phase generating the files for the Vim plugin @@ -45,6 +45,7 @@ redef class ToolContext do super option_context.add_option opt_vim_autocomplete + opt_vim_autocomplete.hidden = true end end @@ -52,7 +53,7 @@ redef class MEntity private fun field_separator: String do return "#====#" private fun line_separator: String do return "#nnnn#" - private fun write_doc(mainmodule: MModule, stream: Writer) + private fun write_doc(model: Model, mainmodule: MModule, stream: Writer) do # 1. Short name for autocompletion stream.write complete_name @@ -78,7 +79,10 @@ redef class MEntity for i in 2.times do stream.write line_separator stream.write mdoc.content.join(line_separator) end - write_extra_doc(mainmodule, stream) + + write_location(mainmodule, stream) + + write_extra_doc(model, mainmodule, stream) stream.write "\n" end @@ -92,7 +96,16 @@ redef class MEntity private fun complete_mdoc: nullable MDoc do return mdoc # Extra auto documentation to append to the `stream` - private fun write_extra_doc(mainmodule: MModule, stream: Writer) do end + private fun write_extra_doc(model: Model, mainmodule: MModule, stream: Writer) do end + + # Location (file and line when available) of related declarations + private fun write_location(mainmodule: MModule, stream: Writer) + do + for i in 2.times do stream.write line_separator + stream.write "## Location" + stream.write line_separator + stream.write "* {location}" + end end redef class MMethodDef @@ -103,6 +116,26 @@ redef class MMethodDef stream.write msignature.to_s end end + + redef fun write_location(mainmodule, stream) + do + for i in 2.times do stream.write line_separator + stream.write "## Location of introduction and refinements" + + # Group locations in the same file + var file_to_location = new MultiHashMap[nullable SourceFile, Location] + for c in mproperty.mpropdefs do + file_to_location[c.location.file].add c.location + end + + # Write one file per location + for file, locations in file_to_location do + var l = locations.first + stream.write line_separator + stream.write "* {l}" + if locations.length > 1 then stream.write " ({locations.length-1} more)" + end + end end redef class MAttributeDef @@ -153,7 +186,7 @@ redef class MClassDef end redef class MClassType - redef fun write_extra_doc(mainmodule, stream) + redef fun write_extra_doc(model, mainmodule, stream) do # Super classes stream.write line_separator*2 @@ -197,37 +230,26 @@ redef class MClassType stream.write line_separator*2 stream.write "## Properties" stream.write line_separator - var props = mclass.all_mproperties(mainmodule, protected_visibility).to_a + var props = mclass.collect_accessible_mproperties(mainmodule).to_a alpha_comparator.sort props for prop in props do if mclass.name == "Object" or prop.intro.mclassdef.mclass.name != "Object" then - - if prop.visibility == public_visibility then - stream.write "+ " - else stream.write "~ " # protected_visibility - - if prop isa MMethod then - if prop.is_init and prop.name != "init" then stream.write "init " - if prop.is_new and prop.name != "new" then stream.write "new " - end - - stream.write prop.name - - if prop isa MMethod then - stream.write prop.intro.msignature.to_s - end - - var mdoc = prop.intro.mdoc - if mdoc != null then - stream.write " # " - stream.write mdoc.content.first - end - stream.write line_separator + prop.write_synopsis(mainmodule, stream) end end end redef fun complete_mdoc do return mclass.intro.mdoc + + redef fun write_location(mainmodule, stream) + do + for i in 2.times do stream.write line_separator + stream.write "## Location of introduction and refinements" + for c in mclass.mclassdefs do + stream.write line_separator + stream.write "* {c.location}" + end + end end private class AutocompletePhase @@ -250,7 +272,7 @@ private class AutocompletePhase # Got all known modules var model = mainmodule.model for mmodule in model.mmodules do - mmodule.write_doc(mainmodule, modules_stream) + mmodule.write_doc(model, mainmodule, modules_stream) end # TODO list other modules from the Nit lib @@ -263,18 +285,18 @@ private class AutocompletePhase # Can it be instantiated? if mclass.kind != interface_kind and mclass.kind != abstract_kind then - for prop in mclass.all_mproperties(mainmodule, public_visibility) do + for prop in mclass.collect_accessible_mproperties(mainmodule) do if prop isa MMethod and prop.is_init then mclass_intro.target_constructor = prop.intro - mclass_intro.write_doc(mainmodule, constructors_stream) + mclass_intro.write_doc(model, mainmodule, constructors_stream) end end mclass_intro.target_constructor = null end # Always add to types and classes - mclass.mclass_type.write_doc(mainmodule, classes_stream) - mclass.mclass_type.write_doc(mainmodule, types_stream) + mclass.mclass_type.write_doc(model, mainmodule, classes_stream) + mclass.mclass_type.write_doc(model, mainmodule, types_stream) end # Get all known properties @@ -284,7 +306,7 @@ private class AutocompletePhase # Is it a virtual type? if mproperty isa MVirtualTypeProp then - mproperty.intro.write_doc(mainmodule, types_stream) + mproperty.intro.write_doc(model, mainmodule, types_stream) continue end @@ -292,7 +314,7 @@ private class AutocompletePhase var first_letter = mproperty.name.chars.first if first_letter == '@' or first_letter == '_' then continue - mproperty.intro.write_doc(mainmodule, properties_stream) + mproperty.intro.write_doc(model, mainmodule, properties_stream) end # Close streams @@ -302,8 +324,80 @@ private class AutocompletePhase stream.close var error = stream.last_error if error != null then - toolcontext.error(null, "Failed to write Vim autocomplete file: {error}") + toolcontext.error(null, "Error: failed to write Vim autocomplete file: {error}.") end end end end + +redef class MModule + redef fun write_extra_doc(model, mainmodule, stream) + do + # Introduced classes + var class_intros = collect_intro_mclasses.to_a + if class_intros.not_empty then + alpha_comparator.sort class_intros + stream.write line_separator*2 + stream.write "## Introduced classes" + + for c in class_intros do + stream.write line_separator + stream.write "* {c.name}" + var doc = c.intro.mdoc + if doc != null then stream.write ": {doc.content.first}" + end + end + + # Introduced properties + var prop_intros = new Array[MPropDef] + for c in mclassdefs do + prop_intros.add_all c.collect_intro_mpropdefs + end + + if prop_intros.not_empty then + alpha_comparator.sort prop_intros + stream.write line_separator*2 + stream.write "## Introduced properties" + stream.write line_separator + + for p in prop_intros do + p.mproperty.write_synopsis(mainmodule, stream) + end + end + end +end + +redef class MProperty + private fun write_synopsis(mainmodule: MModule, stream: Writer) + do + if visibility == public_visibility then + stream.write "+ " + else stream.write "~ " # protected_visibility + + if self isa MMethod then + if is_new and name != "new" then + stream.write "new " + else if is_init and name != "init" then + stream.write "init " + end + end + + stream.write name + + if self isa MMethod then + var intro = intro + assert intro isa MMethodDef + var msignature = intro.msignature + if msignature != null then + stream.write msignature.to_s + end + end + + var mdoc = intro.mdoc + if mdoc != null then + stream.write " # " + stream.write mdoc.content.first + end + stream.write line_separator + end +end