directory. `gen-one.sh` handle only one project at a time while `gen-all.sh`
works on a collection of projects grouped in a directory. For detail about how
to invoke each script, see the comments in these scripts.
+
+
+## Python
+
+The built-in filter of Doxygen for Python is very basic. For example, it
+recognizes anything in the “docstrings” as verbatim detailed description. In
+order to enhance the processing of the Python scripts, the
+[doxypypy](https://github.com/Feneric/doxypypy) filter may be used.
super
end
end
+
+# Importation logics for Python.
+class PythonSource
+ super SourceLanguage
+
+ redef fun apply_member_type(member, type_text) do
+ # Doxygen may forgot to remove the `def` keyword on methods.
+ extract_keyword(type_text, "def")
+ super
+ end
+end
init do
sources["any"] = new DefaultSource
sources["java"] = new JavaSource
+ sources["python"] = new PythonSource
var prefix = new OptionText("""
{{{"NAME".bold}}}
var keys = new Array[String].from(sources.keys)
opt_src_lang = new OptionEnum(keys,
- "The programming language to assume when processing chunk in the declarations left as-is by Doxygen. Use `any` (the default) to disable any language-specific processing.",
+ "The programming language to assume when processing chunks in the declarations left as-is by Doxygen. Use `any` (the default) to disable any language-specific processing.",
keys.index_of("any"), "--src-lang")
option_context.add_option(opt_src_lang)
end
# Add handling of multi-line descriptions.
#
-# Note: The algorithm is naive and do not handle internationalisation and
-# escape sequences.
+# Note: The algorithm is naive and do not handle internationalisation,
+# multi-byte characters and control characters.
redef class Option
redef fun pretty(off) do
## OTHER OPTIONS
+`--vm`
+: Run the virtual machine instead of the naive interpreter (experimental)
+
+The virtual machine is currently under heavy development and, unless you are developing the vm, there is no reason to use this option yet.
+
`-o`
: Does nothing. Used for compatibility.
module annotation
import modelbuilder
-private import literal
+import literal
import model::mmodule_data
redef class Prod
end
return res.first
end
-
- # Return all its annotations of a given name in the order of their declaration
- # Retun an empty array if no such an annotation.
- fun get_annotations(name: String): Array[AAnnotation]
- do
- var res = new Array[AAnnotation]
- var nas = n_annotations
- if nas == null then return res
- for na in nas.n_items do
- if na.name != name then continue
- res.add(na)
- end
- return res
- end
end
redef class AAnnotation
- # The name of the annotation
- fun name: String
- do
- return n_atid.n_id.text
- end
-
# Get the single argument of `self` as a `String`.
# Raise error and return null on any inconsistency.
fun arg_as_string(modelbuilder: ModelBuilder): nullable String
end
end
-redef class AExpr
- # Get `self` as a `String`.
- # Return null if not a string.
- fun as_string: nullable String
- do
- if not self isa AStringFormExpr then return null
- return self.value.as(not null)
- end
-
- # Get `self` as an `Int`.
- # Return null if not an integer.
- fun as_int: nullable Int
- do
- if not self isa AIntExpr then return null
- return self.value.as(not null)
- end
-
- # Get `self` as a single identifier.
- # Return null if not a single identifier.
- fun as_id: nullable String
- do
- if self isa AMethidExpr then
- return self.collect_text
- end
- if not self isa ACallExpr then return null
- if not self.n_expr isa AImplicitSelfExpr then return null
- if not self.n_args.n_exprs.is_empty then return null
- return self.n_id.text
- end
-end
-
redef class ModelBuilder
# Collect all annotations by `name` assocated to `mmodule` and its imported modules.
# Note that visibility is not considered.
abstract
intern
extern
+no_warning
pkgconfig
c_compiler_option
# Collect and orchestration of main frontend phases
module frontend
+import no_warning
import simple_misc_analysis
import literal
import modelize
--- /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.
+
+# Fill toolcontext information about blacklisting of warnings.
+module no_warning
+
+import modelbuilder
+private import literal
+
+redef class ToolContext
+ # The phase should be executed before any warning on the module is processed.
+ var no_warning_phase: Phase = new NoWarningPhase(self, [literal_phase])
+end
+
+private class NoWarningPhase
+ super Phase
+
+ redef fun process_nmodule(nmodule)
+ do
+ # Get the mmodule
+ var mmodule = nmodule.mmodule
+ assert mmodule != null
+
+ # If no decl block then quit
+ var nmoduledecl = nmodule.n_moduledecl
+ if nmoduledecl == null then return
+
+ var modelbuilder = toolcontext.modelbuilder
+
+ # Get all the new annotations
+ var name = "no_warning"
+ var annots = nmoduledecl.get_annotations(name)
+
+ if annots.is_empty then return
+
+ var source = nmodule.location.file
+ if source == null then
+ modelbuilder.warning(annots.first, "file-less-module", "Warning: annotation `{name}` does not currently work on file-less modules.")
+ return
+ end
+
+ for annot in annots do
+ var args = annot.n_args
+ if args.is_empty then
+ modelbuilder.error(annot, "Annotation error: `{name}` needs a list of warnings. Use `\"all\"` to disable all warnings.")
+ continue
+ end
+ for arg in args do
+ var tag = arg.as_string
+ if tag == null then
+ modelbuilder.error(arg, "Annotation error: `{name}` expects String as arguments.")
+ continue
+ end
+
+ toolcontext.warning_blacklist[source].add(tag)
+ end
+ end
+ end
+end
private fun accept_literal(v: LiteralVisitor) do end
end
+redef class AExpr
+ # Get `self` as a `String`.
+ # Return null if not a string.
+ fun as_string: nullable String
+ do
+ if not self isa AStringFormExpr then return null
+ return self.value.as(not null)
+ end
+
+ # Get `self` as an `Int`.
+ # Return null if not an integer.
+ fun as_int: nullable Int
+ do
+ if not self isa AIntExpr then return null
+ return self.value.as(not null)
+ end
+
+ # Get `self` as a single identifier.
+ # Return null if not a single identifier.
+ fun as_id: nullable String
+ do
+ if self isa AMethidExpr then
+ return self.collect_text
+ end
+ if not self isa ACallExpr then return null
+ if not self.n_expr isa AImplicitSelfExpr then return null
+ if not self.n_args.n_exprs.is_empty then return null
+ return self.n_id.text
+ end
+end
+
+
redef class AIntExpr
# The value of the literal int once computed.
var value: nullable Int
import interpreter
import frontend
import parser_util
+import vm
# Create a tool context to handle options and paths
var toolcontext = new ToolContext
toolcontext.option_context.add_option(opt)
var opt_eval = new OptionBool("Specifies the program from command-line", "-e")
var opt_loop = new OptionBool("Repeatedly run the program for each line in file-name arguments", "-n")
-toolcontext.option_context.add_option(opt_eval, opt_loop)
+var opt_vm = new OptionBool("Run the virtual machine instead of the naive interpreter (experimental)", "--vm")
+toolcontext.option_context.add_option(opt_eval, opt_loop, opt_vm)
# We do not add other options, so process them now!
toolcontext.process_options(args)
modelbuilder.run_debugger_autorun(self_mm, self_args)
else if toolcontext.opt_debugger_mode.value then
modelbuilder.run_debugger(self_mm, self_args)
+else if opt_vm.value then
+ modelbuilder.run_virtual_machine(self_mm, self_args)
else
modelbuilder.run_naive_interpreter(self_mm, self_args)
end
var self_mm = mainmodule
var self_args = arguments
-modelbuilder.run_naive_interpreter(self_mm, self_args)
+modelbuilder.run_virtual_machine(self_mm, self_args)
# Lexer and its tokens.
# This file was generated by SableCC (http://www.sablecc.org/).
-module lexer
+module lexer is no_warning("missing-doc")
intrude import parser_nodes
intrude import lexer_work
# Parser.
# This file was generated by SableCC (http://www.sablecc.org/).
-module parser
+module parser is no_warning("missing-doc", "unread-variable")
intrude import parser_prod
intrude import parser_work
# Raw AST node hierarchy.
# This file was generated by SableCC (http://www.sablecc.org/).
-module parser_abs
+module parser_abs is no_warning("missing-doc")
import location
# Visit all nodes in order.
# Thus, call `v.enter_visit(e)` for each child `e`
fun visit_all(v: Visitor) is abstract
+
+ # Do a deep search and return an array of tokens that match a given text
+ fun collect_tokens_by_text(text: String): Array[Token]
+ do
+ var v = new CollectTokensByTextVisitor(text)
+ v.enter_visit(self)
+ return v.result
+ end
+
+ # Do a deep search and return an array of node that are annotated
+ # The attached node can be retrieved by two invocations of parent
+ fun collect_annotations_by_name(name: String): Array[AAnnotation]
+ do
+ var v = new CollectAnnotationsByNameVisitor(name)
+ v.enter_visit(self)
+ return v.result
+ end
end
+private class CollectTokensByTextVisitor
+ super Visitor
+ var text: String
+ var result = new Array[Token]
+ redef fun visit(node)
+ do
+ node.visit_all(self)
+ if node isa Token and node.text == text then result.add(node)
+ end
+end
+
+private class CollectAnnotationsByNameVisitor
+ super Visitor
+ var name: String
+ var result = new Array[AAnnotation]
+ redef fun visit(node)
+ do
+ node.visit_all(self)
+ if node isa AAnnotation and node.n_atid.n_id.text == name then result.add(node)
+ end
+end
+
+
# A sequence of nodes
# It is a specific class (instead of using a Array) to track the parent/child relation when nodes are added or removed
class ANodes[E: ANode]
# All the annotations attached directly to the node
var n_annotations: nullable AAnnotations = null is writable
+ # Return all its annotations of a given name in the order of their declaration
+ # Retun an empty array if no such an annotation.
+ fun get_annotations(name: String): Array[AAnnotation]
+ do
+ var res = new Array[AAnnotation]
+ var nas = n_annotations
+ if nas == null then return res
+ for na in nas.n_items do
+ if na.name != name then continue
+ res.add(na)
+ end
+ return res
+ end
+
redef fun replace_with(n: ANode)
do
super
var n_opar: nullable TOpar = null is writable
var n_args = new ANodes[AExpr](self)
var n_cpar: nullable TCpar = null is writable
+
+ # The name of the annotation
+ fun name: String
+ do
+ return n_atid.n_id.text
+ end
end
# An annotation name
# Production AST nodes full definition.
# This file was generated by SableCC (http://www.sablecc.org/).
-module parser_prod
+module parser_prod is no_warning("missing-doc")
import lexer
intrude import parser_nodes
$ output 'parser_abs.nit'
# Raw AST node hierarchy.
# This file was generated by SableCC (http://www.sablecc.org/).
-module parser_abs
+module parser_abs is no_warning("missing-doc")
import location
$ output 'lexer.nit'
# Lexer and its tokens.
# This file was generated by SableCC (http://www.sablecc.org/).
-module lexer
+module lexer is no_warning("missing-doc")
$ if $usermodule
intrude import $usermodule
$ output 'parser_prod.nit'
# Production AST nodes full definition.
# This file was generated by SableCC (http://www.sablecc.org/).
-module parser_prod
+module parser_prod is no_warning("missing-doc")
import lexer
$ if $usermodule
$ output 'parser.nit'
# Parser.
# This file was generated by SableCC (http://www.sablecc.org/).
-module parser
+module parser is no_warning("missing-doc", "unread-variable")
intrude import parser_prod
intrude import parser_work
return tok
end
end
-
-redef class ANode
- # Do a deep search and return an array of tokens that match a given text
- fun collect_tokens_by_text(text: String): Array[Token]
- do
- var v = new CollectTokensByTextVisitor(text)
- v.enter_visit(self)
- return v.result
- end
-
- # Do a deep search and return an array of node that are annotated
- # The attached node can be retrieved by two invocation of parent
- fun collect_annotations_by_name(name: String): Array[AAnnotation]
- do
- var v = new CollectAnnotationsByNameVisitor(name)
- v.enter_visit(self)
- return v.result
- end
-end
-
-private class CollectTokensByTextVisitor
- super Visitor
- var text: String
- var result = new Array[Token]
- redef fun visit(node)
- do
- node.visit_all(self)
- if node isa Token and node.text == text then result.add(node)
- end
-end
-
-private class CollectAnnotationsByNameVisitor
- super Visitor
- var name: String
- var result = new Array[AAnnotation]
- redef fun visit(node)
- do
- node.visit_all(self)
- if node isa AAnnotation and node.n_atid.n_id.text == name then result.add(node)
- end
-end
import location
import version
import template
+import more_collections
# A warning or an error
class Message
# Set this value to `true` if you need to keep the program going in case of error.
var keep_going = false is writable
+ # List of tags per source-file whose warnings are not displayed.
+ #
+ # Initially empty, it is up to the toll to fill it.
+ # The tag "all" means all warnings and advices.
+ var warning_blacklist = new MultiHashMap[SourceFile, String]
+
+ # Is the source-file of `l` associated with `tag` in `warning_blacklist`?
+ #
+ # currently returns `false` if `l` is null or does not have a source-file.
+ fun is_warning_blacklisted(l: nullable Location, tag: String): Bool
+ do
+ if l == null then return false
+ var f = l.file
+ if f == null then return false
+ var tags = warning_blacklist.get_or_null(f)
+ if tags == null then return false
+ return tags.has("all") or tags.has(tag)
+ end
+
# Output all current stacked messages and display total error informations
#
# Return true if no errors occurred.
do
if opt_warning.value.has("no-{tag}") then return
if not opt_warning.value.has(tag) and opt_warn.value == 0 then return
+ if is_warning_blacklisted(l, tag) then return
messages.add(new Message(l, tag, text))
warning_count = warning_count + 1
if opt_stop_on_first_error.value then check_errors
do
if opt_warning.value.has("no-{tag}") then return
if not opt_warning.value.has(tag) and opt_warn.value <= 1 then return
+ if is_warning_blacklisted(l, tag) then return
messages.add(new Message(l, tag, text))
warning_count = warning_count + 1
if opt_stop_on_first_error.value then check_errors
import perfect_hashing
redef class ModelBuilder
- redef fun run_naive_interpreter(mainmodule: MModule, arguments: Array[String])
+ fun run_virtual_machine(mainmodule: MModule, arguments: Array[String])
do
var time0 = get_time
self.toolcontext.info("*** NITVM STARTING ***", 1)
--src-lang java -- root-namespace ../contrib/neo_doxygen/tests/root-namespace/xml
--src-lang java -- inner-class ../contrib/neo_doxygen/tests/inner-class/xml
-- python-def ../contrib/neo_doxygen/tests/python-def/xml
+--src-lang python -- python-def ../contrib/neo_doxygen/tests/python-def/xml
bench_
nit_args1
nit_args3
+nit_args4
nitvm_args1
nitvm_args3
nitc_args1
nitc_args5
nitc_args6
nitc_args8
-test_markdown_args1
+nitunit_args
+test_docdown_args
pep8analysis
-test_android_platform
-android
-nitcc_parser_gen
-mnit
emscripten
+nitserial_args
+nitunit_args
+nitpretty_args
+hamming_number
+hailstone
+test_map
+nitls
+nituml
-h, --help Show the help (this page).
- --src-lang The programming language to assume when processing chunk in the
+ --src-lang The programming language to assume when processing chunks in the
declarations left as-is by Doxygen. Use `any` (the default) to
- disable any language-specific processing. <any, java>
+ disable any language-specific processing. <any, java, python>
--- /dev/null
+Reading ../contrib/neo_doxygen/tests/python-def/xml... Done.
+3 files read.
+Linking nodes...\e[s \e[u\e[J Done.
+Saving 10 nodes...
+---===DONE===---
+Saving 17 edges...
+Edge
+=type=4:ROOT
+=properties=JsonObject(0):
+{}
+----
+=from=Node
+=labels=Array(3):
+10:python-def
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"python-def"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(1):
+{"name":"python-def"}
+
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(1):
+{"name":"python-def"}
+----
+=to=Node
+=labels=Array(3):
+10:python-def
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"python-def"}
+
+
+Edge
+=type=6:PARENT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#12:namespacefoo
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(4):
+{"kind":"namespace","visibility":"","name":"foo","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(1):
+{"name":"python-def"}
+
+
+Edge
+=type=5:NESTS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(1):
+{"name":"python-def"}
+----
+=to=Entity#12:namespacefoo
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(4):
+{"kind":"namespace","visibility":"","name":"foo","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+
+
+Edge
+=type=8:DECLARES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#12:namespacefoo
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(4):
+{"kind":"namespace","visibility":"","name":"foo","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+7:MModule
+=properties=JsonObject(2):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","name":"foo"}
+
+
+Edge
+=type=10:INTRODUCES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+7:MModule
+=properties=JsonObject(2):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","name":"foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+
+
+Edge
+=type=7:DEFINES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+7:MModule
+=properties=JsonObject(2):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","name":"foo"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+9:MClassDef
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","is_intro":true,"name":"(self)"}
+
+
+Edge
+=type=7:DEFINES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#47:namespacefoo_1aab1e88a2212b202c20f3c9bd799a1ad4
+=labels=Array(4):
+10:python-def
+7:MEntity
+8:MPropDef
+10:MMethodDef
+=properties=JsonObject(8):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:16,1--20,1","is_intern":false,"is_extern":false,"is_abstract":false,"visibility":"public","name":"bar","mdoc":["A bar function in the foo namespace.","By default, Doxygen recognizes anything in the docstrings as verbatim\ndetailed description."],"is_intro":true}
+----
+=to=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+9:MProperty
+7:MMethod
+=properties=JsonObject(3):
+{"visibility":"public","is_init":false,"name":"bar"}
+
+
+Edge
+=type=9:SIGNATURE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#47:namespacefoo_1aab1e88a2212b202c20f3c9bd799a1ad4
+=labels=Array(4):
+10:python-def
+7:MEntity
+8:MPropDef
+10:MMethodDef
+=properties=JsonObject(8):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:16,1--20,1","is_intern":false,"is_extern":false,"is_abstract":false,"visibility":"public","name":"bar","mdoc":["A bar function in the foo namespace.","By default, Doxygen recognizes anything in the docstrings as verbatim\ndetailed description."],"is_intro":true}
+----
+=to=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+5:MType
+10:MSignature
+=properties=JsonObject(0):
+{}
+
+
+Edge
+=type=7:PROJECT
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#12:namespacefoo
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MGroup
+=properties=JsonObject(4):
+{"kind":"namespace","visibility":"","name":"foo","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+----
+=to=Node
+=labels=Array(3):
+10:python-def
+7:MEntity
+8:MProject
+=properties=JsonObject(1):
+{"name":"python-def"}
+
+
+Edge
+=type=9:CLASSTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+----
+=to=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(1):
+{"name":"(self)"}
+
+
+Edge
+=type=5:CLASS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(1):
+{"name":"(self)"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+
+
+Edge
+=type=9:BOUNDTYPE
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+9:MClassDef
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","is_intro":true,"name":"(self)"}
+----
+=to=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+5:MType
+10:MClassType
+=properties=JsonObject(1):
+{"name":"(self)"}
+
+
+Edge
+=type=6:MCLASS
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+9:MClassDef
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","is_intro":true,"name":"(self)"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+6:MClass
+=properties=JsonObject(4):
+{"kind":"class","visibility":"public","name":"(self)","location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1"}
+
+
+Edge
+=type=10:INTRODUCES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+9:MClassDef
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","is_intro":true,"name":"(self)"}
+----
+=to=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+9:MProperty
+7:MMethod
+=properties=JsonObject(3):
+{"visibility":"public","is_init":false,"name":"bar"}
+
+
+Edge
+=type=14:INTRO_CLASSDEF
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(4):
+10:python-def
+7:MEntity
+9:MProperty
+7:MMethod
+=properties=JsonObject(3):
+{"visibility":"public","is_init":false,"name":"bar"}
+----
+=to=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+9:MClassDef
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","is_intro":true,"name":"(self)"}
+
+
+Edge
+=type=8:DECLARES
+=properties=JsonObject(0):
+{}
+----
+=from=Entity#0:
+=labels=Array(3):
+10:python-def
+7:MEntity
+9:MClassDef
+=properties=JsonObject(3):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:1,1--1,1","is_intro":true,"name":"(self)"}
+----
+=to=Entity#47:namespacefoo_1aab1e88a2212b202c20f3c9bd799a1ad4
+=labels=Array(4):
+10:python-def
+7:MEntity
+8:MPropDef
+10:MMethodDef
+=properties=JsonObject(8):
+{"location":"%SOURCE_DIRECTORY%\/foo.py:16,1--20,1","is_intern":false,"is_extern":false,"is_abstract":false,"visibility":"public","name":"bar","mdoc":["A bar function in the foo namespace.","By default, Doxygen recognizes anything in the docstrings as verbatim\ndetailed description."],"is_intro":true}
+
+
+---===DONE===---
-for x in nitg-g nitg-s nitg-sg nitg-e niti; do
+#!/bin/bash
+# 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.
+
+# Run some tests on each engine
+for x in nitg-g nitg-s nitg-sg nitg-e niti nitvm; do
echo "--engine $x"
./tests.sh --engine $x "$@"
done
;;
nitvm)
isinterpret=true
+ enginebinname=nit
+ OPT="--vm $OPT"
savdirs="sav/niti/"
;;
emscripten)