Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

960 lines (859 sloc) 39.091 kB
/*
* Copyright (c) 2004-2008 The University of Wroclaw.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the University may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Nemerle.Collections;
using Nemerle.Utility;
using System.Text;
namespace Nemerle.Compiler
{
public class CompilationOptions
{
public mutable OutputFileName : string;
public mutable OutputPath : string;
public mutable ProjectPath : string;
public mutable RootNamespace : string;
public mutable XmlDocOutputFileName : string;
public mutable DumpTypedTree : bool;
public mutable PrintExpressionsType : bool;
public mutable DumpNamedMethod : string;
public mutable DumpDecisionTree : bool;
public mutable AdditionalDebug : bool;
public mutable TargetIsLibrary : bool;
public mutable TargetIsWinexe : bool;
public mutable IgnoreConfusion : bool;
public mutable ThrowOnError : bool;
public mutable GeneralTailCallOpt : bool;
public mutable ProgressBar : bool;
public mutable ColorMessages : bool;
public mutable UseLoadedCorlib : bool;
public mutable DoNotLoadMacros : bool;
public mutable DoNotLoadStdlib : bool;
public mutable EmitDebug : bool;
public mutable CompileToMemory : bool;
public mutable EarlyExit : bool;
public mutable GreedyReferences : bool;
public mutable IndentationSyntax : bool;
// do not unload external libraries in consecutive compilations
public mutable PersistentLibraries : bool;
public mutable MainClass : string;
public mutable IsMainClassAutogenerated : bool = false;
public mutable DoPrintStats : bool;
public mutable LexerStoreComments : bool;
public mutable Optimize : Hashtable [string, int];
public mutable CheckIntegerOverflow : bool = true;
public mutable DisableExternalParsers : bool = false;
public mutable UnmanagedResource : string;
public mutable LinkedResources : list [string];
public mutable EmbeddedResources : list [string];
public mutable ReferencedLibraries : list [string];
public mutable LibraryPaths : list[string];
public mutable MacrosToLoad : list [string];
public mutable Sources : list [string];
public mutable Platform : string;
private disabled_keywords : Hashtable [string, list [list [string]]] = Hashtable ();
public CommandDefines : Map [string, bool] { get; private set; }
public Warnings : WarningOptions = WarningOptions();
public MatchOptions : MatchCompilerOptions = MatchCompilerOptions();
public StrongAssemblyKeyName : string
{
mutable filename : string;
get { filename }
set {
when (value != null && filename != null) // it already exists
Message.Warning ($"assembly key filename was already specified (`$filename'), ignoring the `$value' one");
filename = value;
}
}
internal Validate () : void
{
when(System.IO.Path.GetExtension (OutputFileName) == "")
OutputFileName += if(this.TargetIsLibrary) ".dll" else ".exe";
when(EmitDebug && null != Optimize)
Message.Warning(10010, "compilation options `-debug+' and `-optimize' has poor compatibility: "
"`-debug+' suppresses runtime optimizations");
}
public this ()
{
Clear ();
}
public Clear () : void
{
OutputFileName = "out.exe";
ProjectPath = System.IO.Directory.GetCurrentDirectory();
OutputPath = "";
XmlDocOutputFileName = null;
DumpTypedTree = false;
PrintExpressionsType = false;
TargetIsLibrary = false;
TargetIsWinexe = false;
IgnoreConfusion = false;
ThrowOnError = false;
GeneralTailCallOpt = false;
ProgressBar = false;
ColorMessages = true;
UseLoadedCorlib = false;
DoNotLoadMacros = false;
DoNotLoadStdlib = false;
EmitDebug = false;
CompileToMemory = false;
EarlyExit = false;
GreedyReferences = true;
DumpNamedMethod = "";
AdditionalDebug = false;
PersistentLibraries = false;
DumpDecisionTree = false;
IndentationSyntax = false;
DoPrintStats = false;
LexerStoreComments = false;
Optimize = null;
CheckIntegerOverflow = true;
UnmanagedResource = null;
Platform = "";
LinkedResources = [];
EmbeddedResources = [];
ReferencedLibraries = [];
LibraryPaths = [];
MacrosToLoad = [];
Sources = [];
disabled_keywords.Clear ();
CommandDefines = Map ();
MainClass = null;
StrongAssemblyKeyName = null;
DisableExternalParsers = false;
MatchOptions.Clear();
}
/// default null value for [in_namespace] means that keyword
/// will be disabled in all namespaces
///
/// Note: only keywords introduced by syntax extensions can be disabled
public DisableKeyword (key : string, in_namespace : string = null) : void
{
def in_namespace =
if (in_namespace == null) null
else NString.Split (in_namespace, '.').Reverse ();
match (disabled_keywords.Get (key)) {
| Some (null) => () // we disable this keyword in all namespaces
| Some (ns) | None with ns = [] =>
if (in_namespace == null)
disabled_keywords [key] = null;
else
unless (ns.Contains (in_namespace))
disabled_keywords [key] = in_namespace :: ns;
}
}
public IsKeywordDisabled (key : string, in_namespaces : list [NamespaceTree.Node]) : bool
{
match (disabled_keywords.Get (key)) {
| Some (null) => true
| None => false
| Some (ns) =>
ret : {
foreach (in_namespace in in_namespaces)
foreach (n in ns)
when (in_namespace.Equals (n)) ret (true);
false
}
}
}
/// Adds given name as a command-line defined constant.
/// It is then visible in all files just like defined preprocessor constant.
public DefineConstant (name : string) : void
{
CommandDefines = CommandDefines.Replace (name, true);
}
/// Removes given name as a command-line defined constant.
public UndefineConstant (name : string) : void
{
CommandDefines = CommandDefines.Replace (name, false);
}
/// Checks if given name was specified as command-line defined constant.
public IsConstantDefined (name : string) : bool
{
match (CommandDefines.Find (name)) {
| Some (x) => x
| _ => false
}
}
public ShouldDump (fn : Typedtree.TFunHeader) : bool
{
DumpTypedTree &&
(DumpNamedMethod == "" || DumpNamedMethod == fn.Name)
}
public GetCommonOptions () : list [Getopt.CliOption]
{
def split_opt (s : string) {
if (s == null)
[]
else {
def split = s.Split (array [' ', '\t', '\n', '\r']);
mutable result = [];
for (mutable i = split.Length - 1; i >= 0; --i) {
def s = split [i].Trim ();
when (s != "")
result ::= s;
}
result
}
}
def execute_pkgconfig (opt : string) {
def pkg = System.Diagnostics.Process ();
pkg.StartInfo.FileName = "pkg-config";
pkg.StartInfo.Arguments = ("--libs " + opt);
pkg.StartInfo.RedirectStandardOutput = true;
pkg.StartInfo.UseShellExecute = false;
mutable result = "";
try
{
ignore (pkg.Start ());
result = pkg.StandardOutput.ReadLine ();
if (pkg.WaitForExit (5000))
pkg.Close ();
else
{
pkg.Kill ();
throw System.Exception ("operation timeouted")
}
}
catch { | e => Message.Warning ($"pkg-config execution failed: $(e.Message)") }
match (split_opt (result))
{
| [] => ["-r", opt]
| x => x
}
}
def execute_fromfile (s : string) {
try {
mutable line = "";
mutable args = [];
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (sr = System.IO.StreamReader(s)) {
def sb = StringBuilder ();
// process each line
while (line != null) {
def t = line.Length;
// iterate through line parsing "" and '' quoted strings
for (mutable i = 0; i < t; i++)
{
mutable c = line [i];
match (c) {
| '"' | '\'' =>
i++;
def end = c;
def loop () {
when (i < t) {
// if it is not the end of quotation, proceed
unless (line [i] == end) {
_ = sb.Append (line [i]);
i++;
loop ()
}
}
}
loop ();
| ' ' =>
// whitespace not inside quotation
when (sb.Length > 0){
args = sb.ToString () :: args;
sb.Length = 0;
}
| _ => ignore (sb.Append (c));
}
}
// if something was read, store it
when (sb.Length > 0){
args = sb.ToString () :: args;
sb.Length = 0;
}
line = sr.ReadLine ();
}
// return result
NList.Rev (args)
}
}
catch {
| _ =>
Message.Error ("cannot read response file `" + s + "'");
[]
}
}
def set_target (target) {
match (target.ToLowerInvariant()) {
| "winexe"
| "wexe"
| "win" =>
this.TargetIsLibrary = false;
this.TargetIsWinexe = true;
| "lib"
| "library"
| "dll" =>
this.TargetIsLibrary = true;
| "exe"
| "console" =>
this.TargetIsLibrary = false;
this.TargetIsWinexe = false;
| x =>
Getopt.Error ($ "invalid target `$(x)'");
System.Environment.Exit (1);
}
}
[
Getopt.CliOption.Flag (name = "-indentation-syntax",
aliases = ["-i"],
help = "Turn on indentation-based syntax (similar to Python)",
handler = fun () { this.IndentationSyntax = true; }),
Getopt.CliOption.String (name = "-out",
aliases = ["-o"],
help = "Output file name",
handler = fun (s) { this.OutputFileName = s }),
Getopt.CliOption.String (name = "-project-path",
aliases = ["-pp"],
help = "Root path of project",
handler = fun (s) { this.ProjectPath = s }),
Getopt.CliOption.String (name = "-output-path",
aliases = [],
handler = fun (s) { this.OutputPath = s }),
Getopt.CliOption.String (name = "-root-namespace",
aliases = ["-rns"],
help = "Root namespace",
handler = fun (s) { this.RootNamespace = s }),
Getopt.CliOption.String (name = "-target",
aliases = ["-t"],
help = "Specifies the target (exe, library, winexe)",
handler = set_target),
Getopt.CliOption.String (name = "-reference",
aliases = ["-r", "-ref"],
help = "Link specified assembly",
handler = fun (s) { this.ReferencedLibraries ::= s }),
Getopt.CliOption.String (name = "-library-path",
aliases = ["-lib", "-L"],
help = "Add specified directory to library search path",
handler = fun (s) { this.LibraryPaths ::= s }),
Getopt.CliOption.String (name = "-define",
aliases = ["-d", "-def"],
help = "Define preprocessor symbol for conditional compilation",
handler = fun (x) {
foreach (constant in x.Split (array [';']))
DefineConstant (constant)
}),
Getopt.CliOption.String (name = "-doc",
aliases = [],
help = "Output XML documentation of program's class hierarchy",
handler = fun (x) {
this.XmlDocOutputFileName = x;
LexerStoreComments = true;
}),
Getopt.CliOption.String (name = "-win32-resource",
aliases = ["-win32res"],
help = "Embed unmanaged resource file to output (only one allowed)",
handler = fun (x) {
if(this.UnmanagedResource == null)
this.UnmanagedResource = x
else
Message.Error("only one unmanaged resource can be embedded")
}),
Getopt.CliOption.String (name = "-platform",
aliases = [],
help = "Specifies the CPU that must be present to host the assembly (x86, x64, anycpu, ia64). The default is anycpu.",
handler = fun (x) {
def platform = x.ToLowerInvariant();
if (["x86", "x64", "anycpu", "ia64"].Contains (platform))
this.Platform = platform;
else
Message.Error ($"invalid platform `$(x)'");
}),
Getopt.CliOption.String (name = "-resource",
aliases = ["-res"],
help = "Embed resource file to output",
handler = fun (x) {
this.EmbeddedResources = x :: this.EmbeddedResources;
}),
Getopt.CliOption.String (name = "-linkresource",
aliases = ["-linkres"],
help = "Link resource file from output assembly",
handler = fun (x) {
this.LinkedResources = x :: this.LinkedResources;
}),
Getopt.CliOption.Boolean (name = "-debug",
aliases = ["-g"],
help = "Enable debug symbols generation",
handler = fun (x) { this.EmitDebug = x }),
Getopt.CliOption.SubstitutionString (name = "-pkg-config",
aliases = ["-pkg", "-p"],
help = "Link to assemblies listed by pkg-config run on"
" given string",
substitute = execute_pkgconfig),
Getopt.CliOption.SubstitutionString (name = "-from-file",
aliases = ["@"],
help = "Read command line options from given file",
substitute = execute_fromfile),
Getopt.CliOption.String (name = "-macros",
aliases = ["-m"],
help = "Load macros from given library (without loading"
" types from library into the scope)",
handler = fun (x) { this.MacrosToLoad ::= x; }),
Getopt.CliOption.String (name = "-warn",
aliases = ["-W"],
help = "Specify warning level",
handler = fun (x) {
Warnings.Level =
match (x) {
| "0" => 0 | "1" => 1 | "2" => 2 | "3" => 3 | "4" => 4 | "5" => 5
| _ =>
Message.Error (x + " is not a valid warning level (must be 0-5)");
-1
}
}),
Getopt.CliOption.String (name = "-nowarn",
aliases = [],
help = "Suppress Specified Warnings",
handler = fun (x : string) {
foreach (str in x.Split (',')) {
try {
def num = int.Parse (str);
Warnings.Disable (num);
}
catch {
| _ =>
Message.Error (str + " is not a valid warning number format")
}
}
}),
Getopt.CliOption.String (name = "-dowarn",
aliases = [],
help = "Enable Specified Warnings",
handler = fun (x : string) {
foreach (str in x.Split (',')) {
try {
def num = int.Parse (str);
Warnings.Enable (num);
}
catch {
| _ =>
Message.Error (Location.Default, str + " is not a valid warning number format")
}
}
}),
Getopt.CliOption.Boolean (name = "-warnaserror",
aliases = [],
help = "Treat warnings as errors",
handler = fun (val) { Warnings.TreatWarningsAsErrors = val }),
Getopt.CliOption.String (name = "-keyfile",
aliases = [],
help = "Specify a strong name key file",
handler = fun (x) { StrongAssemblyKeyName = x }),
Getopt.CliOption.Boolean (name = "-greedy-references",
aliases = ["-greedy"],
help = "Recursive loading references of used assemblies",
handler = fun (val) { this.GreedyReferences = val; }),
Getopt.CliOption.Flag (name = "-general-tail-call-opt",
aliases = ["-Ot"],
help = "Enable general tail call optimization (programs are slower on MS.NET, but faster on Mono)",
handler = fun () { this.GeneralTailCallOpt = true }),
Getopt.CliOption.String (name = "-disable-keyword",
aliases = ["-no-keyword"],
help = "Prevent given identifiers from being reserved as keywords"
" (it only works for keywords introduced by syntax extensions)",
handler = fun (x : string) {
foreach (str in x.Split (',')) {
if (str.IndexOf ('.') == -1)
this.DisableKeyword (str)
else {
def last_dot = str.LastIndexOf ('.');
this.DisableKeyword (str.Substring (last_dot + 1),
str.Substring (0, last_dot))
}
}
}),
Getopt.CliOption.Flag (name = "-no-stdmacros",
aliases = ["-nostdmacros"],
help = "Do not load standard macros",
handler = fun () { this.DoNotLoadMacros = true }),
Getopt.CliOption.Flag (name = "-no-stdlib",
aliases = ["-nostdlib"],
help = "Do not load Nemerle.dll",
handler = fun () { this.DoNotLoadStdlib = true }),
Getopt.CliOption.Flag (name = "-use-loaded-corlib",
help = "Use already loaded mscorlib.dll and System.dll",
handler = fun () { this.UseLoadedCorlib = true }),
Getopt.CliOption.Flag (name = "-ignore-confusion",
help = "Output stack trace even when seen errors",
handler = fun () { this.IgnoreConfusion = true }),
Getopt.CliOption.Flag (name = "-throw-on-error",
help = "Output stack trace on first error",
handler = fun () {
this.ThrowOnError = true;
this.IgnoreConfusion = true;
}),
Getopt.CliOption.Flag (name = "-early-exit",
help = "Exit just after first method with an error",
handler = fun () {
this.EarlyExit = true;
}),
Getopt.CliOption.Flag (name = "-dump-typed-tree",
aliases = ["-dt"],
help = "Pretty prints the typed tree on stdout",
handler = fun () {
this.DumpTypedTree = true;
}),
Getopt.CliOption.Flag (name = "-print-expressions-type",
aliases = ["-pet"],
help = "Pretty prints types of expressions in dump (use with -dt)",
handler = fun () {
this.PrintExpressionsType = true;
}),
Getopt.CliOption.Flag (name = "-additional-debug",
aliases = ["-ad"],
help = "NOHELP",
handler = fun () {
this.AdditionalDebug = true;
}),
Getopt.CliOption.String (name = "-dump-typed-method",
aliases = ["-dm"],
help = "Pretty prints the named typed tree on stdout",
handler = fun (s : string) {
this.DumpTypedTree = true;
this.DumpNamedMethod = s;
}),
Getopt.CliOption.Flag (name = "-dump-decision-trees",
aliases = ["-dd"],
help = "NOHELP",
handler = fun () {
this.DumpDecisionTree = true;
}),
Getopt.CliOption.Flag (name = "-boolean-constant-matching-opt",
aliases = ["-Obcm"],
help = "NOHELP",
handler = fun () {
Message.Warning ("This command line option (-Obcm) has beed removed, it is"
" enabled by default")
}),
Getopt.CliOption.Flag (name = "-ordinal-constant-matching-opt",
aliases = ["-Oocm"],
help = "NOHELP",
handler = fun () {
Message.Warning ("This command line option (-Oocm) has been removed, it is "
" enabled by default")
}),
Getopt.CliOption.Flag (name = "-string-constant-matching-opt",
aliases = ["-Oscm"],
help = "NOHELP",
handler = fun () {
Message.Warning ("This command line option (-Oscm) has been removed - "
"it didn't work correctly. If you would like to contribute"
" code for optimized string matching, please contact us.")
}),
Getopt.CliOption.Flag (name = "-target-library",
aliases = ["-tdll"],
help = "NOHELP",
handler = fun () { this.TargetIsLibrary = true; }),
Getopt.CliOption.Flag (name = "-target-exe",
aliases = ["-texe"],
help = "NOHELP",
handler = fun () { this.TargetIsLibrary = false; }),
Getopt.CliOption.Flag (name = "-nologo",
help = "Suppress compiler copyright message",
handler = fun () { this.ProgressBar = false; }),
Getopt.CliOption.Flag (name = "-no-color",
help = "Disable ANSI coloring of error/warning/hint messages",
handler = fun () { this.ColorMessages = false }),
Getopt.CliOption.Flag (name = "-pedantic-lexer",
help = "Enable some pedantic checks for illegal characters"
" in input stream (default at warning level 5)",
handler = fun () { Warnings.Enable (10002); }),
Getopt.CliOption.Boolean (name = "-progress-bar",
aliases = ["-bar"],
help = "Enable / disable progress bar for compilation",
handler = fun (val) { this.ProgressBar = val; }),
Getopt.CliOption.Flag (name = "-no-progress-bar",
aliases = ["-q"],
help = "NOHELP",
handler = fun () { this.ProgressBar = false; }),
Getopt.CliOption.Flag (name = "-warn-help",
help = "Display help about available warnings.",
handler = fun () {
System.Console.Write (
"Following warning options are available:\n" +
Warnings.Help);
System.Environment.Exit (0);
}),
Getopt.CliOption.Flag (name = "-stats", aliases = [], help = "NOHELP",
handler = fun () { this.DoPrintStats = true; }),
Getopt.CliOption.String (name = "-main",
aliases = [],
help = "Specify the class that contains the entry point",
handler = fun (s) { this.MainClass = s; }),
Getopt.CliOption.Flag ( name = "-optimize",
aliases = ["-O"],
help = "Enable / disable code optimalizations",
handler = fun () {
when (this.Optimize == null)
this.Optimize = Hashtable();
this.Optimize["tuple"] = 1;
this.Optimize["propagate"] = 1;
this.Optimize["unify"] = 1;
this.Optimize["print"] = 0;
}
),
Getopt.CliOption.String (name = "-optimize-options",
aliases = ["-Oopt"],
help = "",
handler = fun (val) {
when (this.Optimize == null)
this.Optimize = Hashtable();
foreach (str in val.Split (','))
{
def kv = str.Split('=');
this.Optimize[kv[0]] =
if (kv.Length == 1)
1
else
int.Parse(kv[1]);
}
}
),
Getopt.CliOption.Boolean (name = "-checked",
aliases = [],
help = "Enable / disable integer overflow check (default: +)",
handler = fun (val) { CheckIntegerOverflow = val }),
Getopt.CliOption.Int (name = "-min-switch-size-variants",
aliases = ["-Oswv"],
help = "Minimum size of switch table used for matching variants "
"(0 disables this optimization).",
handler = fun (val) { MatchOptions.MinSwitchSizeForVariants = val }),
Getopt.CliOption.Int (name = "-min-switch-size-ordinals",
aliases = ["-Oswo"],
help = "Minimum size of switch table used for matching ordinals "
"(0 disables this optimization).",
handler = fun (val) { MatchOptions.MinSwitchSizeForOrdinals = val })
]
}
}
/** Module used to enumerate and filter warnings emitted by compiler
*/
public class WarningOptions
{
[Accessor(flags = WantSetter)]
mutable treat_warnings_as_errors : bool = false;
public Level : int
{
mutable cur_level : int;
get { cur_level }
set {
when (value >= 0 && value <= 4) {
cur_level = value;
currently_enabled = Hashtable ();
for (mutable lev = 0; lev <= value; lev++) {
foreach (x in levels [lev])
unless (disabled.Contains (x))
currently_enabled.Add (x, "");
}
enabled.Iter (fun (x, _) {
unless (currently_enabled.Contains (x))
currently_enabled.Add (x, "")
});
}
}
}
mutable currently_enabled : Hashtable [int, object];
enabled : Hashtable [int, object] = Hashtable ();
disabled : Hashtable [int, object] = Hashtable ();
// FileIndex -> list [line_number * warning_number]
pragma_warning : Hashtable [int, list [int * int]] = Hashtable ();
public this () {
enabled.Clear ();
disabled.Clear ();
pragma_warning.Clear ();
Level = 4;
}
/** Gives information if warning with given number should be emited by
compiler.
It depends on currently set warning level and enabled / disabled
particular warnings.
*/
public IsEnabled (nr : int) : bool
{
mutable ena = false;
try { ena = currently_enabled.Contains (nr); }
catch { | _ => ena = false; }
ena
}
/** Check if given warning is enabled at a given location. */
public IsEnabledAt (loc : Location, nr : int) : bool
{
if (IsEnabled (nr)) {
if (pragma_warning.Contains (loc.FileIndex)) {
def line = loc.Line;
def loop (l) {
| (line', _) :: xs when line' > line =>
loop (xs)
| (_, k) :: xs =>
if (k == 1 || k == nr) false
else if (k == -1 || k == -nr) true
else loop (xs)
| [] => true
}
loop (pragma_warning [loc.FileIndex])
} else true
} else false
}
public AddPragmaWarning (file_idx : int, line_no : int, warning_no : int) : void
{
if (pragma_warning.Contains (file_idx))
pragma_warning [file_idx] ::= (line_no, warning_no)
else
pragma_warning [file_idx] = [(line_no, warning_no)];
}
public Enable (nr : int) : void
{
if (disabled.Contains (nr))
Message.Warning ($"warning N$nr is already explicitly disabled, thus it cannot be enabled");
else {
unless (currently_enabled.Contains (nr))
currently_enabled.Add (nr, null);
unless (enabled.Contains (nr))
enabled.Add (nr, null)
}
}
public Disable (nr : int) : void
{
if (enabled.Contains (nr))
Message.Warning ($"warning N$nr is already explicitly enabled, thus it cannot be disabled");
else {
when (currently_enabled.Contains (nr))
currently_enabled.Remove (nr);
unless (disabled.Contains (nr))
disabled.Add (nr, null)
}
}
levels : array [array [int]] =
array
[
// level 0
array [],
// level 1
array [183, 184, 458, 602, 626, 1633, 1696, 5000, 10010, 10011, 10012, 10013],
// level 2
array [108, 114, 162, 251, 252, 253, 618],
// level 3
array [67, 105, 168, 169, 219],
// level 4
array [28, 78, 109, 402, 628, 649, 10001, 10003, 10005, 10009],
// level 5
array [10002, 10004, 10006, 10007, 10008]
];
public Help : string
{
get
{
def warnings = [
(28, "'function declaration' has the wrong signature to be an entry point"),
(105, "The using directive for 'namespace' appeared previously in this namespace"),
(114, "'f1' hides inherited member 'f2'. To make the current method override that implementation, add the override keyword. Otherwise add the new keyword."),
(168, "The variable 'var' is declared but never used"),
(402, "an entry point cannot be generic or in a generic type"),
(649, "Field 'field' is never assigned to, and will always have its default value 'value"),
(10001, "Cast is unnecessary"),
(10002, "Enable some pedantic checks for illegal characters in input stream"),
(10003, "Other global unused member warnings"),
(10004, "warnings about usage of bit operations on enums without correct attribute"),
(10005, "warnings about ignoring computed values"),
(10006, "`this' is unused, consider making method static"),
(10007, "`$' occurs inside string literal, which is not prefixed itself with `$'"),
(10008, "verify that generic arguments of methods and classes are inferred to some concrete types"),
(10009, "using a constant object reference directly (as first class value)"),
(10010, "compilation options `-debug+' and `-optimize' has poor compatibility: `-debug+' suppresses runtime optimizations"),
(10011, "comparing a value with reference equality"),
];
def sb = StringBuilder ();
foreach ((no, str) in warnings)
{
def loop (lev)
{
if (lev >= levels.Length) ""
else
{
mutable found = false;
foreach (warn in levels [lev])
when (warn == no) found = true;
if (found) $ "[enabled by -warn:$lev]"
else loop (lev + 1)
}
}
def lev = loop (0);
_ = sb.Append ($ "$no\t$str $lev\n");
}
sb.ToString ()
}
}
/* warnings reference:
from C#
0067 - The event 'event' is never used. An event was declared but never
used in the class in which it was declared.
0078 - The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
0108 - The keyword new is required on 'member1' because it hides inherited member 'member2'
0109 - The member 'member' does not hide an inherited member. The new keyword is not required
0162 - Unreachable code detected
0169 - The private field 'class member' is never used
0183 - The given expression is always of the provided ('type') type
0184 - The given expression is never of the provided ('type') type
0219 - The variable 'variable' is assigned but never used
0251 - Indexing an array with a negative index (array indices always start at zero)
0252 - Possible unintended reference comparison; to get a value comparison, cast
the left hand side to type 'type'
0253 - Possible unintended reference comparison; to get a value comparison, cast
the right hand side to type 'type'
0602 - The feature 'old_feature' is deprecated. Please use 'new_feature' instead
0618 - A class member was marked with the Obsolete attribute, such that a warning
will be issued when the class member is referenced.
0626 - Method, operator, or accessor 'method' is marked external and has no
attributes on it. Consider adding a DllImport attribute to specify the external implementation
0628 - 'member' : new protected member declared in sealed class
1633 - unrecognized #pragma directive
...
5000 - Unknown compiler option '/option'
*/
}
/** Match compiler options
*/
public class MatchCompilerOptions
{
[Accessor(flags = WantSetter)]
mutable min_switch_size_for_variants : int;
[Accessor(flags = WantSetter)]
mutable min_switch_size_for_ordinals : int;
public this()
{
Clear();
}
public Clear() : void
{
min_switch_size_for_variants = 12;
min_switch_size_for_ordinals = 4;
}
}
}
Jump to Line
Something went wrong with that request. Please try again.