Common command-line tool infrastructure than handle options and error messages

Introduced classes

class BashCompletion

nitc :: BashCompletion

This class generates a compatible bash_completion script file.
class Message

nitc :: Message

A warning or an error
class ToolContext

nitc :: ToolContext

Global context for tools

Redefined classes

redef class Location

nitc :: toolcontext $ Location

A location inside a source file
redef class SourceFile

nitc :: toolcontext $ SourceFile

A raw text Nit source file

All class definitions

class BashCompletion

nitc $ BashCompletion

This class generates a compatible bash_completion script file.
redef class Location

nitc :: toolcontext $ Location

A location inside a source file
class Message

nitc $ Message

A warning or an error
redef class SourceFile

nitc :: toolcontext $ SourceFile

A raw text Nit source file
class ToolContext

nitc $ ToolContext

Global context for tools
package_diagram nitc::toolcontext toolcontext opts opts nitc::toolcontext->opts nitc::location location nitc::toolcontext->nitc::location nitc::version version nitc::toolcontext->nitc::version template template nitc::toolcontext->template more_collections more_collections nitc::toolcontext->more_collections core core opts->core nitc::location->core nitc::version->core template->core serialization serialization more_collections->serialization poset poset more_collections->poset ...core ... ...core->core ...serialization ... ...serialization->serialization ...poset ... ...poset->poset nitc::phase phase nitc::phase->nitc::toolcontext nitc::modelbuilder_base modelbuilder_base nitc::modelbuilder_base->nitc::toolcontext nitc::parser_util parser_util nitc::parser_util->nitc::toolcontext nitc::neo neo nitc::neo->nitc::toolcontext nitc::test_toolcontext test_toolcontext nitc::test_toolcontext->nitc::toolcontext nitc::literal literal nitc::literal->nitc::phase nitc::modelbuilder modelbuilder nitc::modelbuilder->nitc::phase nitc::simple_misc_analysis simple_misc_analysis nitc::simple_misc_analysis->nitc::phase nitc::literal... ... nitc::literal...->nitc::literal nitc::modelbuilder... ... nitc::modelbuilder...->nitc::modelbuilder nitc::simple_misc_analysis... ... nitc::simple_misc_analysis...->nitc::simple_misc_analysis nitc::loader loader nitc::loader->nitc::modelbuilder_base nitc::loader... ... nitc::loader...->nitc::loader nitc::platform platform nitc::platform->nitc::parser_util nitc::serialization_model_phase serialization_model_phase nitc::serialization_model_phase->nitc::parser_util nitc::deriving deriving nitc::deriving->nitc::parser_util nitc::parallelization_phase parallelization_phase nitc::parallelization_phase->nitc::parser_util nitc::i18n_phase i18n_phase nitc::i18n_phase->nitc::parser_util nitc::regex_phase regex_phase nitc::regex_phase->nitc::parser_util nitc::actors_injection_phase actors_injection_phase nitc::actors_injection_phase->nitc::parser_util nitc::app_annotations app_annotations nitc::app_annotations->nitc::parser_util nitc::testing_base testing_base nitc::testing_base->nitc::parser_util nitc::test_parser test_parser nitc::test_parser->nitc::parser_util nitc::platform... ... nitc::platform...->nitc::platform nitc::serialization_model_phase... ... nitc::serialization_model_phase...->nitc::serialization_model_phase nitc::deriving... ... nitc::deriving...->nitc::deriving nitc::parallelization_phase... ... nitc::parallelization_phase...->nitc::parallelization_phase nitc::i18n_phase... ... nitc::i18n_phase...->nitc::i18n_phase nitc::regex_phase... ... nitc::regex_phase...->nitc::regex_phase nitc::actors_injection_phase... ... nitc::actors_injection_phase...->nitc::actors_injection_phase nitc::app_annotations... ... nitc::app_annotations...->nitc::app_annotations nitc::testing_base... ... nitc::testing_base...->nitc::testing_base nitc::test_parser... ... nitc::test_parser...->nitc::test_parser nitc::test_neo test_neo nitc::test_neo->nitc::neo nitc::test_neo... ... nitc::test_neo...->nitc::test_neo a_star-m a_star-m a_star-m->nitc::test_toolcontext a_star-m... ... a_star-m...->a_star-m

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module location

nitc :: location

Nit source-file and locations in source-file
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module opts

opts :: opts

Management of options on the command line
module template

template :: template

Basic template system
module version

nitc :: version

This file was generated by git-gen-version.sh

Children

module modelbuilder_base

nitc :: modelbuilder_base

Load nit source files and build the associated model
module neo

nitc :: neo

Save and load a Model to/from a Neo4j graph.
module parser_util

nitc :: parser_util

Utils and tools related to parsers and AST
module phase

nitc :: phase

Phases of the processing of nit programs
module test_toolcontext

nitc :: test_toolcontext

Program used to test ToolContext

Descendants

module a_star-m

a_star-m

module abstract_compiler

nitc :: abstract_compiler

Abstract compiler
module actors_generation_phase

nitc :: actors_generation_phase

Generate a support module for each module that contain a class annotated with is actor
module actors_injection_phase

nitc :: actors_injection_phase

Injects model for the classes annotated with "is actor" so
module android

nitc :: android

Compile program for the Android platform
module android_annotations

nitc :: android_annotations

Additionnal annotations to gather metadata on Android projects
module annotation

nitc :: annotation

Management and utilities on annotations
module api

nitc :: api

Components required to build a web server about the nit model.
module api_auth

nitc :: api_auth

module api_base

nitc :: api_base

Base classes used by nitweb.
module api_docdown

nitc :: api_docdown

Nitdoc specific Markdown format handling for Nitweb
module api_feedback

nitc :: api_feedback

Feedback related features
module api_light

nitc :: api_light

Highlight and collect messages from a piece of code
module api_model

nitc :: api_model

module app_annotations

nitc :: app_annotations

Annotations to gather metadata on app.nit projects
module ast_metrics

nitc :: ast_metrics

Metrics about the nodes and identifiers in the AST
module astbuilder

nitc :: astbuilder

Instantiation and transformation of semantic nodes in the AST of expressions and statements
module auto_super_init

nitc :: auto_super_init

Computing of super-constructors that must be implicitly called at the begin of constructors.
module c

nitc :: c

Support for nesting C code within a Nit program using its FFI
module c_compiler_options

nitc :: c_compiler_options

Offers the annotations cflags and ldflags to specify
module catalog

nitc :: catalog

Basic catalog generator for Nit packages
module check_annotation

nitc :: check_annotation

Check that annotation present in the AST are either primitive or user-declared
module code_gen

nitc :: code_gen

Main frontend phases plus code generation phases
module commands_base

nitc :: commands_base

Documentation commands
module commands_catalog

nitc :: commands_catalog

Commands to retrieve Catalog related data
module commands_docdown

nitc :: commands_docdown

Doc down related queries
module commands_graph

nitc :: commands_graph

Graph commands
module commands_http

nitc :: commands_http

Initialize commands from HTTP requests
module commands_model

nitc :: commands_model

Doc commands about a Model or a MEntity
module commands_parser

nitc :: commands_parser

A parser that create DocCommand from a string
module commands_usage

nitc :: commands_usage

Commands about how mentities are used
module compilation

nitc :: compilation

The compilation module of the VirtualMachine
module compiler

nitc :: compiler

Compilation to C
module compiler_ffi

nitc :: compiler_ffi

Full FFI support for the compiler
module compiler_serialization

nitc :: compiler_serialization

Serialization support for the compiler
module contracts

nitc :: contracts

Module to build contract
module cpp

nitc :: cpp

Supports the use of the C++ language through the FFI
module deriving

nitc :: deriving

Injection of automatic method definitions for standard methods, based on the attributes of the classes
module detect_covariance

nitc :: detect_covariance

Detect the static usage of covariance in the code.
module detect_variance_constraints

nitc :: detect_variance_constraints

Collect metrics about detected variances constraints on formal types.
module div_by_zero

nitc :: div_by_zero

Detection of divisions by zero in obvious cases
module dynamic_loading_ffi

nitc :: dynamic_loading_ffi

Execute FFI code by creating and loading shared libraries
module emscripten

nitc :: emscripten

Compile to JavaScript using the Emscripten SDK
module explain_assert

nitc :: explain_assert

Explain failed assert to the console by modifying the AST.
module extern_classes

nitc :: extern_classes

Manages all extern classes and their associated foreign type.
module extra_java_files

nitc :: extra_java_files

Intro the annotation extra_java_files to compile extra java files
module ffi

nitc :: ffi

Full FFI support, independent of the compiler
module ffi_base

nitc :: ffi_base

Tools and utilities for implement FFI with different languages
module flow

nitc :: flow

Intraprocedural static flow.
module frontend

nitc :: frontend

Collect and orchestration of main frontend phases
module generate_hierarchies

nitc :: generate_hierarchies

Create dot files for various hierarchies of a model.
module global_compiler

nitc :: global_compiler

Global compilation of a Nit program
module glsl_validation

nitc :: glsl_validation

Check shader code within Nit modules using the tool glslangValidator
module header_dependency

nitc :: header_dependency

Tracks which modules has public header code that must be imported
module highlight

nitc :: highlight

Highlighting of Nit AST
module html_commands

nitc :: html_commands

Render commands results as HTML
module html_model

nitc :: html_model

Translate mentities to html blocks.
module htmlight

nitc :: htmlight

Highlighting of Nit AST with HTML
module i18n_phase

nitc :: i18n_phase

Basic support of internationalization through the generation of id-to-string tables
module inheritance_metrics

nitc :: inheritance_metrics

Collect metrics about inheritance usage
module interpreter

nitc :: interpreter

Interpretation of Nit programs
module ios

nitc :: ios

Compile programs for the iOS platform
module java

nitc :: java

FFI support for the Java language
module java_compiler

nitc :: java_compiler

Compile Nit code to Java code
module json_commands

nitc :: json_commands

Translate command results to json
module json_model

nitc :: json_model

Make model entities Serializable.
module light

nitc :: light

Light FFI support for the compiler
module light_c

nitc :: light_c

Support for nesting C code within a Nit program using its FFI
module light_ffi

nitc :: light_ffi

Light FFI support, independent of the compiler
module light_ffi_base

nitc :: light_ffi_base

Tools and utilities for implement FFI with different languages
module light_only

nitc :: light_only

Compiler support for the light FFI only, detects unsupported usage of callbacks
module literal

nitc :: literal

Parsing of literal values in the abstract syntax tree.
module loader

nitc :: loader

Loading of Nit source files
module local_var_init

nitc :: local_var_init

Verify that local variables are initialized before their usage
module mclasses_metrics

nitc :: mclasses_metrics

Collect common metrics about mclasses
module md_commands

nitc :: md_commands

Render commands results as Markdown
module memory_logger

nitc :: memory_logger

Extension to inject memory-tracing instrumentation in code generated by nitc.
module mendel_metrics

nitc :: mendel_metrics

The Mendel model helps to understand class hierarchies.
module metrics

nitc :: metrics

Various statistics about Nit models and programs
module metrics_base

nitc :: metrics_base

Helpers for various statistics tools.
module mixin

nitc :: mixin

Loading and additional module refinements at link-time.
module mmodules_metrics

nitc :: mmodules_metrics

Collect common metrics about modules
module model_collect

nitc :: model_collect

Collect things from the model.
module model_hyperdoc

nitc :: model_hyperdoc

Dump of Nit model into hypertext human-readable format.
module model_index

nitc :: model_index

Search things from the Model
module model_visitor

nitc :: model_visitor

Simple visitor framework for Nit models.
module modelize

nitc :: modelize

Create a model from nit source files
module modelize_class

nitc :: modelize_class

Analysis and verification of class definitions to instantiate model element
module modelize_property

nitc :: modelize_property

Analysis and verification of property definitions to instantiate model element
module naive_interpreter

nitc :: naive_interpreter

Interpretation of a Nit program directly on the AST
module nit

nitc :: nit

A naive Nit interpreter
module nitc

nitc :: nitc

A Nit compiler
module nitcatalog

nitc :: nitcatalog

Basic catalog generator for Nit packages
module nitdoc

nitc :: nitdoc

Generator of static API documentation for the Nit language
module nith

nitc :: nith

A ligHt Nit compiler
module nitj

nitc :: nitj

Compile Nit into Java code runnable on the Java Virtual Machine.
module nitlight

nitc :: nitlight

Tool that produces highlighting for Nit programs
module nitls

nitc :: nitls

Simple tool to list Nit source files
module nitmetrics

nitc :: nitmetrics

A program that collects various metrics on nit programs and libraries
module nitni

nitc :: nitni

Native interface related services (used underneath the FFI)
module nitni_base

nitc :: nitni_base

Native interface related services (used underneath the FFI)
module nitni_callbacks

nitc :: nitni_callbacks

nitni services related to callbacks (used underneath the FFI)
module nitpackage

nitc :: nitpackage

Helpful features about packages
module nitpick

nitc :: nitpick

A program that collect potential style and code issues
module nitpretty

nitc :: nitpretty

module nitrestful

nitc :: nitrestful

Tool generating boilerplate code linking RESTful actions to Nit methods
module nitsaf

nitc :: nitsaf

Nit Static Analysis Framework client example.
module nitserial

nitc :: nitserial

Serialization support compiler, a tool to support deserialization of live generic types
module nitsmells

nitc :: nitsmells

module nituml

nitc :: nituml

UML generator in dot format.
module nitunit

nitc :: nitunit

Testing tool.
module nitvm

nitc :: nitvm

The Nit virtual machine launcher
module nitweb

nitc :: nitweb

Runs a webserver based on nitcorn that render things from model.
module nitx

nitc :: nitx

nitx, a command tool that displays useful data about Nit code
module no_warning

nitc :: no_warning

Fill toolcontext information about blacklisting of warnings.
module nullables_metrics

nitc :: nullables_metrics

Statistics about the usage of nullables
module objc

nitc :: objc

FFI support for Objective-C
module on_demand_compiler

nitc :: on_demand_compiler

Compiles extern code within a module to a static library, as needed
module parallelization_phase

nitc :: parallelization_phase

Phase generating threads for functions annotated with threaded annotation
module parse_annotations

nitc :: parse_annotations

Simple annotation parsing
module pkgconfig

nitc :: pkgconfig

Offers the PkgconfigPhase to use the external program "pkg-config" in order
module platform

nitc :: platform

Platform system, used to customize the behavior of the compiler.
module poset_metrics

nitc :: poset_metrics

Metrics about the various posets of the model of a Nit program
module pretty

nitc :: pretty

Library used to pretty print Nit code.
module rapid_type_analysis

nitc :: rapid_type_analysis

Rapid type analysis on the AST
module readme_metrics

nitc :: readme_metrics

Collect common metrics about README files
module refinement_metrics

nitc :: refinement_metrics

Collect metrics about refinement usage
module regex_phase

nitc :: regex_phase

Check for error in regular expressions from string literals
module rta_metrics

nitc :: rta_metrics

Metrics from RTA
module saf

nitc :: saf

Nit Static Analysis Framework.
module saf_base

nitc :: saf_base

Static Analysis Framework base
module scope

nitc :: scope

Identification and scoping of local variables and labels.
module self_metrics

nitc :: self_metrics

Metrics about the usage of explicit and implicit self
module semantize

nitc :: semantize

Process bodies of methods in regard with the model.
module separate_compiler

nitc :: separate_compiler

Separate compilation of a Nit program
module separate_erasure_compiler

nitc :: separate_erasure_compiler

Separate compilation of a Nit program with generic type erasure
module serialization_code_gen_phase

nitc :: serialization_code_gen_phase

Phase generating methods (code) to serialize Nit objects
module serialization_model_phase

nitc :: serialization_model_phase

Phase generating methods (model-only) to serialize Nit objects
module simple_misc_analysis

nitc :: simple_misc_analysis

Simple vavious processing on a AST
module ssa

nitc :: ssa

Single-Static Assignment algorithm from an AST
module static

nitc :: static

Nitdoc generation framework
module static_base

nitc :: static_base

Base entities shared by all the nitdoc code
module static_cards

nitc :: static_cards

Cards templates for the static documentation
module static_html

nitc :: static_html

Render documentation pages as HTML
module static_index

nitc :: static_index

Manage indexing of Nit model for Nitdoc QuickSearch.
module static_structure

nitc :: static_structure

Composes the pages of the static documentation
module static_types_metrics

nitc :: static_types_metrics

Metrics on the usage of explicit static types.
module tables_metrics

nitc :: tables_metrics

Metrics on table generation
module term

nitc :: term

module term_model

nitc :: term_model

Markdown templates for Nit model MEntities.
module test_astbuilder

nitc :: test_astbuilder

Program used to test the clone method of the astbuilder tool
module test_highlight

nitc :: test_highlight

Program used to test the Nit highlighter
module test_model_visitor

nitc :: test_model_visitor

Example of model_visitor
module test_neo

nitc :: test_neo

Test for neo model saving and loading.
module test_parser

nitc :: test_parser

Program used to test the NIT parser
module test_phase

nitc :: test_phase

Stub for loading a runing phases on a bunch of modules
module test_test_phase

nitc :: test_test_phase

Example of simple module that aims to do some specific work on nit programs.
module testing

nitc :: testing

Test unit generation and execution for Nit.
module testing_base

nitc :: testing_base

Base options for testing tools.
module testing_doc

nitc :: testing_doc

Testing from code comments.
module testing_gen

nitc :: testing_gen

Test Suites generation.
module testing_suite

nitc :: testing_suite

Testing from external files.
module transform

nitc :: transform

Thansformations that simplify the AST of expressions
module typing

nitc :: typing

Intraprocedural resolution of static types and OO-services
module uml

nitc :: uml

Group head module for UML generation services
module uml_base

nitc :: uml_base

Exposes the base class for UML generation of a Model
module uml_class

nitc :: uml_class

Provides facilities of exporting a Model to a UML class diagram
module uml_module

nitc :: uml_module

Services for generation of a UML package diagram based on a Model
module variables_numbering

nitc :: variables_numbering

Handle all numbering operations related to local variables in the Nit virtual machine
module vim_autocomplete

nitc :: vim_autocomplete

Generate files used by the Vim plugin to autocomplete with doc
module virtual_machine

nitc :: virtual_machine

Implementation of the Nit virtual machine
module vm

nitc :: vm

Entry point of all vm components
module vm_optimizations

nitc :: vm_optimizations

Optimization of the nitvm
module xcode_templates

nitc :: xcode_templates

Templates and other services to create XCode projects
# Common command-line tool infrastructure than handle options and error messages
module toolcontext

import opts
import location
import version
import template
import more_collections

# A warning or an error
class Message
	super Comparable
	redef type OTHER: Message

	# The origin of the message in the source code, if any.
	var location: nullable Location

	# The category of the message.
	#
	# Used by quality-control tool for statistics or to enable/disable things individually.
	var tag: nullable String

	# The human-readable description of the message.
	#
	# eg. "Error: cannot find method `foo`."
	#
	# A good message should:
	#
	# * start with a message type like "Error:", "Syntax Error:", "Warning:".
	#   The type is capitalized and terminated by a column.
	#   The rest on the message starts with a lowercase letter and is terminated with a dot.
	#
	# * be short and fit on a single line.
	#
	# * have meaningful information first.
	#   This helps the reader and remain usable
	#   when truncated, by an IDE for instance.
	#
	# * enclose identifiers, keywords and pieces of code with back-quotes.
	var text: String

	# The severity level
	#
	# * 0 is advices (see `ToolContext::advice`)
	# * 1 is warnings (see `ToolContext::warning`)
	# * 2 is errors (see `ToolContext::error`)
	var level: Int

	# Comparisons are made on message locations.
	redef fun <(other: OTHER): Bool do
		if location == null then return true
		if other.location == null then return false

		return location.as(not null) < other.location.as(not null)
	end

	redef fun ==(other): Bool do
		if not other isa Message then return false
		return location == other.location and tag == other.tag and text == other.text
	end

	redef fun to_s: String
	do
		var l = location
		if l == null then
			return text
		else
			return "{l}: {text}"
		end
	end

	# A colored version of the message including the original source line
	fun to_color_string: String
	do
		var esc = 27.code_point
		#var red = "{esc}[0;31m"
		#var bred = "{esc}[1;31m"
		#var green = "{esc}[0;32m"
		var yellow = "{esc}[0;33m"
		var def = "{esc}[0m"

		var tag = tag
		if tag != null then
			tag = " ({tag})"
		else
			tag = ""
		end
		var l = location
		if l == null then
			return "{text}{tag}"
		else if l.file == null then
			return "{yellow}{l}{def}: {text}{tag}"
		else
			return "{yellow}{l}{def}: {text}{tag}\n{l.colored_line("1;31")}"
		end
	end
end

redef class Location
	# Errors and warnings associated to this location.
	var messages: nullable Array[Message]

	# Add a message to `self`
	#
	# See `messages`
	private fun add_message(m: Message)
	do
		var ms = messages
		if ms == null then
			ms = new Array[Message]
			messages = ms
		end
		ms.add m
		var s = file
		if s != null then s.messages.add m
	end
end

redef class SourceFile
	# Errors and warnings associated to the whole source.
	var messages = new Array[Message]
end

# Global context for tools
class ToolContext
	# Number of errors
	var error_count: Int = 0 is writable

	# Number of warnings
	var warning_count: Int = 0

	# Directory where to generate log files
	var log_directory: String = "logs"

	# Stream in `log_directory` where all info messages are written
	var log_info: nullable Writer = null

	# Messages
	private var messages = new Array[Message]
	private var message_sorter: Comparator = default_comparator

	# Does an error prevent the program to stop at `check_errors`?
	#
	# Default to false.
	# 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, total and exit the program
	#
	# If there is no error, exit with 0, else exit with 1.
	fun quit
	do
		check_errors
		errors_info
		if error_count > 0 then exit(1) else exit(0)
	end

	# Output all current stacked messages
	#
	# Return true if no errors occurred.
	#
	# If some errors occurred, the behavior depends on the value of `keep_going`.
	# If `keep_going` is false, then the total error informations is displayed and the program exits.
	# Else, false is returned.
	fun check_errors: Bool
	do
		if messages.length > 0 then
			message_sorter.sort(messages)

			for m in messages do
				if opt_no_color.value then
					sys.stderr.write("{m}\n")
				else
					sys.stderr.write("{m.to_color_string}\n")
				end
			end

			messages.clear
		end

		if error_count > 0 then
			if not keep_going then
				errors_info
				exit(1)
			end
			return false
		end
		return true
	end

	# Display total error informations
	fun errors_info
	do
		if error_count == 0 and warning_count == 0 then return
		if opt_no_color.value then return
		sys.stderr.write "Errors: {error_count}. Warnings: {warning_count}.\n"
	end

	# Display an error
	#
	# Return the message (to add information)
	fun error(l: nullable Location, s: String): Message
	do
		var m = new Message(l, null, s, 2)
		if messages.has(m) then return m
		if l != null then l.add_message m
		if opt_warn.value <= -1 then return m
		messages.add m
		error_count = error_count + 1
		if opt_stop_on_first_error.value then check_errors
		return m
	end

	# Add an error, show errors and quit
	#
	# Because the program will quit, nothing is returned.
	fun fatal_error(l: nullable Location, s: String)
	do
		error(l,s)
		check_errors
	end

	# Display a first-level warning.
	#
	# First-level warnings are warnings that SHOULD be corrected,
	# and COULD usually be immediately corrected.
	#
	# * There is a simple correction
	# * There is no reason to let the code this way (no reasonable @supresswarning-like annotation)
	# * They always are real issues (no false positive)
	#
	# First-level warnings are displayed by default (except if option `-q` is given).
	#
	# Return the message (to add information) or null if the warning is disabled
	fun warning(l: nullable Location, tag: String, text: String): nullable Message
	do
		if is_warning_blacklisted(l, tag) then return null
		var m = new Message(l, tag, text, 1)
		if messages.has(m) then return null
		if l != null then l.add_message m
		if opt_warning.value.has("no-{tag}") then return null
		if not opt_warning.value.has(tag) and opt_warn.value <= 0 then return null
		messages.add m
		warning_count = warning_count + 1
		if opt_stop_on_first_error.value then check_errors
		return m
	end

	# Display a second-level warning.
	#
	# Second-level warnings are warnings that should require investigation,
	# but cannot always be immediately corrected.
	#
	# * The correction could be complex. e.g. require a refactorisation or an API change.
	# * The correction cannot be done. e.g. Code that use a deprecated API for some compatibility reason.
	# * There is not a real issue (false positive). Note that this should be unlikely.
	# * Transitional: While a real warning, it fires a lot in current code, so a transition is needed
	#   in order to fix them before promoting the advice to a warning.
	#
	# In order to prevent warning inflation à la Java, second-level warnings are not displayed by
	# default and require an additional option `-W`.
	#
	# Return the message (to add information) or null if the warning is disabled
	fun advice(l: nullable Location, tag: String, text: String): nullable Message
	do
		if is_warning_blacklisted(l, tag) then return null
		var m = new Message(l, tag, text, 0)
		if messages.has(m) then return null
		if l != null then l.add_message m
		if opt_warning.value.has("no-{tag}") then return null
		if not opt_warning.value.has(tag) and opt_warn.value <= 1 then return null
		messages.add m
		warning_count = warning_count + 1
		if opt_stop_on_first_error.value then check_errors
		return m
	end

	# Display an info
	fun info(s: String, level: Int)
	do
		if level <= verbose_level then
			print "{s}"
		end
		if log_info != null then
			log_info.write s
			log_info.write "\n"
		end
	end

	# Executes a program while checking if it's available and if the execution ended correctly
	#
	# Stops execution and prints errors if the program isn't available or didn't end correctly
	fun exec_and_check(args: Array[String], error: String)
	do
		info("+ {args.join(" ")}", 2)

		var prog = args.first
		args.remove_at 0

		# Is the wanted program available?
		var proc_which = new ProcessReader.from_a("which", [prog])
		proc_which.wait
		var res = proc_which.status
		if res != 0 then
			print_error "{error}: executable \"{prog}\" not found"
			exit 1
		end

		# Execute the wanted program
		var proc = new Process.from_a(prog, args)
		proc.wait
		res = proc.status
		if res != 0 then
			print_error "{error}: execution of \"{prog} {args.join(" ")}\" failed"
			exit 1
		end
	end

	# Global OptionContext
	var option_context = new OptionContext

	# Option --warn
	var opt_warn = new OptionCount("Show additional warnings (advices)", "-W", "--warn")

	# Option --warning
	var opt_warning = new OptionArray("Show/hide a specific warning", "-w", "--warning")

	# Option --quiet
	var opt_quiet = new OptionBool("Do not show warnings", "-q", "--quiet")

	# Option --log
	var opt_log = new OptionBool("Generate various log files", "--log")

	# Option --log-dir
	var opt_log_dir = new OptionString("Directory where to generate log files", "--log-dir")

	# Option --nit-dir
	var opt_nit_dir = new OptionString("Base directory of the Nit installation", "--nit-dir")

	# Option --share-dir
	var opt_share_dir = new OptionString("Directory containing tools assets", "--share-dir")

	# Option --help
	var opt_help = new OptionBool("Show Help (This screen)", "-h", "-?", "--help")

	# Option --version
	var opt_version = new OptionBool("Show version and exit", "--version")

	# Option --set-dummy-tool
	var opt_set_dummy_tool = new OptionBool("Set toolname and version to DUMMY. Useful for testing", "--set-dummy-tool")

	# Option --verbose
	var opt_verbose = new OptionCount("Additional messages from the tool", "-v", "--verbose")

	# Option --stop-on-first-error
	var opt_stop_on_first_error = new OptionBool("Just display the first encountered error then stop", "--stop-on-first-error")

	# Option --keep-going
	var opt_keep_going = new OptionBool("Continue after errors, whatever the consequences", "--keep-going")

	# Option --no-color
	var opt_no_color = new OptionBool("Do not use color to display errors and warnings", "--no-color")

	# Option --bash-completion
	var opt_bash_completion = new OptionBool("Generate bash_completion file for this program", "--bash-completion")

	# Option --stub-man
	var opt_stub_man = new OptionBool("Generate a stub manpage in pandoc markdown format", "--stub-man")

	# Option --no-contract
	var opt_no_contract = new OptionBool("Disable the contracts usage", "--no-contract")

	# Option --full-contract
	var opt_full_contract = new OptionBool("Enable all contracts usage", "--full-contract")

	# Verbose level
	var verbose_level: Int = 0

	init
	do
		option_context.add_option(opt_warn, opt_warning, opt_quiet, opt_stop_on_first_error, opt_keep_going, opt_no_color, opt_log, opt_log_dir, opt_nit_dir, opt_help, opt_version, opt_set_dummy_tool, opt_verbose, opt_bash_completion, opt_stub_man, opt_no_contract, opt_full_contract)

		# Hide some internal options
		opt_stub_man.hidden = true
		opt_bash_completion.hidden = true
		opt_set_dummy_tool.hidden = true
	end

	# Name, usage and synopsis of the tool.
	# It is mainly used in `usage`.
	# Should be correctly set by the client before calling `process_options`
	# A multi-line string is recommmended.
	#
	# eg. `"Usage: tool [OPTION]... [FILE]...\nDo some things."`
	var tooldescription: String = "Usage: [OPTION]... [ARG]..." is writable

	# Does `process_options` should accept an empty sequence of arguments.
	# ie. nothing except options.
	# Is `false` by default.
	#
	# If required, if should be set by the client before calling `process_options`
	var accept_no_arguments = false is writable

	# print the full usage of the tool.
	# Is called by `process_option` on `--help`.
	# It also could be called by the client.
	fun usage
	do
		print tooldescription
		option_context.usage
	end

	# Parse and process the options given on the command line
	fun process_options(args: Sequence[String])
	do
		self.opt_warn.value = 1

		# init options
		option_context.parse(args)

		if opt_help.value then
			usage
			exit 0
		end

		if opt_version.value then
			print version
			exit 0
		end

		if opt_bash_completion.value then
			var bash_completion = new BashCompletion(self)
			bash_completion.write_to(sys.stdout)
			exit 0
		end

		if opt_stub_man.value then
			print """
# NAME

{{{tooldescription.split("\n")[1]}}}

# SYNOPSYS

# OPTIONS
"""
			for o in option_context.options do
				var first = true
				printn "### "
				for n in o.names do
					if first then first = false else printn ", "
					printn "`{n}`"
				end
				print ""
				print "{o.helptext}."
				print ""
			end
			print """
# SEE ALSO

The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>"""
			exit 0
		end

		var errors = option_context.errors
		if not errors.is_empty then
			for e in errors do print "Error: {e}"
			print tooldescription
			print "Use --help for help"
			exit 1
		end

		nit_dir = locate_nit_dir

		if option_context.rest.is_empty and not accept_no_arguments then
			print tooldescription
			print "Use --help for help"
			exit 1
		end

		# Set verbose level
		verbose_level = opt_verbose.value

		if opt_keep_going.value then keep_going = true

		if self.opt_quiet.value then self.opt_warn.value = 0

		if opt_log_dir.value != null then log_directory = opt_log_dir.value.as(not null)
		if opt_log.value then
			# Make sure the output directory exists
			log_directory.mkdir

			# Redirect the verbose messages
			log_info = (log_directory/"info.txt").to_path.open_wo
		end
	end

	# Get the current `nit_version` or "DUMMY_VERSION" if `--set-dummy-tool` is set.
	fun version: String do
		if opt_set_dummy_tool.value then
			return "DUMMY_VERSION"
		end
		return nit_version
	end

	# Get the name of the tool or "DUMMY_TOOL" id `--set-dummy-tool` is set.
	fun toolname: String do
		if opt_set_dummy_tool.value then
			return "DUMMY_TOOL"
		end
		return sys.program_name.basename
	end

	# The identified root directory of the Nit package
	#
	# It is assignable but is automatically set by `process_options` with `locate_nit_dir`.
	var nit_dir: nullable String = null is writable

	# Shared files directory.
	#
	# Most often `nit/share/`.
	var share_dir: String is lazy do
		var sharedir = opt_share_dir.value
		if sharedir == null then
			sharedir = nit_dir / "share"
			if not sharedir.file_exists then
				fatal_error(null, "Fatal Error: cannot locate shared files directory in {sharedir}. Uses --share-dir to define it's location.")
			end
		end
		return sharedir
	end

	# Guess a possible nit_dir.
	#
	# It uses, in order:
	#
	# * the option `opt_nit_dir`
	# * the environment variable `NIT_DIR`
	# * the runpath of the program from argv[0]
	# * the runpath of the process from /proc
	# * the search in PATH
	#
	# If there is errors (e.g. the indicated path is invalid) or if no
	# path is found, then an error is displayed and the program exits.
	#
	# The result is returned without being assigned to `nit_dir`.
	# This function is automatically called by `process_options`
	fun locate_nit_dir: String
	do
		# the option has precedence
		var res = opt_nit_dir.value
		if res != null then
			if not check_nit_dir(res) then
				fatal_error(null, "Fatal Error: the value of --nit-dir does not seem to be a valid base Nit directory: {res}.")
			end
			return res
		end

		# then the environ variable has precedence
		res = "NIT_DIR".environ
		if not res.is_empty then
			if not check_nit_dir(res) then
				fatal_error(null, "Fatal Error: the value of NIT_DIR does not seem to be a valid base Nit directory: {res}.")
			end
			return res
		end

		# find the runpath of the program from argv[0]
		res = "{sys.program_name.dirname}/.."
		if check_nit_dir(res) then return res.simplify_path

		# find the runpath of the process from /proc
		var exe = "/proc/self/exe"
		if exe.file_exists then
			res = exe.realpath
			res = res.dirname.join_path("..")
			if check_nit_dir(res) then return res.simplify_path
		end

		# search in the PATH
		var path_sep = if is_windows then ";" else ":"
		var ps = "PATH".environ.split(path_sep)
		for p in ps do
			res = p/".."
			if check_nit_dir(res) then return res.simplify_path
		end

		fatal_error(null, "Fatal Error: cannot locate a valid base Nit directory. It is quite unexpected. Try to set the environment variable `NIT_DIR` or to use the `--nit-dir` option.")
		abort
	end

	private fun check_nit_dir(res: String): Bool
	do
		return res.file_exists and "{res}/src/nit.nit".file_exists
	end
end

# This class generates a compatible `bash_completion` script file.
#
# On some Linux systems `bash_completion` allow the program to control command line behaviour.
#
# ~~~sh
# $ nitls [TAB][TAB]
# file1.nit              file2.nit              file3.nit
#
# $ nitls --[TAB][TAB]
# --bash-toolname        --keep                 --path                 --tree
# --depends              --log                  --package              --verbose
# --disable-phase        --log-dir              --quiet                --version
# --gen-bash-completion  --no-color             --recursive            --warn
# --help                 --only-metamodel       --source
# --ignore-visibility    --only-parse           --stop-on-first-error
# ~~~
#
# Generated file can be placed in system bash_completion directory `/etc/bash_completion.d/`
# or source it in `~/.bash_completion`.
class BashCompletion
	super Template

	var toolcontext: ToolContext

	private fun extract_options_names: Array[String] do
		var names = new Array[String]
		for option in toolcontext.option_context.options do
			for name in option.names do
				if name.has_prefix("--") then names.add name
			end
		end
		return names
	end

	redef fun rendering do
		var name = toolcontext.toolname
		var option_names = extract_options_names
		addn "# generated bash completion file for {name} {toolcontext.version}"
		addn "_{name}()"
		addn "\{"
		addn "	local cur prev opts"
		addn "	COMPREPLY=()"
		addn "	cur=\"$\{COMP_WORDS[COMP_CWORD]\}\""
		addn "	prev=\"$\{COMP_WORDS[COMP_CWORD-1]\}\""
		if not option_names.is_empty then
			addn "	opts=\"{option_names.join(" ")}\""
			addn "	if [[ $\{cur\} == -* ]] ; then"
			addn "		COMPREPLY=( $(compgen -W \"$\{opts\}\" -- $\{cur\}) )"
			addn "		return 0"
			addn "	fi"
		end
		addn "\} &&"
		addn "complete -o default -F _{name} {name}"
	end
end
src/toolcontext.nit:20,1--690,3