Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<!-- Disable RUDE OPT-OUT breaking change for entire repo -->
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>

<!--
DO NOT ALLOW Implicit using msbuild feature - EVIL; causes mass issues and frustration moving code between projects when one doesn't
support it or uses a different version. Not to mention hiding the actual namespaces involved, making resolving conflicts HARDER.
Expand Down
2 changes: 1 addition & 1 deletion src/Samples/Kaleidoscope/Chapter8/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System.IO;

namespace Kaleidoscope
namespace Kaleidoscope.Chapter8
{
/// <summary>Command line options for this application</summary>
internal partial class Options
Expand Down
26 changes: 19 additions & 7 deletions src/Samples/Kaleidoscope/Chapter8/Options.g..cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,38 @@

using Ubiquity.NET.CommandLine;

namespace Kaleidoscope
namespace Kaleidoscope.Chapter8
{
internal partial class Options
: IRootCommand<Options>
: ICommandLineOptions<Options>
{
public static Options Bind( ParseResult parseResult )
{
return new()
{
// NOTE: an Argument descriptor does NOT have a "Required" property
// binding to a required value that is NOT present AND has no Default value provider
// will generate an exception. There is no "try" semantics. One could argue that
// anything with a default value provider isn't really required but it depends on perspective.
// Any value that MUST be provided by the user (no default is possible) vs. any value that must
// be used by the consumer (default possible if not provided) are different scenarios and each
// can consider the value as "required" as things can't work without it. (That is, evaluation of
// the term "required" must include a subject [that is, an answer to the "to whom/what?"].
// "required" is a concept that is a dependent term and evaluation without a subject is not possible.)
//
// Source generator should make this CRYSTAL CLEAR.
SourcePath = parseResult.GetRequiredValue( Descriptors.SourceFilePath )
};
}

public static AppControlledDefaultsRootCommand BuildRootCommand( CmdLineSettings? settings )
public static AppControlledDefaultsRootCommand BuildRootCommand( CmdLineSettings settings )
{
return new AppControlledDefaultsRootCommand( "Kaleidoscope sample app", settings )
// description is hard coded and should come from generation attribute on the "Options" type
return new AppControlledDefaultsRootCommand( settings, "Kaleidoscope sample app (Chapter 8)" )
{
Descriptors.SourceFilePath
Descriptors.SourceFilePath,

// Additional Options, Arguments, Sub-commands, and directives go here...
};
}
}
Expand All @@ -38,8 +51,7 @@ file static class Descriptors
internal static readonly Argument<FileInfo> SourceFilePath
= new Argument<FileInfo>("SourceFilePath")
{
Description = "Path of the input source file [Used as ref for debug information]",
HelpName = "Source file path",
Description = "Path of the input source file to compile",
}.AcceptExistingFileOnly();
}
}
7 changes: 5 additions & 2 deletions src/Samples/Kaleidoscope/Chapter8/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

using static Ubiquity.NET.Llvm.Library;

// error CA1506: 'Main' is coupled with '41' different types from '15' different namespaces...
// Total BS. Maybe at the IL level, but hardly true at the source level
#pragma warning disable CA1506

namespace Kaleidoscope.Chapter8
{
public static class Program
Expand Down Expand Up @@ -44,7 +48,6 @@ public static int Main( string[] args )
string irFilePath = Path.ChangeExtension( sourceFilePath, ".ll" );
string asmPath = Path.ChangeExtension( sourceFilePath, ".s" );

using var rdr = File.OpenText( sourceFilePath );
using var libLLVM = InitializeLLVM( );
libLLVM.RegisterTarget( CodeGenTarget.Native );

Expand All @@ -61,7 +64,7 @@ public static int Main( string[] args )

// time the parse and code generation
var timer = System.Diagnostics.Stopwatch.StartNew( );
var ast = parser.Parse( rdr );
var ast = parser.ParseFrom( sourceFilePath );
if(!errorLogger.CheckAndReportParseErrors( ast ))
{
Module? module = generator.Generate( ast );
Expand Down
2 changes: 1 addition & 1 deletion src/Samples/Kaleidoscope/Chapter9/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System.IO;

namespace Kaleidoscope
namespace Kaleidoscope.Chapter9
{
/// <summary>Command line options for this application</summary>
internal partial class Options
Expand Down
26 changes: 19 additions & 7 deletions src/Samples/Kaleidoscope/Chapter9/Options.g..cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,38 @@

using Ubiquity.NET.CommandLine;

namespace Kaleidoscope
namespace Kaleidoscope.Chapter9
{
internal partial class Options
: IRootCommand<Options>
: ICommandLineOptions<Options>
{
public static Options Bind( ParseResult parseResult )
{
return new()
{
// NOTE: an Argument descriptor does NOT have a "Required" property
// binding to a required value that is NOT present AND has no Default value provider
// will generate an exception. There is no "try" semantics. One could argue that
// anything with a default value provider isn't really required but it depends on perspective.
// Any value that MUST be provided by the user (no default is possible) vs. any value that must
// be used by the consumer (default possible if not provided) are different scenarios and each
// can consider the value as "required" as things can't work without it. (That is, evaluation of
// the term "required" must include a subject [that is, an answer to the "to whom/what?"].
// "required" is a concept that is a dependent term and evaluation without a subject is not possible.)
//
// Source generator should make this CRYSTAL CLEAR.
SourcePath = parseResult.GetRequiredValue( Descriptors.SourceFilePath )
};
}

public static AppControlledDefaultsRootCommand BuildRootCommand( CmdLineSettings? settings )
public static AppControlledDefaultsRootCommand BuildRootCommand( CmdLineSettings settings )
{
return new AppControlledDefaultsRootCommand( "Kaleidoscope sample app", settings )
// description is hard coded and should come from generation attribute on the "Options" type
return new AppControlledDefaultsRootCommand( settings, "Kaleidoscope sample app (Chapter 9)" )
{
Descriptors.SourceFilePath
Descriptors.SourceFilePath,

// Additional Options, Arguments, Sub-commands, and directives go here...
};
}
}
Expand All @@ -38,8 +51,7 @@ file static class Descriptors
internal static readonly Argument<FileInfo> SourceFilePath
= new Argument<FileInfo>("SourceFilePath")
{
Description = "Path of the input source file [Used as ref for debug information]",
HelpName = "Source file path",
Description = "Path of the input source file to compile",
}.AcceptExistingFileOnly();
}
}
7 changes: 5 additions & 2 deletions src/Samples/Kaleidoscope/Chapter9/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

using static Ubiquity.NET.Llvm.Library;

// error CA1506: 'Main' is coupled with '41' different types from '15' different namespaces...
// Total BS. Maybe at the IL level, but hardly true at the source level
#pragma warning disable CA1506

namespace Kaleidoscope.Chapter9
{
public static class Program
Expand Down Expand Up @@ -44,7 +48,6 @@ public static int Main( string[] args )
string irFilePath = Path.ChangeExtension( sourceFilePath, ".ll" );
string asmPath = Path.ChangeExtension( sourceFilePath, ".s" );

using var rdr = File.OpenText( sourceFilePath );
using var libLLVM = InitializeLLVM( );
libLLVM.RegisterTarget( CodeGenTarget.Native );

Expand All @@ -61,7 +64,7 @@ public static int Main( string[] args )

// time the parse and code generation
var timer = System.Diagnostics.Stopwatch.StartNew( );
var ast = parser.Parse( rdr );
var ast = parser.ParseFrom( sourceFilePath );
if(!errorLogger.CheckAndReportParseErrors( ast ))
{
Module? module = generator.Generate( ast );
Expand Down
6 changes: 3 additions & 3 deletions src/Samples/Kaleidoscope/Kaleidoscope.Grammar/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ public LanguageLevel LanguageLevel
public DynamicRuntimeState GlobalState { get; }

/// <inheritdoc/>
public IAstNode Parse( string txt )
public IAstNode? Parse( string txt )
{
return Parse( (txt ?? string.Empty).ToCharArray(), ParseMode.ReplLoop );
}

/// <inheritdoc/>
public IAstNode Parse( TextReader reader )
public IAstNode? Parse( TextReader reader )
{
ArgumentNullException.ThrowIfNull( reader );
return Parse( reader.ReadToEnd().ToCharArray(), ParseMode.FullSource );
Expand All @@ -80,7 +80,7 @@ internal enum ParseMode
FullSource
}

private IAstNode Parse( char[] input, ParseMode mode )
private IAstNode? Parse( char[] input, ParseMode mode )
{
try
{
Expand Down
15 changes: 13 additions & 2 deletions src/Ubiquity.NET.CommandLine/AppControlledDefaultsRootCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Ubiquity.NET Contributors. All rights reserved.
// Licensed under the Apache-2.0 WITH LLVM-exception license. See the LICENSE.md file in the project root for full license information.

using System;
using System.CommandLine;
using System.CommandLine.Help;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -9,17 +10,27 @@
namespace Ubiquity.NET.CommandLine
{
/// <summary>Extension of <see cref="RootCommand"/> that allows app control of defaults that are otherwise forced</summary>
/// <remarks>
/// This type is derived from <see cref="RootCommand"/> and offers no additional behavior beyond the construction.
/// The constructor will adapt the command based on the <see cref="CmdLineSettings"/> provided. This moves the
/// hard coded defaults into an app controlled domain. The default constructed settings matches the behavior of
/// <see cref="RootCommand"/> so there's no distinction. This allows an application to explicitly decide the behavior
/// and support of various defaults that could otherwise surprise the author/user. This is especially important when
/// replacing the internal command line handling of a published app or otherwise creating a "drop-in" replacement. In
/// such cases, strict adherence to back-compat is of paramount importance and the addition of default behavior is
/// potentially a breaking change.
/// </remarks>
[SuppressMessage( "Design", "CA1010:Generic interface should also be implemented", Justification = "Collection initialization" )]
public class AppControlledDefaultsRootCommand
: RootCommand
{
/// <summary>Initializes a new instance of the <see cref="AppControlledDefaultsRootCommand"/> class.</summary>
/// <param name="description">Description of this root command</param>
/// <param name="settings">Settings to apply for the command parsing</param>
public AppControlledDefaultsRootCommand( string description = "", CmdLineSettings? settings = null )
public AppControlledDefaultsRootCommand( CmdLineSettings settings, string description = "" )
: base( description )
{
settings ??= new CmdLineSettings();
ArgumentNullException.ThrowIfNull(settings);

// RootCommand constructor already adds HelpOption and VersionOption so remove them
// unless specified by caller.
Expand Down
Loading
Loading