+++ /dev/null
-# 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.
-
-# Console templates for Nit model MEntities.
-#
-# This module introduces console rendering services in model entities.
-module console_model
-
-import console
-import doc_base
-import ordered_tree
-
-redef class MDoc
- # Returns the full comment formatted for the console.
- fun cs_comment: String do
- var res = new FlatBuffer
- for line in content do
- res.append " {line}\n"
- end
- return res.write_to_string
- end
-
- # Returns the synopsys formatted for the console.
- fun cs_short_comment: String do return content.first
-end
-
-redef class MEntity
-
- # Returns the mentity name with short signature.
- #
- # * MPackage: `foo`
- # * MGroup: `foo`
- # * MModule: `foo`
- # * MClass: `Foo[E]`
- # * MClassDef: `Foo[E]`
- # * MProperty: `foo(e)`
- # * MPropdef: `foo(e)`
- var cs_name: String is lazy do return name
-
- # Returns the list of keyword used in `self` declaration.
- fun cs_modifiers: Array[String] is abstract
-
- # Returns the complete MEntity declaration (modifiers + name + signature).
- #
- # * MPackage: `package foo`
- # * MGroup: `group foo`
- # * MModule: `module foo`
- # * MClass: `private abstract class Foo[E: Object]`
- # * MClassDef: `redef class Foo[E]`
- # * MProperty: `private fun foo(e: Object): Int`
- # * MPropdef: `redef fun foo(e)`
- var cs_declaration: String is lazy do
- var tpl = new FlatBuffer
- tpl.append cs_modifiers.join(" ")
- tpl.append " "
- tpl.append cs_name
- return tpl.write_to_string
- end
-
- # Returns `self` namespace formatted for console.
- #
- # * MPackage: `mpackage`
- # * MGroup: `mpackage(::group)`
- # * MModule: `mgroup::mmodule`
- # * MClass: `mpackage::mclass`
- # * MClassDef: `mmodule::mclassdef`
- # * MProperty: `mclass::mprop`
- # * MPropdef: `mclassdef:mpropdef`
- fun cs_namespace: String is abstract
-
- # Returns the comment of this MEntity formatted for console.
- var cs_comment: nullable String is lazy do
- var mdoc = mdoc_or_fallback
- if mdoc == null then return null
- # FIXME add markdown for console
- return mdoc.cs_comment
- end
-
- # Returns the comment of this MEntity formatted for console.
- var cs_short_comment: nullable String is lazy do
- var mdoc = mdoc_or_fallback
- if mdoc == null then return null
- return mdoc.cs_short_comment
- end
-
- # Returns `self` as a list element that can be displayed in console.
- #
- # Displays `cs_icon`, `cs_name`, `cs_short_comment, `cs_namespace`,
- # `cs_declaration` and `cs_location`.
- fun cs_list_item: String do
- var tpl = new FlatBuffer
- tpl.append " {cs_visibility_color(cs_icon).bold} {cs_name.blue.bold}"
- var comment = cs_short_comment
- if comment != null then
- tpl.append " # {comment}".green
- end
- tpl.append "\n "
- tpl.append cs_namespace.gray.bold
- tpl.append "\n "
- tpl.append cs_declaration
- tpl.append "\n "
- tpl.append cs_location.gray
- return tpl.write_to_string
- end
-
- # Returns `self` as a short list element that can be displayed in console.
- # Displays `cs_icon`, `cs_name`, and `cs_short_comment.
- fun cs_short_list_item: String do
- var tpl = new FlatBuffer
- tpl.append " {cs_visibility_color(cs_icon).bold} {cs_name.blue.bold}"
- var comment = cs_short_comment
- if comment != null then
- tpl.append " # {comment}".green
- end
- return tpl.write_to_string
- end
-
- # ASCII icon to be displayed in front of the list item.
- fun cs_icon: String do return "*"
-
- # Source code location of this MEntity formatted for console.
- fun cs_location: String is abstract
-
- # Sets text color depending on visibility.
- #
- # See module `console`.
- fun cs_visibility_color(string: String): String do return string.green
-
- # Source code associated to this MEntity.
- #
- # Uses `cs_location` to locate the source code.
- fun cs_source_code: String do
- # FIXME up location to mentity
- var loc = new Location.from_string(cs_location)
- var fr = new FileReader.open(loc.file.filename)
- var content = new FlatBuffer
- var i = 0
- while not fr.eof do
- i += 1
- var line = fr.read_line
- if i < loc.line_start or i > loc.line_end then continue
- # FIXME add nitlight for console
- content.append "{line}\n"
- end
- fr.close
- return content.write_to_string
- end
-end
-
-redef class MPackage
- redef var cs_modifiers = ["package"]
- redef fun cs_namespace do return cs_name
- redef fun cs_icon do return "P"
- redef fun cs_location do return root.mmodules.first.location.to_s
-end
-
-redef class MGroup
- redef var cs_modifiers = ["group"]
- redef fun cs_icon do return "G"
-
- # Depends if `self` is root or not.
- #
- # * If root `mpackage`.
- # * Else `mpackage::self`.
- redef fun cs_namespace do
- var tpl = new FlatBuffer
- tpl.append mpackage.cs_namespace
- if mpackage.root != self then
- tpl.append "::"
- tpl.append cs_name
- end
- return tpl.write_to_string
- end
-
- redef fun cs_location do return mmodules.first.location.to_s
-end
-
-redef class MModule
- redef var cs_modifiers = ["module"]
- redef fun cs_icon do return "M"
-
- # Depends if `self` belongs to a MGroup.
- #
- # * If mgroup `mgroup::self`.
- # * Else `self`.
- redef fun cs_namespace do
- var tpl = new FlatBuffer
- if mgroup != null then
- tpl.append mgroup.cs_namespace
- tpl.append "::"
- end
- tpl.append cs_name
- return tpl.write_to_string
- end
-
- redef fun cs_location do return location.to_s
-end
-
-redef class MClass
- redef fun cs_icon do return intro.cs_icon
-
- # Format: `Foo[E]`
- redef var cs_name is lazy do
- var tpl = new FlatBuffer
- tpl.append name
- if arity > 0 then
- tpl.append "["
- var parameter_names = new Array[String]
- for p in mparameters do
- parameter_names.add(p.cs_name)
- end
- tpl.append parameter_names.join(", ")
- tpl.append "]"
- end
- return tpl.write_to_string
- end
-
- redef fun cs_modifiers do return intro.cs_modifiers
- redef fun cs_declaration do return intro.cs_declaration
-
- # Returns `mpackage::self`.
- redef fun cs_namespace do
- var tpl = new FlatBuffer
- tpl.append intro_mmodule.mgroup.mpackage.cs_namespace
- tpl.append "::"
- tpl.append cs_name
- return tpl.write_to_string
- end
-
- # Returns `intro.cs_short_signature`.
- fun cs_short_signature: String do return intro.cs_short_signature
-
- # Returns `intro.cs_signature`.
- fun cs_signature: String do return intro.cs_signature
-
- redef fun cs_visibility_color(string) do
- if visibility == private_visibility then
- return string.red
- else if visibility == protected_visibility then
- return string.yellow
- end
- return string.green
- end
-
- redef fun cs_location do return intro.location.to_s
-end
-
-redef class MClassDef
- redef fun cs_icon do return "C"
-
- # Depends if `self` is an intro or not.
- #
- # * If intro contains the visibility and kind.
- # * If redef contains the `redef` keyword and kind.
- redef fun cs_modifiers do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- if mclass.visibility != public_visibility then
- res.add mclass.visibility.to_s
- end
- end
- res.add mclass.kind.to_s
- return res
- end
-
- # Depends if `self` is an intro or not.
- #
- # For intro: `private abstract class Foo[E: Object]`
- # For redef: `redef class Foo[E]`
- redef fun cs_declaration do
- var tpl = new FlatBuffer
- tpl.append cs_modifiers.join(" ")
- tpl.append " "
- tpl.append cs_name
- if is_intro then
- tpl.append cs_signature
- else
- tpl.append cs_short_signature
- end
- return tpl.write_to_string.write_to_string.write_to_string
- end
-
- # Returns `mmodule::self`
- redef fun cs_namespace do
- var tpl = new FlatBuffer
- tpl.append mmodule.cs_namespace
- tpl.append "::"
- tpl.append mclass.cs_name
- return tpl.write_to_string.write_to_string
- end
-
- # Returns the MClassDef generic signature without static bounds.
- fun cs_short_signature: String do
- var tpl = new FlatBuffer
- var mparameters = mclass.mparameters
- if not mparameters.is_empty then
- tpl.append "["
- for i in [0..mparameters.length[ do
- tpl.append mparameters[i].cs_name
- if i < mparameters.length - 1 then tpl.append ", "
- end
- tpl.append "]"
- end
- return tpl.write_to_string
- end
-
- # Returns the MClassDef generic signature with static bounds.
- fun cs_signature: String do
- var tpl = new FlatBuffer
- var mparameters = mclass.mparameters
- if not mparameters.is_empty then
- tpl.append "["
- for i in [0..mparameters.length[ do
- tpl.append "{mparameters[i].cs_name}: "
- tpl.append bound_mtype.arguments[i].cs_signature
- if i < mparameters.length - 1 then tpl.append ", "
- end
- tpl.append "]"
- end
- return tpl.write_to_string
- end
-
- redef fun cs_location do return location.to_s
-end
-
-redef class MProperty
- redef fun cs_modifiers do return intro.cs_modifiers
- redef fun cs_declaration do return intro.cs_declaration
- redef fun cs_icon do return intro.cs_icon
-
- # Returns `mclass::self`.
- redef fun cs_namespace do
- var tpl = new FlatBuffer
- tpl.append intro_mclassdef.mclass.cs_namespace
- tpl.append "::"
- tpl.append intro.cs_name
- return tpl.write_to_string
- end
-
- # Returns `intro.cs_short_signature`.
- fun cs_short_signature: String do return intro.cs_short_signature
-
- # Returns `intro.cs_signature`.
- fun cs_signature: String do return intro.cs_signature
-
- redef fun cs_visibility_color(string) do
- if visibility == private_visibility then
- return string.red
- else if visibility == protected_visibility then
- return string.yellow
- end
- return string.green
- end
-
- # Returns `intro.cs_location`.
- redef fun cs_location do return intro.location.to_s
-end
-
-redef class MPropDef
- # Depends if `self` is an intro or not.
- #
- # * If intro contains the visibility and kind.
- # * If redef contains the `redef` keyword and kind.
- redef fun cs_modifiers do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- if mproperty.visibility != public_visibility then
- res.add mproperty.visibility.to_s
- end
- end
- return res
- end
-
- # Depends if `self` is an intro or not.
- #
- # For intro: `private fun foo(e: Object): Bar is abstract`
- # For redef: `redef fun foo(e) is cached`
- redef fun cs_declaration do
- var tpl = new FlatBuffer
- tpl.append cs_modifiers.join(" ")
- tpl.append " "
- if is_intro then
- tpl.append cs_name
- tpl.append cs_signature
- else
- tpl.append mproperty.intro.cs_name
- tpl.append cs_short_signature
- end
- return tpl.write_to_string
- end
-
- # Returns `mclassdef::self`
- redef fun cs_namespace do
- var tpl = new FlatBuffer
- tpl.append mclassdef.cs_namespace
- tpl.append "::"
- tpl.append cs_name
- return tpl.write_to_string
- end
-
- redef fun cs_location do return location.to_s
-
- # Returns the MPropdDef signature without static types.
- fun cs_short_signature: String is abstract
-
- # Returns the MPropDef signature with static types.
- fun cs_signature: String is abstract
-end
-
-redef class MAttributeDef
-
- redef fun cs_modifiers do
- var res = super
- res.add "var"
- return res
- end
-
- redef fun cs_short_signature do return ""
-
- redef fun cs_signature do
- var tpl = new FlatBuffer
- if static_mtype != null then
- tpl.append ": "
- tpl.append static_mtype.cs_signature
- end
- return tpl.write_to_string
- end
-
- redef fun cs_icon do return "A"
-end
-
-redef class MMethodDef
-
- redef fun cs_modifiers do
- if mproperty.is_init then
- var res = new Array[String]
- if mproperty.visibility != public_visibility then
- res.add mproperty.visibility.to_s
- end
- return res
- end
- var res = super
- if is_abstract then
- res.add "abstract"
- else if is_intern then
- res.add "intern"
- end
- res.add "fun"
- return res
- end
-
- redef fun cs_declaration do
- if mproperty.is_init then
- var tpl = new FlatBuffer
- if not cs_modifiers.is_empty then
- tpl.append cs_modifiers.join(" ")
- tpl.append " "
- end
- tpl.append cs_name
- tpl.append cs_signature
- return tpl.write_to_string
- end
- return super
- end
-
- redef fun cs_short_signature do
- if mproperty.is_root_init then
- return new_msignature.cs_short_signature
- end
- return msignature.cs_short_signature
- end
-
- redef fun cs_signature do
- if mproperty.is_root_init then
- return new_msignature.cs_signature
- end
- return msignature.cs_signature
- end
-
- redef fun cs_icon do
- if mproperty.is_init then
- return "I"
- end
- return "F"
- end
-end
-
-redef class MVirtualTypeDef
-
- redef fun cs_modifiers do
- var res = super
- res.add "type"
- return res
- end
-
- # Short signature for `MVirtualType` is always empty.
- redef fun cs_short_signature do return ""
-
- redef fun cs_signature do
- var tpl = new FlatBuffer
- if bound == null then return tpl.write_to_string
- tpl.append ": "
- tpl.append bound.cs_signature
- return tpl.write_to_string
- end
- redef fun cs_icon do return "V"
-end
-
-redef class MType
- # Returns the signature of this type whithout bounds.
- fun cs_short_signature: String is abstract
-
- # Returns the signature of this type.
- fun cs_signature: String is abstract
-
- redef fun cs_icon do return "T"
-end
-
-redef class MClassType
- redef fun cs_short_signature do return cs_name
- redef fun cs_signature do return cs_name
-end
-
-redef class MNullableType
-
- redef fun cs_short_signature do
- var tpl = new FlatBuffer
- tpl.append "nullable "
- tpl.append mtype.cs_short_signature
- return tpl.write_to_string
- end
-
- redef fun cs_signature do
- var tpl = new FlatBuffer
- tpl.append "nullable "
- tpl.append mtype.cs_signature
- return tpl.write_to_string
- end
-end
-
-redef class MGenericType
- redef fun cs_short_signature do
- var tpl = new FlatBuffer
- tpl.append name
- tpl.append "["
- for i in [0..arguments.length[ do
- tpl.append arguments[i].cs_short_signature
- if i < arguments.length - 1 then tpl.append ", "
- end
- tpl.append "]"
- return tpl.write_to_string
- end
-
- redef fun cs_signature do
- var tpl = new FlatBuffer
- tpl.append mclass.name
- tpl.append "["
- for i in [0..arguments.length[ do
- tpl.append arguments[i].cs_signature
- if i < arguments.length - 1 then tpl.append ", "
- end
- tpl.append "]"
- return tpl.write_to_string
- end
-end
-
-redef class MParameterType
- redef fun cs_short_signature do return cs_name
- redef fun cs_signature do return cs_name
-end
-
-redef class MVirtualType
- redef fun cs_signature do return cs_name
-end
-
-redef class MSignature
-
- redef fun cs_short_signature do
- var tpl = new FlatBuffer
- if not mparameters.is_empty then
- tpl.append "("
- for i in [0..mparameters.length[ do
- tpl.append mparameters[i].cs_short_signature
- if i < mparameters.length - 1 then tpl.append ", "
- end
- tpl.append ")"
- end
- return tpl.write_to_string
- end
-
- redef fun cs_signature do
- var tpl = new FlatBuffer
- if not mparameters.is_empty then
- tpl.append "("
- for i in [0..mparameters.length[ do
- tpl.append mparameters[i].cs_signature
- if i < mparameters.length - 1 then tpl.append ", "
- end
- tpl.append ")"
- end
- if return_mtype != null then
- tpl.append ": "
- tpl.append return_mtype.cs_signature
- end
- return tpl.write_to_string
- end
-end
-
-redef class MParameter
-
- # Returns `self` name and ellipsys if any.
- fun cs_short_signature: String do
- var tpl = new FlatBuffer
- tpl.append name
- if is_vararg then tpl.append "..."
- return tpl.write_to_string
- end
-
- # Returns `self` name with it's static type and ellipsys if any.
- fun cs_signature: String do
- var tpl = new FlatBuffer
- tpl.append "{name}: "
- tpl.append mtype.cs_signature
- if is_vararg then tpl.append "..."
- return tpl.write_to_string
- end
-end
-
-################################################################################
-# Additions to `model_ext`.
-
-redef class MRawType
- redef fun cs_signature do
- var tpl = new FlatBuffer
-
- for part in parts do
- if part.target != null then
- tpl.append part.target.as(not null).cs_name
- else
- tpl.append part.text
- end
- end
- return tpl.write_to_string
- end
-end
-
-redef class MInnerClass
- redef fun cs_signature do return inner.cs_signature
-end
-
-redef class MInnerClassDef
- redef fun cs_signature do return inner.cs_signature
-end
+++ /dev/null
-# 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.
-
-# Introduces templates that compose the documentation in console rendering.
-module console_templates
-
-import console_model
-import doc_phases::doc_structure
-
-# Renders the page displayable as ASCII.
-redef class DocPage
- super Template
-
- # Renders the footer and content.
- private fun render_content do add root
-
- # Renders the whole page
- redef fun rendering do render_content
-end
-
-redef class DocComposite
- super Template
-
- # Title that can be decorated for console display.
- #
- # Set as `null` if you don't want to display a title.
- var cs_title: nullable String is writable, lazy do return title
-
- # Subtitle that can be decorated for console display.
- #
- # Set as `null` if you don't want to display a subtitle.
- var cs_subtitle: nullable String is noinit, writable
-
- # Renders the element `cs_title` and `cs_subtitle` as any.
- fun render_title do
- if cs_title != null then
- add "{"#" * depth} ".blue.bold
- addn cs_title.blue.bold
- end
- if cs_subtitle != null then
- addn cs_subtitle.gray.bold
- end
- if cs_title != null or cs_subtitle != null then addn ""
- end
-
- # Renders the element body.
- fun render_body do for child in children do add child.write_to_string
-
- redef fun rendering do
- render_title
- render_body
- end
-end
-
-redef class DocRoot
- redef fun rendering do render_body
-end
-
-redef class ConcernSection
- redef var cs_title is lazy do return "in {mentity.cs_namespace}"
- redef var cs_subtitle is lazy do return mentity.cs_declaration
-
- redef fun rendering do
- var mentity = self.mentity
- if mentity isa MGroup and mentity.mpackage.root == mentity then
- render_body
- else
- super
- end
- end
-end
-
-redef class MEntityComposite
- redef var cs_title is lazy do return mentity.cs_name
- redef var cs_subtitle is lazy do return mentity.cs_namespace
-end
-
-redef class IntroArticle
- redef fun render_body do
- addn " {mentity.cs_declaration.bold}"
- addn " {mentity.cs_location.gray.bold}"
- addn ""
- var comment = mentity.cs_comment
- if comment != null then
- add comment
- end
- addn ""
- super
- end
-end
-
-redef class ConcernsArticle
- redef fun render_body do
- var w = new StringWriter
- concerns.write_to(w)
- addn w.to_s
- end
-end
-
-redef class DefinitionArticle
- # If short, displays only synopsyses.
- var is_short = false is writable
-
- redef fun render_body do
- addn " {mentity.cs_visibility_color(mentity.cs_declaration).bold}"
- addn " {mentity.cs_location.gray.bold}"
- addn ""
- var comment
- if is_short then
- comment = mentity.cs_short_comment
- else
- comment = mentity.cs_comment
- end
- if comment != null then
- add comment
- end
- addn ""
- super
- end
-end
-
-redef class MEntitiesListArticle
- redef fun render_body do
- for mentity in mentities do
- addn mentity.cs_short_list_item
- end
- end
-end
+++ /dev/null
-# 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.
-
-# Nitx related components
-#
-# This module is a place holder for `nitx` related services.
-# No `doc_phase` can be found here, only components used by Nitx tool.
-module doc_console
-
-import semantize
-import doc_commands
-import doc_poset
-import doc::console_templates
-import model::model_index
-
-# Nitx handles console I/O.
-#
-# Using `prompt`, the command line can be turned on an interactive tool.
-class Nitx
-
- # ToolContext used to access options.
- var ctx: ToolContext
-
- # DocModel that contains the informations to display.
- var doc: DocModel
-
- # Comparator used to sort MEntities.
- var sorter = new MEntityNameSorter
-
- # Displays the welcome message and start prompt.
- fun start do
- welcome
- prompt
- end
-
- # Displays the welcome message and the list of loaded modules.
- fun welcome do
- print "Welcome in the Nit Index."
- print ""
- print "Loaded modules:"
- var mmodules = doc.mmodules.to_a
- sorter.sort(mmodules)
- for m in mmodules do
- print "\t{m.name}"
- end
- print ""
- help
- end
-
- # Displays the list of available commands.
- fun help do
- print "\nCommands:\n"
- print "\tname\t\t\tlookup module, class and property with the corresponding 'name'"
- print "\tdoc: <name::space>\tdisplay the documentation page of 'namespace'"
- print "\nType lookup:"
- print "\tparam: <Type>\t\tlookup methods using the corresponding 'Type' as parameter"
- print "\treturn: <Type>\t\tlookup methods returning the corresponding 'Type'"
- print "\tnew: <Type>\t\tlookup methods creating new instances of 'Type'"
- print "\tcall: <name>\t\tlookup methods calling 'name'"
- print "\nHierarchy lookup:"
- print "\tparents: <Class>\tlist direct parents of 'Class'"
- print "\tancestors: <Class>\tlist all ancestors of 'Class'"
- print "\tchildren: <Class>\tlist direct children of 'Class'"
- print "\tdescendants: <Class>\tlist all descendants of 'Class'"
- print "\nCode lookup:"
- print "\tcode: <name>\t\tdisplay the source code associated to the 'name' entity"
- print "\n"
- print "\t:h\t\t\tdisplay this help message"
- print "\t:q\t\t\tquit interactive mode"
- print ""
- end
-
- # Prompts the user for a command.
- fun prompt do
- printn ">> "
- do_query(sys.stdin.read_line)
- prompt
- end
-
- # Parser used to process doc commands
- var parser: DocCommandParser is lazy do
- var parser = new DocCommandParser
- parser.allowed_commands = ["doc", "comment", "list", "param", "return",
- "new", "call", "code"]
- return parser
- end
-
- # Processes the query string and performs it.
- fun do_query(str: String) do
- if str == ":q" then
- exit 0
- else if str == ":h" then
- help
- return
- end
- var query = parser.parse(str)
- if query == null then
- query = new CommentCommand(str)
- query.arg = str
- end
- var res = query.perform(self, doc)
- var suggest = null
- if res.is_empty then
- suggest = query.suggest(self, doc)
- end
- var page = query.make_results(self, res, suggest)
- print page.write_to_string
- end
-end
-
-redef class DocCommand
-
- # Looks up the `doc` model and returns possible matches.
- fun perform(nitx: Nitx, doc: DocModel): Array[NitxMatch] is abstract
-
- # Looks up the `doc` model and returns possible suggestions.
- fun suggest(nitx: Nitx, doc: DocModel): nullable Array[MEntity] do
- return find_suggestions(doc, arg)
- end
-
- # Pretty prints the results for the console.
- fun make_results(nitx: Nitx, results: Array[NitxMatch], suggest: nullable Array[MEntity]): DocPage do
- var page = new DocPage("results", "Results")
- page.root.add_child(new QueryResultArticle("results", "Results", self, results, suggest))
- return page
- end
-
- # Lookup mentities based on a `query` string.
- #
- # 1- lookup by first name (returns always one value)
- # 2- lookup by name (can return conflicts)
- fun find_mentities(doc: DocModel, query: String): Array[MEntityMatch] do
- var res = new Array[MEntityMatch]
-
- # First lookup by full_name
- var mentity = doc.mentity_by_full_name(query)
- if mentity != null then
- res.add new MEntityMatch(self, mentity)
- return res
- end
-
- # If no results, lookup by name
- for m in doc.mentities_by_name(query) do
- res.add new MEntityMatch(self, m)
- end
-
- return res
- end
-
- # Suggest some mentities based on a `query` string.
- fun find_suggestions(doc: DocModel, query: String): Array[MEntity] do
- return doc.find(query, 3)
- end
-end
-
-# Something that matches a `DocCommand`.
-abstract class NitxMatch
-
- # Query matched by `self`.
- var query: DocCommand
-
- # Pretty prints `self` for console.
- fun make_list_item: String is abstract
-end
-
-# A match between a `DocCommand` and a `MEntity`.
-class MEntityMatch
- super NitxMatch
-
- # MEntity matched.
- var mentity: MEntity
-
- redef fun make_list_item do return mentity.cs_list_item
-end
-
-redef class CommentCommand
- redef fun perform(nitx, doc) do return find_mentities(doc, arg)
-
- redef fun make_results(nitx, results, suggest) do
- var len = results.length
- if len == 1 then
- var res = results.first.as(MEntityMatch)
- var mentity = res.mentity
- var page = new DocPage("resultats", "Results")
- var article = new DefinitionArticle("results", "Results", mentity)
- article.cs_title = mentity.name
- article.cs_subtitle = mentity.cs_declaration
- page.root.add_child article
- return page
- else
- return super
- end
- end
-end
-
-# A query to search signatures using a specific `MType` as parameter.
-redef class ParamCommand
- redef fun perform(nitx, doc) do
- var res = new Array[NitxMatch]
- var mtype_name = arg
- for mproperty in doc.mproperties do
- if not mproperty isa MMethod then continue
- var msignature = mproperty.intro.msignature
- if msignature != null then
- for mparam in msignature.mparameters do
- if mparam.mtype.name == mtype_name then
- res.add new MEntityMatch(self, mproperty)
- end
- end
- end
- end
- return res
- end
-end
-
-# A query to search signatures using a specific `MType` as return.
-redef class ReturnCommand
- redef fun perform(nitx, doc) do
- var res = new Array[NitxMatch]
- var mtype_name = arg
- for mproperty in doc.mproperties do
- if not mproperty isa MMethod then continue
- var msignature = mproperty.intro.msignature
- if msignature != null then
- var mreturn = msignature.return_mtype
- if mreturn != null and mreturn.name == mtype_name then
- res.add new MEntityMatch(self, mproperty)
- end
- end
- end
- return res
- end
-end
-
-# A query to search methods creating new instances of a specific `MType`.
-redef class NewCommand
- redef fun perform(nitx, doc) do
- var res = new Array[NitxMatch]
- var mtype_name = arg
- for mpropdef in doc.mpropdefs do
- var visitor = new TypeInitVisitor(mtype_name)
- var npropdef = nitx.ctx.modelbuilder.mpropdef2node(mpropdef)
- if npropdef == null then continue
- visitor.enter_visit(npropdef)
- for i in visitor.inits do
- res.add new MEntityMatch(self, mpropdef)
- end
- end
- return res
- end
-end
-
-# A query to search methods calling a specific `MProperty`.
-redef class CallCommand
- redef fun perform(nitx, doc) do
- var res = new Array[NitxMatch]
- var mprop_name = arg
- for mpropdef in doc.mpropdefs do
- var visitor = new MPropertyCallVisitor
- var npropdef = nitx.ctx.modelbuilder.mpropdef2node(mpropdef)
- if npropdef == null then continue
- visitor.enter_visit(npropdef)
- for mprop in visitor.calls do
- if mprop.name != mprop_name then continue
- res.add new MEntityMatch(self, mpropdef)
- end
- end
- return res
- end
-end
-
-# A match between a `DocPage` and a `MEntity`.
-class PageMatch
- super NitxMatch
-
- # `DocPage` matched.
- var page: DocPage
-
- redef fun make_list_item do
- var page = self.page
- if page isa MEntityPage then
- return page.mentity.cs_list_item
- end
- return " * {page.title}"
- end
-end
-
-# Search in class or module hierarchy of a `MEntity`.
-#
-# It actually searches for pages about the mentity and extracts the
-# pre-calculated hierarchies by the `doc_post` phase.
-abstract class HierarchiesQuery
- super DocCommand
-
- redef fun make_results(nitx, results, suggest) do
- var page = new DocPage("hierarchy", "Hierarchy")
- for result in results do
- if not result isa PageMatch then continue
- var rpage = result.page
- if not rpage isa MClassPage then continue
- page.root.add_child build_article(rpage)
- end
- return page
- end
-
- # Build an article containing the hierarchy list depending on subclasses.
- private fun build_article(page: MClassPage): DocArticle is abstract
-end
-
-# List all parents of a `MClass`.
-class AncestorsQuery
- super HierarchiesQuery
-
- redef fun build_article(page) do
- return new MEntitiesListArticle(
- "ancerstors",
- "Ancestors for {page.mentity.name}",
- page.ancestors.to_a)
- end
-end
-
-# List direct parents of a `MClass`.
-class ParentsQuery
- super HierarchiesQuery
-
- redef fun build_article(page) do
- return new MEntitiesListArticle(
- "parents",
- "Parents for {page.mentity.name}",
- page.parents.to_a)
- end
-end
-
-# List direct children of a `MClass`.
-class ChildrenQuery
- super HierarchiesQuery
-
- redef fun build_article(page) do
- return new MEntitiesListArticle(
- "children",
- "Children for {page.mentity.name}",
- page.children.to_a)
- end
-end
-
-# List all descendants of a `MClass`.
-class DescendantsQuery
- super HierarchiesQuery
-
- redef fun build_article(page) do
- return new MEntitiesListArticle(
- "descendants",
- "Descendants for {page.mentity.name}",
- page.children.to_a)
- end
-end
-
-# A query to search source code from a file name.
-redef class CodeCommand
- # FIXME refactor this!
- redef fun perform(nitx, doc) do
- var res = new Array[NitxMatch]
- var name = arg
- # if name is an existing sourcefile, opens it
- if name.file_exists then
- var fr = new FileReader.open(name)
- var content = fr.read_all
- fr.close
- res.add new CodeMatch(self, name, content)
- return res
- end
- # else, lookup the model by name
- for match in find_mentities(doc, name) do
- if match.mentity isa MClass then continue
- if match.mentity isa MProperty then continue
- res.add new CodeMatch(self, match.mentity.cs_location, match.mentity.cs_source_code)
- end
- return res
- end
-
- redef fun make_results(nitx, results, suggest) do
- var page = new DocPage("results", "Code Results")
- for res in results do
- page.add new CodeQueryArticle("results", "Results", self, res.as(CodeMatch))
- end
- return page
- end
-end
-
-# A match between a piece of code and a string.
-class CodeMatch
- super NitxMatch
-
- # Location of the code match.
- var location: String
-
- # Piece of code matched.
- var content: String
-
- redef fun make_list_item do return "* {location}"
-end
-
-## exploration
-
-# Visitor looking for initialized `MType` (new T).
-#
-# See `NewQuery`.
-private class TypeInitVisitor
- super Visitor
-
- # `MType` name to look for.
- var mtype_name: String
-
- var inits = new HashSet[MType]
- redef fun visit(node)
- do
- node.visit_all(self)
- # look for init
- if not node isa ANewExpr then return
- var mtype = node.n_type.mtype
- if mtype != null and mtype.name == mtype_name then inits.add(mtype)
- end
-end
-
-# Visitor looking for calls to a `MProperty` (new T).
-#
-# See `CallQuery`.
-private class MPropertyCallVisitor
- super Visitor
-
- var calls = new HashSet[MProperty]
- redef fun visit(node)
- do
- node.visit_all(self)
- if not node isa ASendExpr then return
- calls.add node.callsite.as(not null).mproperty
- end
-end
-
-# display
-
-# A `DocArticle` that displays query results.
-private class QueryResultArticle
- super DocArticle
-
- # Query linked to the results to display.
- var query: DocCommand
-
- # Results to display.
- var results: Array[NitxMatch]
-
- # Optional suggestion when no matches where found
- var suggest: nullable Array[MEntity] = null is optional
-
- redef fun render_title do
- var len = results.length
- if len == 0 then
- addn "No result found for '{query.string}'..."
- var suggest = self.suggest
- if suggest != null and suggest.not_empty then
- add "\nDid you mean "
- var i = 0
- for s in suggest do
- add "`{s.full_name}`"
- if i == suggest.length - 2 then add ", "
- if i == suggest.length - 1 then add " or "
- i += 1
- end
- add "?"
- end
- else
- add "# {len} result(s) for '{query.string}'".green.bold
- end
- end
-
- redef fun render_body do
- addn ""
- for result in results do
- addn ""
- addn result.make_list_item
- end
- end
-end
-
-# An article that displays a piece of code.
-private class CodeQueryArticle
- super DocArticle
-
- # The query linked to the result to display.
- var query: DocCommand
-
- # The result to display.
- var result: CodeMatch
-
- redef fun render_body do
- addn ""
- addn "in {result.location}".gray.bold
- addn ""
- add result.content
- end
-end
-
-# A Pager is used to display data into a unix `less` container.
-private class Pager
-
- # Content to display.
- var content = new FlatBuffer
-
- # Adds text to the pager.
- fun add(text: String) do
- content.append(escape(text))
- end
-
- fun render do sys.system("echo \"{content}\" | less -r")
-
- fun escape(str: String): String
- do
- var b = new FlatBuffer
- for c in str.chars do
- if c == '\n' then
- b.append("\\n")
- else if c == '\0' then
- b.append("\\0")
- else if c == '"' then
- b.append("\\\"")
- else if c == '\\' then
- b.append("\\\\")
- else if c == '`' then
- b.append("'")
- else if c.code_point < 32 then
- b.append("\\{c.code_point.to_base(8)}")
- else
- b.add(c)
- end
- end
- return b.to_s
- end
-end
--- /dev/null
+# 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.
+
+# Markdown templates for Nit model MEntities.
+#
+# This module introduces Markdown rendering services in model entities.
+# With the `no_color` option set to `false`, the output can be highlighted for console.
+module templates_term
+
+import model_collect
+import console
+
+redef class MDoc
+ # Returns the full comment formatted for the console
+ fun cs_comment(no_color: nullable Bool, indent: nullable Int): String do
+ var res = new FlatBuffer
+ indent = indent or else 0
+ for line in content do
+ res.append "{" " * indent}{line}\n"
+ end
+ if no_color == null or not no_color then
+ return res.write_to_string.green
+ end
+ return res.write_to_string
+ end
+
+ # Returns the synopsys formatted for the console
+ fun cs_short_comment(no_color: nullable Bool): String do
+ if no_color == null or not no_color then
+ return content.first.green
+ end
+ return content.first
+ end
+end
+
+redef class MEntity
+
+ # Text icon to be displayed in front of the entity
+ fun cs_icon(no_color: nullable Bool): String do
+ return public_visibility.cs_icon(no_color)
+ end
+
+ # Source code location of this MEntity formatted for console
+ fun cs_location(no_color: nullable Bool): String do
+ if no_color == null or not no_color then
+ return location.to_s.bold.gray
+ end
+ return location.to_s
+ end
+
+ # Returns `self.full_name` formatted for console
+ fun cs_full_name(no_color: nullable Bool): String do
+ if no_color == null or not no_color then
+ return full_name.bold.blue
+ end
+ return full_name
+ end
+
+ # Returns `self` signature formatted for console.
+ fun cs_signature(no_color: nullable Bool): String do return ""
+
+ # Returns the comment of this MEntity formatted for console.
+ fun cs_comment(no_color: nullable Bool): nullable String do
+ var mdoc = mdoc_or_fallback
+ if mdoc == null then return null
+ # FIXME add markdown for console
+ return mdoc.cs_comment(no_color)
+ end
+
+ # Returns the comment of this MEntity formatted for console.
+ fun cs_short_comment(no_color: nullable Bool): nullable String do
+ var mdoc = mdoc_or_fallback
+ if mdoc == null then return null
+ return mdoc.cs_short_comment(no_color)
+ end
+
+ # Returns the complete MEntity declaration (modifiers + name + signature).
+ #
+ # * MPackage: `package foo`
+ # * MGroup: `group foo`
+ # * MModule: `module foo`
+ # * MClass: `private abstract class Foo[E: Object]`
+ # * MClassDef: `redef class Foo[E]`
+ # * MProperty: `private fun foo(e: Object): Int`
+ # * MPropdef: `redef fun foo(e)`
+ fun cs_declaration(no_color: nullable Bool): String do
+ var tpl = new FlatBuffer
+ tpl.append collect_modifiers.join(" ")
+ tpl.append " "
+ tpl.append name
+ tpl.append cs_signature(no_color)
+ if no_color == null or not no_color then
+ return tpl.write_to_string.bold
+ end
+ return tpl.write_to_string
+ end
+
+ # Returns `self` as a list element that can be displayed in console.
+ #
+ # Displays `cs_icon`, `cs_name`, `cs_short_comment, `cs_namespace`,
+ # `cs_declaration` and `cs_location`.
+ fun cs_list_item(no_color: nullable Bool): String do
+ var tpl = new FlatBuffer
+ tpl.append " "
+ tpl.append cs_icon(no_color)
+ tpl.append " "
+ tpl.append cs_full_name(no_color)
+ var comment = cs_short_comment(no_color)
+ if comment != null then
+ tpl.append "\n "
+ if no_color == null or not no_color then
+ tpl.append "# ".green
+ else
+ tpl.append "# "
+ end
+ tpl.append comment
+ end
+ tpl.append "\n "
+ tpl.append cs_declaration(no_color)
+ tpl.append "\n "
+ tpl.append cs_location(no_color)
+ return tpl.write_to_string
+ end
+
+ # Source code associated to this MEntity.
+ #
+ # Uses `cs_location` to locate the source code.
+ fun cs_source_code: String do
+ var tpl = new Buffer
+ tpl.append "\n~~~\n"
+ tpl.append location.text
+ tpl.append "\n~~~\n"
+ return tpl.write_to_string
+ end
+end
+
+redef class MClass
+ redef fun cs_icon(no_color) do return intro.cs_icon(no_color)
+ redef fun cs_signature(no_color) do return intro.cs_signature(no_color)
+end
+
+redef class MClassDef
+ redef fun cs_icon(no_color) do
+ if is_intro then return visibility.cs_icon(no_color)
+ return visibility.cs_visibility_color("*")
+ end
+
+ # Returns the MClassDef generic signature with static bounds.
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ var mparameters = mclass.mparameters
+ if not mparameters.is_empty then
+ tpl.append "["
+ for i in [0..mparameters.length[ do
+ tpl.append "{mparameters[i].name}: "
+ tpl.append bound_mtype.arguments[i].cs_signature(no_color)
+ if i < mparameters.length - 1 then tpl.append ", "
+ end
+ tpl.append "]"
+ end
+ return tpl.write_to_string
+ end
+end
+
+redef class MProperty
+ redef fun cs_icon(no_color) do return intro.cs_icon(no_color)
+ redef fun cs_signature(no_color) do return intro.cs_signature(no_color)
+end
+
+redef class MPropDef
+ redef fun cs_icon(no_color) do
+ if is_intro then return visibility.cs_icon(no_color)
+ return visibility.cs_visibility_color("*", no_color)
+ end
+end
+
+redef class MAttributeDef
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ var static_mtype = self.static_mtype
+ if static_mtype != null then
+ tpl.append ": "
+ tpl.append static_mtype.cs_signature(no_color)
+ end
+ return tpl.write_to_string
+ end
+end
+
+redef class MMethodDef
+ redef fun cs_signature(no_color) do
+ if mproperty.is_root_init then
+ return new_msignature.as(not null).cs_signature(no_color)
+ end
+ return msignature.as(not null).cs_signature(no_color)
+ end
+end
+
+redef class MVirtualTypeDef
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ var bound = self.bound
+ if bound == null then return tpl.write_to_string
+ tpl.append ": "
+ tpl.append bound.cs_signature(no_color)
+ return tpl.write_to_string
+ end
+end
+
+redef class MClassType
+ redef fun cs_signature(no_color) do return name
+end
+
+redef class MNullableType
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ tpl.append "nullable "
+ tpl.append mtype.cs_signature(no_color)
+ return tpl.write_to_string
+ end
+end
+
+redef class MGenericType
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ tpl.append mclass.name
+ tpl.append "["
+ for i in [0..arguments.length[ do
+ tpl.append arguments[i].cs_signature(no_color)
+ if i < arguments.length - 1 then tpl.append ", "
+ end
+ tpl.append "]"
+ return tpl.write_to_string
+ end
+end
+
+redef class MParameterType
+ redef fun cs_signature(no_color) do return name
+end
+
+redef class MVirtualType
+ redef fun cs_signature(no_color) do return name
+end
+
+redef class MSignature
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ if not mparameters.is_empty then
+ tpl.append "("
+ for i in [0..mparameters.length[ do
+ tpl.append mparameters[i].cs_signature(no_color)
+ if i < mparameters.length - 1 then tpl.append ", "
+ end
+ tpl.append ")"
+ end
+ var return_mtype = self.return_mtype
+ if return_mtype != null then
+ tpl.append ": "
+ tpl.append return_mtype.cs_signature(no_color)
+ end
+ return tpl.write_to_string
+ end
+end
+
+redef class MParameter
+ redef fun cs_signature(no_color) do
+ var tpl = new FlatBuffer
+ tpl.append "{name}: "
+ tpl.append mtype.cs_signature(no_color)
+ if is_vararg then tpl.append "..."
+ return tpl.write_to_string
+ end
+end
+
+redef class MVisibility
+ # Visibility icon
+ fun cs_icon(no_color: nullable Bool): String do
+ var icon
+ if self == private_visibility then
+ icon = cs_visibility_color("-", no_color)
+ else if self == protected_visibility then
+ icon = cs_visibility_color("#", no_color)
+ else
+ icon = cs_visibility_color("+", no_color)
+ end
+ if no_color != null and no_color then return icon
+ return icon.bold
+ end
+
+ # Colorize `string` depending on the visibility
+ fun cs_visibility_color(string: String, no_color: nullable Bool): String do
+ if no_color != null and no_color then return string
+ if self == private_visibility then
+ return string.red
+ else if self == protected_visibility then
+ return string.yellow
+ else
+ return string.green
+ end
+ end
+end
--- /dev/null
+# 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.
+
+module term
+
+import commands::commands_parser
+import templates::templates_term
+
+redef class CommandParser
+
+ fun execute(query: String, no_color: nullable Bool) do
+ var cmd = self.parse(query)
+ var error = self.error
+
+ # If not a command, try a comment query
+ if cmd == null and error isa CmdParserError then
+ error = null
+ cmd = new CmdComment(view, mentity_name = query)
+ var opts = new HashMap[String, String]
+ var status = cmd.parser_init(query, opts)
+ if not status isa CmdSuccess then error = status
+ end
+
+ if error isa CmdError or error isa CmdWarning then
+ error.print_message(no_color)
+ print ""
+ end
+ cmd.as(not null).execute(no_color)
+ end
+end
+
+redef class DocCommand
+ fun execute(no_color: nullable Bool) is abstract
+end
+
+redef class CmdMessage
+ fun print_message(no_color: nullable Bool) do print to_s
+end
+
+redef class CmdError
+ redef fun print_message(no_color) do
+ var res = "Error: {to_s}"
+ if no_color == null or not no_color then res = res.bold.red
+ print res
+ end
+end
+
+redef class CmdWarning
+ redef fun print_message(no_color) do
+ var res = "Warning: {to_s}"
+ if no_color == null or not no_color then res = res.bold.yellow
+ print res
+ end
+end
+
+# Model queries
+
+redef class ErrorMEntityNotFound
+ redef fun print_message(no_color) do
+ if no_color == null or not no_color then
+ print "No result found for `{mentity_name.blue}`...".bold
+ else
+ print "No result found for `{mentity_name}`..."
+ end
+ print ""
+ if suggestions.not_empty then
+ print "Did you mean?"
+ print ""
+ for s in suggestions do
+ print s.cs_list_item(no_color)
+ print ""
+ end
+ end
+ end
+end
+
+redef class ErrorMEntityConflict
+ redef fun print_message(no_color) do
+ if no_color == null or not no_color then
+ print "Multiple results found for `{mentity_name.blue}`...".bold
+ else
+ print "Multiple results found for `{mentity_name}`..."
+ end
+ print ""
+ if conflicts.not_empty then
+ print "Did you mean?"
+ print ""
+ for s in conflicts do
+ print s.cs_list_item(no_color)
+ print ""
+ end
+ end
+ end
+end
+
+redef class CmdList
+ fun print_list(list_title: nullable String, list_items: nullable Array[MEntity], no_color: nullable Bool) do
+ if list_title != null then
+ if no_color == null or not no_color then
+ print list_title.bold
+ else
+ print list_title
+ end
+ print ""
+ end
+ if list_items != null and list_items.not_empty then
+ for mentity in list_items do
+ print mentity.cs_list_item(no_color)
+ print ""
+ end
+ else
+ print "None."
+ end
+ end
+end
+
+redef class CmdComment
+ redef fun execute(no_color) do
+ var mentity = self.mentity
+ if mentity == null then return
+
+ var full_name = mentity.cs_full_name(no_color)
+ if no_color == null or not no_color then
+ print "Documentation for `{full_name}`:".bold
+ else
+ print "Documentation for `{full_name}`:"
+ end
+ print ""
+ print " {mentity.cs_icon(no_color)} {mentity.cs_full_name(no_color)}"
+ print " {mentity.cs_declaration(no_color)}"
+ print " {mentity.cs_location(no_color)}"
+ print ""
+ var mdoc = self.mdoc
+ if mdoc == null then return
+ if full_doc then
+ print mdoc.cs_comment(no_color, 3)
+ else
+ print " {mdoc.cs_short_comment(no_color)}\n"
+ end
+ end
+end
+
+redef class CmdAncestors
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Ancestors for `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdParents
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Parents for `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdChildren
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Children for `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdDescendants
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Descendants for `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdLinearization
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Linearization for `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdSearch
+ redef fun execute(no_color) do
+ print_list("Search results for `{query.as(not null)}`:", results, no_color)
+ end
+end
+
+redef class CmdModelEntities
+ redef fun execute(no_color) do
+ var kind = self.kind
+ if no_color != null and not no_color then kind = kind.blue
+ print_list("MEntities for kind `{kind}`:", results, no_color)
+ end
+end
+
+redef class CmdFeatures
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Features for `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdCode
+ redef fun execute(no_color) do
+ var mentity = self.mentity
+ if mentity == null then return
+
+ var title = "Code for `{mentity.cs_full_name(no_color)}`:"
+ if no_color == null or not no_color then
+ print title.bold
+ else
+ print title
+ end
+ printn mentity.cs_source_code
+ end
+end
+
+redef class CmdGraph
+ redef fun execute(no_color) do
+ format = "dot"
+ var dot = self.render
+ if dot == null then return
+ var f = new ProcessWriter("dot", "-Txlib")
+ f.write dot.write_to_string
+ f.close
+ f.wait
+ end
+end
+
+# CmdUsage
+
+redef class CmdCall
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Methods calling `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdNew
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Methods intializing `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdReturn
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Methods returning `{full_name}`:", results, no_color)
+ end
+end
+
+redef class CmdParam
+ redef fun execute(no_color) do
+ var full_name = mentity.as(not null).cs_full_name(no_color)
+ print_list("Methods accepting `{full_name}` as parameter:", results, no_color)
+ end
+end
+
+# CmdCatalog
+
+redef class CmdCatalogPackages
+ redef fun execute(no_color) do
+ print_list("Packages from catalog:", results, no_color)
+ end
+end
+
+redef class CmdCatalogStats
+ redef fun execute(no_color) do
+ if no_color == null or not no_color then
+ print "Catalog statistics:".bold
+ else
+ print "Catalog statistics:"
+ end
+
+ var stats = self.stats.as(not null)
+ print " * {stats.packages} packages"
+ print " * {stats.modules} modules"
+ print " * {stats.methods} methods"
+ print " * {stats.classes} classes"
+ print " * {stats.loc} lines of code"
+ print " * {stats.contributors} contributors"
+ print " * {stats.maintainers} maintainers"
+ print " * {stats.tags} tags"
+ end
+end
+
+redef class CmdCatalogTags
+ redef fun execute(no_color) do
+ if no_color == null or not no_color then
+ print "Tags from catalog:".bold
+ else
+ print "Tags from catalog:"
+ end
+
+ print ""
+ var counts = self.packages_count_by_tags.as(not null)
+ for tag, count in counts do
+ if no_color == null or not no_color then
+ print " * {tag.blue.bold}: {count} packages"
+ else
+ print " * {tag}: {count} packages"
+ end
+ end
+ end
+end
+
+redef class CmdCatalogTag
+ redef fun execute(no_color) do
+ var tag = self.tag.as(not null)
+ if no_color == null or not no_color then tag = tag.blue.bold
+ print_list("Packages tagged with `{tag}`:", results, no_color)
+ end
+end
+
+redef class CmdCatalogMaintaining
+ redef fun execute(no_color) do
+ var name = self.person_name.as(not null)
+ if no_color == null or not no_color then name = name.blue.bold
+ print_list("Packages maintained by `{name}`:", results, no_color)
+ end
+end
+
+redef class CmdCatalogContributing
+ redef fun execute(no_color) do
+ var name = self.person_name.as(not null)
+ if no_color == null or not no_color then name = name.blue.bold
+ print_list("Packages contributed by `{name}`:", results, no_color)
+ end
+end
# See the License for the specific language governing permissions and
# limitations under the License.
-# `nitx`, is a command tool that displays useful informations about the code.
+# `nitx`, a command tool that displays useful data about Nit code
#
# Features:
#
-# * Display comment from name/namespace
-# * Display documentation page from Nitdoc in console
+# * Display documentation from name/namespace
# * Find type usage in parameters, returns and news.
-# * Find usage of a specific property.
+# * Find usage (calls) of a specific property.
# * Find source code related to class/property by its name.
+# * Display inheritance lists
module nitx
-import modelbuilder
-import doc::doc_phases::doc_console
+import frontend
+import doc::term
+import readline
redef class ToolContext
- # Nittx generation phase.
- var docx: Phase = new NitxPhase(self, null)
-
# Used to shortcut the prompt and display directly the result in console.
var opt_command = new OptionString("Nitx command to perform", "-c", "--command")
- init do option_context.add_option opt_command
+ # Compute and use the catalog
+ var opt_catalog = new OptionBool("Use catalog", "--catalog")
+
+ init do option_context.add_option(opt_command, opt_catalog)
end
-# Nitx phase explores the model and prepares the console rendering.
-private class NitxPhase
- super Phase
- redef fun process_mainmodule(mainmodule, mmodules)
- do
- var doc = new DocModel(mainmodule.model, mainmodule)
-
- var phases = [
- new MakePagePhase(toolcontext, doc),
- new ConcernsPhase(toolcontext, doc),
- new StructurePhase(toolcontext, doc),
- new POSetPhase(toolcontext, doc): DocPhase]
-
- for phase in phases do
- toolcontext.info("# {phase.class_name}", 1)
- phase.apply
+# Nitx handles console queries
+#
+# Using `prompt`, the command line can be turned on an interactive tool.
+class Nitx
+
+ # ModelView that contains the informations to display
+ var view: ModelView
+
+ # ModelBuilder to access AST nodes
+ var modelbuilder: ModelBuilder
+
+ # Catalog if any
+ var catalog: nullable Catalog = null is optional
+
+ # Do not use colors in the output
+ var no_color = false is optional
+
+ # Displays the welcome message and start prompt.
+ fun start do
+ welcome
+ prompt
+ end
+
+ # Displays the welcome message and the list of loaded modules.
+ fun welcome do
+ print "Welcome in the Nit Index!"
+ print ""
+ print "Loaded packages:\n"
+ var cmd = new CmdModelEntities(view, kind = "packages")
+ cmd.init_command
+ for mpackage in cmd.results.as(not null) do
+ print " * {mpackage.full_name}"
+ end
+ help
+ end
+
+ # Displays the list of available queries.
+ fun help do
+ # TODO automatize that
+ print "\nCommands:\n"
+ for usage, doc in parser.commands_usage do
+ var l = usage.length / 8
+ print "\t{usage}{"\t" * (3 - l)}{doc}"
+ end
+ print "\n"
+ print "\t:h\t\t\tdisplay this help message"
+ print "\t:q\t\t\tquit interactive mode"
+ print ""
+ end
+
+ # Prompts the user for a query.
+ fun prompt do
+ var line = readline(">> ", true)
+ if line != null then
+ do_command(line)
end
+ prompt
+ end
+
+ # Parser used to process doc commands
+ var parser = new CommandParser(view, modelbuilder, catalog) is lazy
- # start nitx
- var nitx = new Nitx(toolcontext, doc)
- var q = toolcontext.opt_command.value
- if q != null then # shortcut prompt
- print ""
- nitx.do_query(q)
+ # Processes the query string and performs it.
+ fun do_command(str: String) do
+ if str == ":q" then
+ exit 0
+ else if str == ":h" then
+ help
return
end
- nitx.start
+ parser.execute(str, no_color)
+ end
+end
+
+redef class Catalog
+ # Build the catalog for Nitx
+ private fun build_catalog(view: ModelView) do
+ # Compute the poset
+ for p in view.mpackages do
+ var g = p.root
+ assert g != null
+ modelbuilder.scan_group(g)
+
+ deps.add_node(p)
+ for gg in p.mgroups do for m in gg.mmodules do
+ for im in m.in_importation.direct_greaters do
+ var ip = im.mpackage
+ if ip == null or ip == p then continue
+ deps.add_edge(p, ip)
+ end
+ end
+ end
+ # Build the catalog
+ for mpackage in view.mpackages do
+ package_page(mpackage)
+ git_info(mpackage)
+ mpackage_stats(mpackage)
+ end
end
end
var toolcontext = new ToolContext
var tpl = new Template
tpl.add "Usage: nitx [OPTION]... <file.nit>... [query]\n"
-tpl.add "Displays specific pieces of API information from Nit source files."
+tpl.add "Displays pieces of API information from Nit source files."
toolcontext.tooldescription = tpl.write_to_string
# process options
if mmodules.is_empty then return
mbuilder.run_phases
toolcontext.run_global_phases(mmodules)
+var mainmodule = toolcontext.make_main_module(mmodules)
+
+# build views
+var view = new ModelView(model, mainmodule)
+var catalog = null
+if toolcontext.opt_catalog.value then
+ catalog = new Catalog(mbuilder)
+ catalog.build_catalog(view)
+end
+
+# start nitx
+var nitx = new Nitx(view, mbuilder, catalog, toolcontext.opt_no_color.value)
+var q = toolcontext.opt_command.value
+if q != null then # shortcut prompt
+ print ""
+ nitx.do_command(q)
+ return
+end
+nitx.start