Skip to content

Commit

Permalink
Support for implementation specific options using -X (#254)
Browse files Browse the repository at this point in the history
* Update .editorconfig

* Make PrintUsage/PrintVersion virtual

* Add implementation-specific options

* Check that val is set

* Make PrintLanguageHelp virtual

* Remove UseImplementationSpecificOptions handling

* Note unparsed options

* Do SaveAssemblies in HandleImplementationSpecificOption
  • Loading branch information
slozier authored Sep 6, 2021
1 parent 7c13c7a commit 13681b7
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 62 deletions.
26 changes: 26 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ csharp_new_line_before_catch = false
csharp_new_line_before_finally = false
csharp_space_after_keywords_in_control_flow_statements = true

csharp_style_prefer_index_operator = false
csharp_style_prefer_range_operator = false

dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = true

# use language keywords instead of BCL types
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
Expand All @@ -38,7 +44,11 @@ csharp_preferred_modifier_order = public, private, protected, internal, static,
dotnet_analyzer_diagnostic.severity = warning
dotnet_analyzer_diagnostic.category-style.severity = default

dotnet_diagnostic.CA1000.severity = none # CA1000: Do not declare static members on generic types
dotnet_diagnostic.CA1001.severity = suggestion # CA1001: Types that own disposable fields should be disposable
dotnet_diagnostic.CA1010.severity = suggestion # CA1010: Generic interface should also be implemented
dotnet_diagnostic.CA1018.severity = suggestion # CA1018: Mark attributes with AttributeUsageAttribute
dotnet_diagnostic.CA1036.severity = suggestion # CA1036: Override methods on comparable types
dotnet_diagnostic.CA1051.severity = none # CA1051: Do not declare visible instance fields
dotnet_diagnostic.CA1069.severity = suggestion # CA1069: Enums values should not be duplicated
dotnet_diagnostic.CA1200.severity = suggestion # CA1200: Avoid using cref tags with a prefix
Expand All @@ -47,20 +57,36 @@ dotnet_diagnostic.CA1305.severity = none # CA1305: Specify IFormatProvide
dotnet_diagnostic.CA1307.severity = suggestion # CA1307: Specify StringComparison for clarity
dotnet_diagnostic.CA1309.severity = suggestion # CA1309: Use ordinal string comparison
dotnet_diagnostic.CA1310.severity = warning # CA1310: Specify StringComparison for correctness
dotnet_diagnostic.CA1707.severity = none # CA1707: Identifiers should not contain underscores
dotnet_diagnostic.CA1708.severity = none # CA1708: Identifiers should differ by more than case
dotnet_diagnostic.CA1710.severity = none # CA1710: Identifiers should have correct suffix
dotnet_diagnostic.CA1711.severity = none # CA1711: Identifiers should not have incorrect suffix
dotnet_diagnostic.CA1712.severity = none # CA1712: Do not prefix enum values with type name
dotnet_diagnostic.CA1715.severity = none # CA1715: Identifiers should have correct prefix
dotnet_diagnostic.CA1716.severity = none # CA1716: Identifiers should not match keywords
dotnet_diagnostic.CA1720.severity = none # CA1720: Identifier contains type name
dotnet_diagnostic.CA1725.severity = suggestion # CA1725: Parameter names should match base declaration
dotnet_diagnostic.CA1805.severity = suggestion # CA1805: Do not initialize unnecessarily
dotnet_diagnostic.CA1806.severity = none # CA1806: Do not ignore method results
dotnet_diagnostic.CA1816.severity = suggestion # CA1816: Dispose methods should call SuppressFinalize
dotnet_diagnostic.CA1822.severity = none # CA1822: Mark members as static
dotnet_diagnostic.CA1825.severity = none # CA1825: Avoid zero-length array allocations
dotnet_diagnostic.CA1830.severity = suggestion # CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder
dotnet_diagnostic.CA1834.severity = suggestion # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1837.severity = suggestion # CA1837: Use 'Environment.ProcessId'
dotnet_diagnostic.CA1838.severity = suggestion # CA1838: Avoid 'StringBuilder' parameters for P/Invokes
dotnet_diagnostic.CA1845.severity = none # CA1845: Use span-based 'string.Concat'
dotnet_diagnostic.CA1846.severity = none # CA1846: Prefer 'AsSpan' over 'Substring'
dotnet_diagnostic.CA1847.severity = none # CA1847: Use char literal for a single character lookup
dotnet_diagnostic.CA2101.severity = suggestion # CA2101: Specify marshaling for P/Invoke string arguments
dotnet_diagnostic.CA2201.severity = none # CA2201: Do not raise reserved exception types
dotnet_diagnostic.CA2208.severity = suggestion # CA2208: Instantiate argument exceptions correctly
dotnet_diagnostic.CA2211.severity = none # CA2211: Non-constant fields should not be visible
dotnet_diagnostic.CA2219.severity = suggestion # CA2219: Do not raise exceptions in finally clauses
dotnet_diagnostic.CA2229.severity = suggestion # CA2229: Implement serialization constructors
dotnet_diagnostic.CA2249.severity = suggestion # CA2249: Consider using 'string.Contains' instead of 'string.IndexOf'
dotnet_diagnostic.CA3075.severity = suggestion # CA3075: Insecure DTD processing in XML
dotnet_diagnostic.CA5350.severity = suggestion # CA5350: Do Not Use Weak Cryptographic Algorithms
dotnet_diagnostic.CA5351.severity = suggestion # CA5351: Do Not Use Broken Cryptographic Algorithms
dotnet_diagnostic.CA5359.severity = suggestion # CA5359: Do Not Disable Certificate Validation
dotnet_diagnostic.CA5372.severity = suggestion # CA5372: Use XmlReader For XPathDocument
10 changes: 5 additions & 5 deletions Src/Microsoft.Dynamic/Hosting/Shell/ConsoleHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ protected virtual string GetHelp() {
return sb.ToString();
}

public void PrintLanguageHelp(StringBuilder output) {
public virtual void PrintLanguageHelp(StringBuilder output) {
ContractUtils.RequiresNotNull(output, nameof(output));

CreateOptionsParser().GetHelp(out string commandLine, out string[,] options, out string[,] environmentVariables, out string comments);
Expand Down Expand Up @@ -300,7 +300,7 @@ private void Execute() {
protected virtual void ExecuteInternal() {
Debug.Assert(_engine != null);

if (_consoleOptions.PrintVersion){
if (_consoleOptions.PrintVersion) {
PrintVersion();
}

Expand Down Expand Up @@ -409,15 +409,15 @@ private int RunCommandLine() {
return exitCodeOverride.Value;
}

private void PrintUsage()
protected virtual void PrintUsage()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Usage: {0}.exe ", ExeName);
PrintLanguageHelp(sb);
Console.Write(sb.ToString());
}

protected void PrintVersion() {
protected virtual void PrintVersion() {
Console.WriteLine("{0} {1} on {2}", Engine.Setup.DisplayName, Engine.LanguageVersion, GetRuntime());
}

Expand Down Expand Up @@ -448,4 +448,4 @@ protected static void PrintException(TextWriter output, Exception e) {
}
}

#endif
#endif
156 changes: 103 additions & 53 deletions Src/Microsoft.Dynamic/Hosting/Shell/OptionsParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;

using Microsoft.Scripting.Generation;
Expand Down Expand Up @@ -49,13 +48,13 @@ public PlatformAdaptationLayer Platform {
}

#if FEATURE_FULL_CONSOLE
public abstract ConsoleOptions CommonConsoleOptions {
get;
public abstract ConsoleOptions CommonConsoleOptions {
get;
}
#endif
public IList<string> IgnoredArgs {
get { return _ignoredArgs; }
}
}

/// <exception cref="InvalidOptionException">On error.</exception>
public void Parse(string[] args, ScriptRuntimeSetup setup, LanguageSetup languageSetup, PlatformAdaptationLayer platform) {
Expand Down Expand Up @@ -109,11 +108,7 @@ protected string PeekNextArg() {
if (_current < _args.Length)
return _args[_current];

throw new InvalidOptionException(
String.Format(
CultureInfo.CurrentCulture,
"Argument expected for the {0} option.",
_current > 0 ? _args[_current - 1] : string.Empty));
throw new InvalidOptionException($"Argument expected for the {(_current > 0 ? _args[_current - 1] : string.Empty)} option.");
}

protected string PopNextArg() {
Expand All @@ -137,10 +132,10 @@ protected static Exception InvalidOptionValue(string option, string value) {
#if FEATURE_FULL_CONSOLE
public class OptionsParser<TConsoleOptions> : OptionsParser
where TConsoleOptions : ConsoleOptions, new() {

private TConsoleOptions _consoleOptions;

#if FEATURE_REFEMIT
#if FEATURE_REFEMIT && DEBUG
private bool _saveAssemblies = false;
private string _assembliesDir = null;
#endif
Expand All @@ -149,13 +144,13 @@ public TConsoleOptions ConsoleOptions {
get {
if (_consoleOptions == null) {
_consoleOptions = new TConsoleOptions();
}
return _consoleOptions;
}

return _consoleOptions;
}
set {
ContractUtils.RequiresNotNull(value, nameof(value));
_consoleOptions = value;
_consoleOptions = value;
}
}

Expand All @@ -178,73 +173,129 @@ protected override void ParseArgument(string arg) {
IgnoreRemainingArgs();
break;

case "-D":
RuntimeSetup.DebugMode = true;
case "-D":
RuntimeSetup.DebugMode = true;
break;

case "-X:PrivateBinding":
case "-X:PassExceptions":
// TODO: #if !IRONPYTHON_WINDOW
case "-X:ColorfulConsole":
case "-X:TabCompletion":
case "-X:AutoIndent":
// #endif
#if DEBUG
#if FEATURE_REFEMIT
case "-X:SaveAssemblies":
#endif
case "-X:TrackPerformance":
#endif
case "-X:Interpret":
case "-X:NoAdaptiveCompilation":
case "-X:ExceptionDetail":
case "-X:ShowClrExceptions":
#if DEBUG
case "-X:PerfStats":
#endif
HandleImplementationSpecificOption(arg.Substring(3), null);
break;

#if DEBUG && FEATURE_REFEMIT
case "-X:AssembliesDir":
#endif
case "-X:CompilationThreshold":
#if FEATURE_REMOTING
case "-X:" + Remote.RemoteRuntimeServer.RemoteRuntimeArg:
#endif
HandleImplementationSpecificOption(arg.Substring(3), PopNextArg());
break;

default:
ConsoleOptions.FileName = arg.Trim();
break;
}
}

protected virtual void HandleImplementationSpecificOption(string arg, string val) {
switch (arg) {
case "PrivateBinding":
RuntimeSetup.PrivateBinding = true;
break;
case "-X:PrivateBinding":
RuntimeSetup.PrivateBinding = true;

case "PassExceptions":
ConsoleOptions.HandleExceptions = false;
break;

case "-X:PassExceptions": ConsoleOptions.HandleExceptions = false; break;
// TODO: #if !IRONPYTHON_WINDOW
case "-X:ColorfulConsole": ConsoleOptions.ColorfulConsole = true; break;
case "-X:TabCompletion": ConsoleOptions.TabCompletion = true; break;
case "-X:AutoIndent": ConsoleOptions.AutoIndent = true; break;

case "ColorfulConsole":
ConsoleOptions.ColorfulConsole = true;
break;

case "TabCompletion":
ConsoleOptions.TabCompletion = true;
break;

case "AutoIndent":
ConsoleOptions.AutoIndent = true;
break;

//#endif

#if DEBUG
#if FEATURE_REFEMIT
case "-X:AssembliesDir":
_assembliesDir = PopNextArg();

case "AssembliesDir":
if (string.IsNullOrEmpty(val)) throw new InvalidOptionException($"Argument expected for the -X:{arg} option.");
_assembliesDir = val;
if (_saveAssemblies) {
Snippets.SetSaveAssemblies(true, _assembliesDir);
}
break;

case "-X:SaveAssemblies":
case "SaveAssemblies":
_saveAssemblies = true;
Snippets.SetSaveAssemblies(true, _assembliesDir);
break;
#endif

case "-X:TrackPerformance":
SetDlrOption(arg.Substring(3));
case "TrackPerformance":
SetDlrOption(arg);
break;
#endif

// TODO: remove
case "-X:Interpret":
case "Interpret":
LanguageSetup.Options["InterpretedMode"] = ScriptingRuntimeHelpers.True;
break;

case "-X:NoAdaptiveCompilation":
case "NoAdaptiveCompilation":
LanguageSetup.Options["NoAdaptiveCompilation"] = true;
break;

case "-X:CompilationThreshold":
LanguageSetup.Options["CompilationThreshold"] = Int32.Parse(PopNextArg());
case "CompilationThreshold":
int threshold;
if (!int.TryParse(val, out threshold)) {
throw new InvalidOptionException($"The argument for the -X:{arg} option must be an integer.");
}
LanguageSetup.Options["CompilationThreshold"] = threshold;
break;

case "-X:ExceptionDetail":
case "-X:ShowClrExceptions":
case "ExceptionDetail":
case "ShowClrExceptions":
#if DEBUG
case "-X:PerfStats":
case "PerfStats":
#endif
// TODO: separate options dictionary?
LanguageSetup.Options[arg.Substring(3)] = ScriptingRuntimeHelpers.True;
LanguageSetup.Options[arg] = ScriptingRuntimeHelpers.True;
break;

#if FEATURE_REMOTING
case Remote.RemoteRuntimeServer.RemoteRuntimeArg:
ConsoleOptions.RemoteRuntimeChannel = PopNextArg();
if (string.IsNullOrEmpty(val)) throw new InvalidOptionException($"Argument expected for the -X:{arg} option.");
ConsoleOptions.RemoteRuntimeChannel = val;
break;
#endif
default:
ConsoleOptions.FileName = arg.Trim();
break;
}

#if FEATURE_REFEMIT
if (_saveAssemblies) {
Snippets.SetSaveAssemblies(true, _assembliesDir);
}
#endif
}

internal static void SetDlrOption(string option) {
Expand All @@ -259,14 +310,13 @@ internal static void SetDlrOption(string option, string value) {

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional")] // TODO: fix
public override void GetHelp(out string commandLine, out string[,] options, out string[,] environmentVariables, out string comments) {

commandLine = "[options] [file|- [arguments]]";

options = new string[,] {
{ "-c cmd", "Program passed in as string (terminates option list)" },
{ "-h", "Display usage" },
{ "-i", "Inspect interactively after running script" },
{ "-V", "Print the version number and exit" },
{ "-i", "Inspect interactively after running script" }, // TODO: remove this? not handled by OptionsParser.ParseArgument
{ "-V", "Print the version number and exit" }, // TODO: remove this? not handled by OptionsParser.ParseArgument
{ "-D", "Enable application debugging" },

{ "-X:AutoIndent", "Enable auto-indenting in the REPL loop" },
Expand All @@ -284,11 +334,11 @@ public override void GetHelp(out string commandLine, out string[,] options, out
{ "-X:TrackPerformance", "Track performance sensitive areas [debug only]" },
{ "-X:PerfStats", "Print performance stats when the process exists [debug only]" },
#if FEATURE_REMOTING
{ Remote.RemoteRuntimeServer.RemoteRuntimeArg + " <channel_name>",
{ $"-X:{Remote.RemoteRuntimeServer.RemoteRuntimeArg} <channel_name>",
"Start a remoting server for a remote console session." },
#endif
#endif
};
};

environmentVariables = new string[0, 0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private static string GetChannelName() {

private ProcessStartInfo GetProcessStartInfo() {
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Arguments = RemoteRuntimeServer.RemoteRuntimeArg + " " + _channelName;
processInfo.Arguments = "-X:" + RemoteRuntimeServer.RemoteRuntimeArg + " " + _channelName;
processInfo.CreateNoWindow = true;

// Set UseShellExecute to false to enable redirection.
Expand Down Expand Up @@ -271,4 +271,4 @@ protected RemoteRuntimeStartupException(SerializationInfo info, StreamingContext
}
}

#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft.Scripting.Hosting.Shell.Remote {
/// </summary>
public static class RemoteRuntimeServer {
internal const string CommandDispatcherUri = "CommandDispatcherUri";
internal const string RemoteRuntimeArg = "-X:RemoteRuntimeChannel";
internal const string RemoteRuntimeArg = "RemoteRuntimeChannel";

private static TimeSpan GetSevenDays() {
return new TimeSpan(7, 0, 0, 0); // days,hours,mins,secs
Expand Down Expand Up @@ -81,4 +81,4 @@ internal static void StartServer(string remoteRuntimeChannelName, ScriptScope sc
}
}

#endif
#endif

0 comments on commit 13681b7

Please sign in to comment.