diff --git a/Directory.Packages.props b/Directory.Packages.props
index 1351bbb22..a70281288 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -49,8 +49,14 @@
-
+
+
+
+
+
+
+
diff --git a/docfx/CommandLine/api/index.md b/docfx/CommandLine/api/index.md
deleted file mode 100644
index 6de856d79..000000000
--- a/docfx/CommandLine/api/index.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# About
-`Ubiquity.NET.CommandLine` contains general extensions for .NET. to support command line
-parsing using `System.CommandLine`
diff --git a/docfx/CommandLine/index.md b/docfx/CommandLine/index.md
deleted file mode 100644
index e35c04e85..000000000
--- a/docfx/CommandLine/index.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# About
-Ubiquity.NET.CommandLine contains general extensions for .NET. to support command line
-parsing using `System.CommandLine`
diff --git a/docfx/CommandLine/toc.yml b/docfx/CommandLine/toc.yml
deleted file mode 100644
index 1963d8b3d..000000000
--- a/docfx/CommandLine/toc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# TOC (Left nav) for the 'CommandLine' folder
-- name: Overview
- href: index.md
-- name: Namespaces
- href: api/toc.yml
diff --git a/docfx/SrcGeneration/api/index.md b/docfx/SrcGeneration/api/index.md
deleted file mode 100644
index 832948997..000000000
--- a/docfx/SrcGeneration/api/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Ubiquity.NET.SrcGeneration
-This library contains support functionality to aid in building a source generator.
-This library is multi-targetting to allow consumption from a Roslyn source generator
-or VSIX project. Other uses should leverage the modern runtimes but those cases
-***MUST*** target only `.NET Standard 2.0`
-
diff --git a/docfx/SrcGeneration/index.md b/docfx/SrcGeneration/index.md
deleted file mode 100644
index 832948997..000000000
--- a/docfx/SrcGeneration/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Ubiquity.NET.SrcGeneration
-This library contains support functionality to aid in building a source generator.
-This library is multi-targetting to allow consumption from a Roslyn source generator
-or VSIX project. Other uses should leverage the modern runtimes but those cases
-***MUST*** target only `.NET Standard 2.0`
-
diff --git a/docfx/SrcGeneration/toc.yml b/docfx/SrcGeneration/toc.yml
deleted file mode 100644
index c6a728a53..000000000
--- a/docfx/SrcGeneration/toc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# TOC (Left nav) for SrcGeneration folder
-- name: Overview
- href: index.md
-- name: Namespaces
- href: api/toc.yml
diff --git a/docfx/antlr-utils/api/.gitignore b/docfx/antlr-utils/api/.gitignore
deleted file mode 100644
index e8079a3be..000000000
--- a/docfx/antlr-utils/api/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-###############
-# temp file #
-###############
-*.yml
-.manifest
diff --git a/docfx/antlr-utils/api/index.md b/docfx/antlr-utils/api/index.md
deleted file mode 100644
index ff7b78337..000000000
--- a/docfx/antlr-utils/api/index.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Ubiquity.NET.ANTLR.Utils
-This namespace supports all of extensions to support use of ANTLR as a parsing engine.
diff --git a/docfx/antlr-utils/index.md b/docfx/antlr-utils/index.md
deleted file mode 100644
index 45b94f0a8..000000000
--- a/docfx/antlr-utils/index.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# About
-This library provides general extensions to ANTLR including adapter bindings
-for the Ubiquity.NET.Runtime library.
-
-# Key usage
-* Get a SourceLocation from various ANTLR types (rule,tokens,terminals)
- - This provides an adaptation to the abstract SourceLocation
-* Debug trace listener
- - Provides debug TRACE support for any parser by listening for every rule and using
- Debug.Trace() to generate a string representation of that rule. This is VERY useful
- when developing or debugging a grammar.
-* Adapter for parse error listeners to a unified and abstract
- `Ubiquity.NET.Runtime.IParseErrorListener`.
- - This allows building consumers that deal with errors and remain independent of the
- parsing technology.
-* Extension functions that provides commonly used support for ANTLR
- - Get a character interval from a ParserRuleContext with support for the standard EOF
- rule.
- - Get the source stream from an IRecognizer
- - Get the source text from a rule context and recognizer that produced it.
- - Get source text from a rule context and stream that it was parsed from.
- - Get a unique ID for a parse tree
- * Useful for building graphs of the result of parsing as many graphing representations
- require a unique node id for every node in the graph.
diff --git a/docfx/antlr-utils/toc.yml b/docfx/antlr-utils/toc.yml
deleted file mode 100644
index d5dad6106..000000000
--- a/docfx/antlr-utils/toc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# TOC (Left nav) for antly-utils folder
-- name: Overview
- href: index.md
-- name: Namespaces
- href: api/toc.yml
diff --git a/docfx/docfx.json b/docfx/docfx.json
index d0cdf9eb2..32bd670e1 100644
--- a/docfx/docfx.json
+++ b/docfx/docfx.json
@@ -11,64 +11,9 @@
// warnings and returns a non-success value which stops the build.
// Each project is listed in the order they appear in the VS solution explorer so they are easier
// to find and check etc...
- {
- // Interop helpers library
- "memberLayout": "separatePages",
- "namespaceLayout": "nested",
- "src": [
- {
- "src": "../src/Ubiquity.NET.InteropHelpers",
- "files": [ "**.csproj" ]
- }
- ],
- "dest": "interop-helpers/api"
- },
+ //
// NOTE: Ubiquity.NET.Llvm.Interop is intentionally NOT documented (It's considered an implementation detail)
// NOTE: Sample projects are not generating docs, they are... samples 8^)
- {
- // ANTLR Utilities library
- "memberLayout": "separatePages",
- "namespaceLayout": "nested",
- "src": [
- {
- "src": "../src/Ubiquity.NET.ANTLR.Utils",
- "files": [ "**.csproj" ]
- }
- ],
- "dest": "antlr-utils/api"
- },
- {
- // ANTLR Utilities library
- "memberLayout": "separatePages",
- "namespaceLayout": "nested",
- "src": [
- {
- "src": "../src/Ubiquity.NET.CommandLine",
- "files": [ "**.csproj" ]
- }
- ],
- "dest": "CommandLine/api"
- },
- {
- // Extensions library
- "memberLayout": "separatePages",
- "namespaceLayout": "nested",
- "src": [
- {
- "src": "../src/Ubiquity.NET.Extensions",
- "files": [ "**.csproj" ]
- }
- ],
- "dest": "extensions/api",
- "properties": {
- // use .NET 8.0 for the TFM as it is multi-targeting
- // Sadly, DocFX can't find the dependent project builds if this is .NET 9.0
- // and then generates warnings as a result. (DocFX metadata generation is
- // pretty well borked and needs replacement as there are a LOT of workarounds
- // in this project let alone all the ones found on-line.)
- "TargetFramework": "net8.0"
- }
- },
{
// LLVM OO Wrappers library
"memberLayout": "separatePages",
@@ -80,38 +25,6 @@
}
],
"dest": "llvm/api"
- },
- {
- // Runtime utilities library
- "memberLayout": "separatePages",
- "namespaceLayout": "nested",
- "src": [
- {
- "src": "../src/Ubiquity.NET.Runtime.Utils",
- "files": [ "**.csproj" ]
- }
- ],
- "dest": "runtime-utils/api",
- },
- {
- // SrcGeneration library
- "memberLayout": "separatePages",
- "namespaceLayout": "nested",
- "src": [
- {
- "src": "../src/Ubiquity.NET.SrcGeneration",
- "files": [ "**.csproj" ]
- }
- ],
- "dest": "SrcGeneration/api",
- "properties": {
- // use .NET 8.0 for the TFM as it is multi-targeting
- // Sadly, DocFX can't find the dependent project builds if this is .NET 9.0
- // and then generates warnings as a result. (DocFX metadata generation is
- // pretty well borked and needs replacement as there are a LOT of workarounds
- // in this project let alone all the ones found on-line.)
- "TargetFramework": "net8.0"
- }
}
],
"build": {
@@ -129,17 +42,6 @@
"toc.yml"
]
},
- {
- // InteropHelpers project additional content, Includes the generated metadata API folder
- "files": [
- "interop-helpers/**.{md,yml}"
- ],
- // Exclude the namespace overwrites and XREF maps as they are listed explicitly elsewhere
- "exclude": [
- "**/namespaces/**.md",
- "**/*-xref.yml"
- ]
- },
{
// Pull in the LLVM samples as content. The LLVM core project is more complex in the docfx.json as it
// includes the samples but they are NOT participating in metadata generation. They only contribute
@@ -159,39 +61,6 @@
"**/ReadMe.md"
]
},
- {
- // ANTLR Utils project additional content, Includes the generated metadata API folder
- "files": [
- "antlr-utils/**.{md,yml}"
- ],
- // Exclude the namespace overwrites and XREF maps as they are listed explicitly elsewhere
- "exclude": [
- "**/namespaces/**.md",
- "**/*-xref.yml"
- ]
- },
- {
- // CommandLine Utils project additional content, Includes the generated metadata API folder
- "files": [
- "CommandLine/**.{md,yml}"
- ],
- // Exclude the namespace overwrites and XREF maps as they are listed explicitly elsewhere
- "exclude": [
- "**/namespaces/**.md",
- "**/*-xref.yml"
- ]
- },
- {
- // extensions project additional content, Includes the generated metadata API folder
- "files": [
- "extensions/**.{md,yml}"
- ],
- // Exclude the namespace overwrites and XREF maps as they are listed explicitly elsewhere
- "exclude": [
- "**/namespaces/**.md",
- "**/*-xref.yml"
- ]
- },
{
// LLVM project additional content, Includes the generated metadata API folder
"files": [
@@ -202,30 +71,6 @@
"**/namespaces/**.md",
"**/*-xref.yml"
]
- },
- {
- // Runtime Utils project additional content, Includes the generated metadata API folder
- // NOTE: File paths are relative to the location of this file
- "files": [
- "runtime-utils/**.{md,yml}"
- ],
- // Exclude the namespace overwrites and XREF maps as they are listed explicitly elsewhere
- "exclude": [
- "**/namespaces/**.md",
- "**/*-xref.yml"
- ]
- },
- {
- // SrcGenerations project additional content, Includes the generated metadata API folder
- // NOTE: File paths are relative to the location of this file
- "files": [
- "SrcGeneration/**.{md,yml}"
- ],
- // Exclude the namespace overwrites and XREF maps as they are listed explicitly elsewhere
- "exclude": [
- "**/namespaces/**.md",
- "**/*-xref.yml"
- ]
}
],
"resource": [
diff --git a/docfx/documentation.msbuildproj b/docfx/documentation.msbuildproj
index b187f8d38..ff7692251 100644
--- a/docfx/documentation.msbuildproj
+++ b/docfx/documentation.msbuildproj
@@ -33,25 +33,21 @@
-
-
-
-
@@ -62,16 +58,12 @@
-
-
-
-
diff --git a/docfx/extensions/api/.gitignore b/docfx/extensions/api/.gitignore
deleted file mode 100644
index e8079a3be..000000000
--- a/docfx/extensions/api/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-###############
-# temp file #
-###############
-*.yml
-.manifest
diff --git a/docfx/extensions/api/index.md b/docfx/extensions/api/index.md
deleted file mode 100644
index 7e6c50857..000000000
--- a/docfx/extensions/api/index.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# About
-Ubiquity.NET.Extensions contains general extensions for .NET. This is
-a bit of a [grab bag](https://www.merriam-webster.com/dictionary/grab%20bag) of
-functionality used by but not actually part of multiple other Ubiquity.NET projects.
-
-## Key support
-* Computing a hash code for a ReadOnlySpan of bytes using
- [System.IO.System.IO.Hashing.XxHash3](https://learn.microsoft.com/en-us/dotnet/api/system.io.hashing.xxhash3)
-* DisposableAction for building actions that must occur on Dispose
- - This is useful for implementing the RAII pattern in .NET.
-* MustUseReturnValueAttribute that is compatible with the [MustUseRetVal](https://github.com/mykolav/must-use-ret-val-fs)
- package.
-* StringNormalizer extensions to support converting line endings of strings for
- interoperability.
-* Fluent style parameter value validation extensions.
- - These are useful when passing parameters to a function that produces a result that is
- fed to the base constructor. These are also useful in body expressions to validate
- input parameters.
-* DictionaryBuilder to enable dictionary initializer style initialization of
- `ImmutableDictionary` with significantly reduced overhead.
- - This leverages an `ImmutableDictionary.Builder` under the hood to build
- the dictionary. When the `ToImmutable()` method is called the builder is converted to
- the immutable state without any overhead of a copy or re-construction of hash tables
- etc...
-* KvpArrayBuilder to enable array initializer style initialization of
- `ImmutableArray>` with significantly reduced overhead.
- - This leverages an `ImmutableArray.Builder` under the hood to build the array
- directly. When the `ToImmutable()` method is called the builder is converted to the
- immutable state without any overhead of a copy.
- - Since this is an array and not a dictionary there is no overhead for allocating,
- initializing or copying any hash mapping for the keys.
-
diff --git a/docfx/extensions/index.md b/docfx/extensions/index.md
deleted file mode 100644
index 7e6c50857..000000000
--- a/docfx/extensions/index.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# About
-Ubiquity.NET.Extensions contains general extensions for .NET. This is
-a bit of a [grab bag](https://www.merriam-webster.com/dictionary/grab%20bag) of
-functionality used by but not actually part of multiple other Ubiquity.NET projects.
-
-## Key support
-* Computing a hash code for a ReadOnlySpan of bytes using
- [System.IO.System.IO.Hashing.XxHash3](https://learn.microsoft.com/en-us/dotnet/api/system.io.hashing.xxhash3)
-* DisposableAction for building actions that must occur on Dispose
- - This is useful for implementing the RAII pattern in .NET.
-* MustUseReturnValueAttribute that is compatible with the [MustUseRetVal](https://github.com/mykolav/must-use-ret-val-fs)
- package.
-* StringNormalizer extensions to support converting line endings of strings for
- interoperability.
-* Fluent style parameter value validation extensions.
- - These are useful when passing parameters to a function that produces a result that is
- fed to the base constructor. These are also useful in body expressions to validate
- input parameters.
-* DictionaryBuilder to enable dictionary initializer style initialization of
- `ImmutableDictionary` with significantly reduced overhead.
- - This leverages an `ImmutableDictionary.Builder` under the hood to build
- the dictionary. When the `ToImmutable()` method is called the builder is converted to
- the immutable state without any overhead of a copy or re-construction of hash tables
- etc...
-* KvpArrayBuilder to enable array initializer style initialization of
- `ImmutableArray>` with significantly reduced overhead.
- - This leverages an `ImmutableArray.Builder` under the hood to build the array
- directly. When the `ToImmutable()` method is called the builder is converted to the
- immutable state without any overhead of a copy.
- - Since this is an array and not a dictionary there is no overhead for allocating,
- initializing or copying any hash mapping for the keys.
-
diff --git a/docfx/extensions/toc.yml b/docfx/extensions/toc.yml
deleted file mode 100644
index 262c8b726..000000000
--- a/docfx/extensions/toc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# TOC (Left nav) for the 'extensions' folder
-- name: Overview
- href: index.md
-- name: Namespaces
- href: api/toc.yml
diff --git a/docfx/index.md b/docfx/index.md
index 1883d63d1..9b8d79b74 100644
--- a/docfx/index.md
+++ b/docfx/index.md
@@ -5,15 +5,14 @@ are rather close. In the mean time this set of libraries provides the building b
for creating a Domain Specific Language (DSL) implementation or custom language compiler,
including JIT execution. Several useful generalized libraries are also included.
-## The Libraries in this repository
-(At least the ones generating docs at this point anyway! :grin:)
+## The Libraries[1](#footnote_1) in this repository
| Library | Description |
|---------|-------------|
-| [Ubiquity.NET.Antlr.Utils](antlr-utils/index.md) | This library contains extensions and helpers for using ANTLR with .NET |
-| [Ubiquity.NET.CommandLine](CommandLine/index.md) | This library contains extensions and helpers for command line parsing via `System.CommandLine` |
-| [Ubiquity.NET.Extensions](extensions/index.md) | This library contains general extensions and helpers for many scenarios using .NET |
| [Ubiquity.NET.Llvm](llvm/index.md) | This library contains The core of the LLVM projection to .NET |
-| [Ubiquity.NET.Runtime.Utils](runtime-utils/index.md) | This library contains common support for DSL runtime and language implementors |
-| [Ubiquity.NET.InteropHelpers](interop-helpers/index.md) | This library contains extensions and helpers for implementing interop support for native libraries |
-| [Ubiquity.NET.SrcGeneration](SrcGeneration/index.md) | This library contains extensions and helpers for implementing source generators |
+
+---
+1 The Ubiquity.NET.Llvm.Interop is intentionally NOT documented. It is an internal
+implementation detail subject to change in the future. There are plans to merge it with the
+OO wrapper library. Therefore, applications should NOT depend on it as it is likely to cease
+existing in the future.
diff --git a/docfx/interop-helpers/api/.gitignore b/docfx/interop-helpers/api/.gitignore
deleted file mode 100644
index e8079a3be..000000000
--- a/docfx/interop-helpers/api/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-###############
-# temp file #
-###############
-*.yml
-.manifest
diff --git a/docfx/interop-helpers/api/index.md b/docfx/interop-helpers/api/index.md
deleted file mode 100644
index dbfea6c2f..000000000
--- a/docfx/interop-helpers/api/index.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# About
-`Ubiquity.NET.InteropHelpers` helper support common to low level interop libraries. While
-this library is intended to support the Ubiquity.NET.Llvm interop requirements there isn't
-anything bound to that library in the support here. That is it is independent and a useful
-library for any code base providing interop support.
-
-# Key Features
-* String handling
- * A lot of interop deals with strings in some form or another and handling them is a
- major amount of effort for most interop libraries. The support provided here enables
- lazy evaluation/marshalling and encoding of native strings and managed strings. These
- allow a simple `byte[]` to store a native string and ONLY marshals to a UTF16 managed
- string once when needed. This allows storing and passing strings in their native form
- for FAST retrieval from a native call and then providing that same string as an `in`
- parameter in another call. All without the need to marshal from native and then back
- again just for the call. This is a MAJOR performance enhancement for APIs that deal in
- strings.
-* Delegates and NativeCallbacks as Function pointers
- * Function pointers are a new feature of C# that makes for very high performance interop
- scenarios. However, sometimes the callback for a function pointer actually needs
- additional data not part of the parameters of the function to work properly. This
- library provides support for such scenarios where a delegate is used to "capture" the
- data while still supporting AOT scenarios. (NOTE: `Marshal.GetFunctionPointerForDelegate()`
- must dynamically emit a thunk that contains the proper signature and the captured
- "this" pointer so is NOT AOT friendly) The support offered in this library, though a
- bit more tedious, is AOT friendly.
-
diff --git a/docfx/interop-helpers/index.md b/docfx/interop-helpers/index.md
deleted file mode 100644
index dbfea6c2f..000000000
--- a/docfx/interop-helpers/index.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# About
-`Ubiquity.NET.InteropHelpers` helper support common to low level interop libraries. While
-this library is intended to support the Ubiquity.NET.Llvm interop requirements there isn't
-anything bound to that library in the support here. That is it is independent and a useful
-library for any code base providing interop support.
-
-# Key Features
-* String handling
- * A lot of interop deals with strings in some form or another and handling them is a
- major amount of effort for most interop libraries. The support provided here enables
- lazy evaluation/marshalling and encoding of native strings and managed strings. These
- allow a simple `byte[]` to store a native string and ONLY marshals to a UTF16 managed
- string once when needed. This allows storing and passing strings in their native form
- for FAST retrieval from a native call and then providing that same string as an `in`
- parameter in another call. All without the need to marshal from native and then back
- again just for the call. This is a MAJOR performance enhancement for APIs that deal in
- strings.
-* Delegates and NativeCallbacks as Function pointers
- * Function pointers are a new feature of C# that makes for very high performance interop
- scenarios. However, sometimes the callback for a function pointer actually needs
- additional data not part of the parameters of the function to work properly. This
- library provides support for such scenarios where a delegate is used to "capture" the
- data while still supporting AOT scenarios. (NOTE: `Marshal.GetFunctionPointerForDelegate()`
- must dynamically emit a thunk that contains the proper signature and the captured
- "this" pointer so is NOT AOT friendly) The support offered in this library, though a
- bit more tedious, is AOT friendly.
-
diff --git a/docfx/interop-helpers/toc.yml b/docfx/interop-helpers/toc.yml
deleted file mode 100644
index abeb0d1f0..000000000
--- a/docfx/interop-helpers/toc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# TOC (Left nav) for interop-helpers folder
-- name: Overview
- href: index.md
-- name: Namespaces
- href: api/toc.yml
diff --git a/docfx/runtime-utils/api/.gitignore b/docfx/runtime-utils/api/.gitignore
deleted file mode 100644
index e8079a3be..000000000
--- a/docfx/runtime-utils/api/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-###############
-# temp file #
-###############
-*.yml
-.manifest
diff --git a/docfx/runtime-utils/api/index.md b/docfx/runtime-utils/api/index.md
deleted file mode 100644
index c3858c81f..000000000
--- a/docfx/runtime-utils/api/index.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Ubiquity.NET.Runtime.Utils
-This library contains support functionality to aid in building a language
-parser or runtime. Generally this is used in conjunction with custom types
-and the Ubiquity.NET.Llvm library to provide custom DSL JIT support.
-
diff --git a/docfx/runtime-utils/index.md b/docfx/runtime-utils/index.md
deleted file mode 100644
index c3858c81f..000000000
--- a/docfx/runtime-utils/index.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Ubiquity.NET.Runtime.Utils
-This library contains support functionality to aid in building a language
-parser or runtime. Generally this is used in conjunction with custom types
-and the Ubiquity.NET.Llvm library to provide custom DSL JIT support.
-
diff --git a/docfx/runtime-utils/toc.yml b/docfx/runtime-utils/toc.yml
deleted file mode 100644
index d76070c1b..000000000
--- a/docfx/runtime-utils/toc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# TOC (Left nav) for runtime-utils folder
-- name: Overview
- href: index.md
-- name: Namespaces
- href: api/toc.yml
diff --git a/docfx/toc.yml b/docfx/toc.yml
index f555478e9..9d7578d04 100644
--- a/docfx/toc.yml
+++ b/docfx/toc.yml
@@ -11,15 +11,3 @@
items:
- name: Llvm
href: llvm/index.md
- - name: Runtime Utils
- href: runtime-utils/index.md
- - name: .NET Extensions
- href: extensions/index.md
- - name: ANTLR Utilities
- href: antlr-utils/index.md
- - name: Interop Helpers
- href: interop-helpers/index.md
- - name: CommandLine Parsing
- href: CommandLine/index.md
- - name: Source Generation
- href: SrcGeneration/index.md
diff --git a/src/Interop/InteropTests/Ubiquity.NET.Llvm.Interop.UT.csproj b/src/Interop/InteropTests/Ubiquity.NET.Llvm.Interop.UT.csproj
index ecebd6c97..cc7a5fe9a 100644
--- a/src/Interop/InteropTests/Ubiquity.NET.Llvm.Interop.UT.csproj
+++ b/src/Interop/InteropTests/Ubiquity.NET.Llvm.Interop.UT.csproj
@@ -8,7 +8,6 @@
True
- Ubiquity.NET.Llvm.Interoptrue
@@ -20,5 +19,6 @@
+
diff --git a/src/Interop/LlvmBindingsGenerator/LlvmBindingsGenerator.csproj b/src/Interop/LlvmBindingsGenerator/LlvmBindingsGenerator.csproj
index 5c48600b6..4479e05dd 100644
--- a/src/Interop/LlvmBindingsGenerator/LlvmBindingsGenerator.csproj
+++ b/src/Interop/LlvmBindingsGenerator/LlvmBindingsGenerator.csproj
@@ -19,7 +19,7 @@
-
+
@@ -73,7 +69,7 @@
<__RspContent Include="-e $(PkgUbiquity_NET_LibLLVM)\Content\native" />
<__RspContent Include="-o $(__GeneratedSourcePath)" />
-
+
diff --git a/src/Interop/Ubiquity.NET.Llvm.Interop/Ubiquity.NET.Llvm.Interop.csproj b/src/Interop/Ubiquity.NET.Llvm.Interop/Ubiquity.NET.Llvm.Interop.csproj
index 294d2662b..1e3436f88 100644
--- a/src/Interop/Ubiquity.NET.Llvm.Interop/Ubiquity.NET.Llvm.Interop.csproj
+++ b/src/Interop/Ubiquity.NET.Llvm.Interop/Ubiquity.NET.Llvm.Interop.csproj
@@ -81,11 +81,8 @@
+
+
-
-
-
-
-
diff --git a/src/Samples/Kaleidoscope/Chapter8/Chapter8.csproj b/src/Samples/Kaleidoscope/Chapter8/Chapter8.csproj
index f24a94f7e..49401afed 100644
--- a/src/Samples/Kaleidoscope/Chapter8/Chapter8.csproj
+++ b/src/Samples/Kaleidoscope/Chapter8/Chapter8.csproj
@@ -16,7 +16,10 @@
-
+
+
+
+
diff --git a/src/Samples/Kaleidoscope/Chapter9/Chapter9.csproj b/src/Samples/Kaleidoscope/Chapter9/Chapter9.csproj
index 64ca0c8c5..9e812d113 100644
--- a/src/Samples/Kaleidoscope/Chapter9/Chapter9.csproj
+++ b/src/Samples/Kaleidoscope/Chapter9/Chapter9.csproj
@@ -16,7 +16,10 @@
-
+
+
+
+
diff --git a/src/Samples/Kaleidoscope/Kaleidoscope.Grammar/Kaleidoscope.Grammar.csproj b/src/Samples/Kaleidoscope/Kaleidoscope.Grammar/Kaleidoscope.Grammar.csproj
index 98e12bd14..e036924ab 100644
--- a/src/Samples/Kaleidoscope/Kaleidoscope.Grammar/Kaleidoscope.Grammar.csproj
+++ b/src/Samples/Kaleidoscope/Kaleidoscope.Grammar/Kaleidoscope.Grammar.csproj
@@ -20,11 +20,8 @@
-
-
-
-
-
-
+
+
+
diff --git a/src/Samples/OrcV2VeryLazy/OrcV2VeryLazy.csproj b/src/Samples/OrcV2VeryLazy/OrcV2VeryLazy.csproj
index 2c2d1339d..278bbf9cf 100644
--- a/src/Samples/OrcV2VeryLazy/OrcV2VeryLazy.csproj
+++ b/src/Samples/OrcV2VeryLazy/OrcV2VeryLazy.csproj
@@ -10,9 +10,12 @@
True
+
+
+
+
-
diff --git a/src/Ubiquity.NET.ANTLR.Utils/AntlrParseErrorListenerAdapter.cs b/src/Ubiquity.NET.ANTLR.Utils/AntlrParseErrorListenerAdapter.cs
deleted file mode 100644
index a9c63ae0f..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/AntlrParseErrorListenerAdapter.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.ANTLR.Utils
-{
- /// Adapter to translate ANTLR error listeners to an
- ///
- /// This intentionally ignores the provided by ANTLR and uses the
- /// provided in the constructor. This allows a much greater level of flexibility in reporting of diagnostics from
- /// a parser. Especially in abstracting the underlying parse technology from the diagnostic reporting
- ///
- /// The is used to allow for future adaptation of the parser to map errors from a
- /// recognizer state, which is not stable if the grammar changes. This ensures that the ID values remain unique
- /// even if the underlying grammar changes. The default is to use a 1:1 mapping where the ID values are used
- /// directly. Any value not in the map is used directly.
- ///
- ///
- public class AntlrParseErrorListenerAdapter
- : IAntlrErrorListener
- , IAntlrErrorListener
- {
- /// Initializes a new instance of the class
- /// Inner listener to route all notifications to
- /// Map of ids to translate values to an ID
- public AntlrParseErrorListenerAdapter(
- IParseErrorListener innerListener,
- ImmutableDictionary? identifierMap = default
- )
- {
- InnerListener = innerListener;
- IdentifierMap = identifierMap;
- }
-
- /// Gets the mapping for identifiers. If this is then no mapping is used.
- public ImmutableDictionary? IdentifierMap { get; }
-
- ///
- public void SyntaxError( TextWriter output // ignored
- , [NotNull] IRecognizer recognizer
- , [Nullable] int offendingSymbol
- , int line
- , int charPositionInLine
- , [NotNull] string msg
- , [Nullable] RecognitionException e
- )
- {
- var err = new SyntaxError( ParseErrorSource.Lexer
- , recognizer.InputStream.SourceName
- , GetMappedId(recognizer.State)
- , string.Empty
- , new SourcePosition(line, charPositionInLine, recognizer.InputStream.Index)
- , msg
- , e
- );
-
- InnerListener.SyntaxError( err );
- }
-
- ///
- public void SyntaxError( TextWriter output // ignored
- , [NotNull] IRecognizer recognizer
- , [Nullable] IToken offendingSymbol
- , int line
- , int charPositionInLine
- , [NotNull] string msg
- , [Nullable] RecognitionException e
- )
- {
- var err = new SyntaxError( ParseErrorSource.Parser
- , recognizer.InputStream.SourceName
- , GetMappedId(recognizer.State)
- , offendingSymbol.Text
- , new SourcePosition(line, charPositionInLine, recognizer.InputStream.Index)
- , msg
- , e
- );
-
- InnerListener.SyntaxError( err );
- }
-
- private int GetMappedId(int state)
- {
- int mappedId = state; // assume 1:1 mapping.
-
- if(IdentifierMap is not null && IdentifierMap.IsEmpty)
- {
- if(IdentifierMap.TryGetValue(mappedId, out int mappedValue))
- {
- mappedId = mappedValue;
- }
- }
-
- return mappedId;
- }
-
- private readonly IParseErrorListener InnerListener;
- }
-}
diff --git a/src/Ubiquity.NET.ANTLR.Utils/AntlrUtilities.cs b/src/Ubiquity.NET.ANTLR.Utils/AntlrUtilities.cs
deleted file mode 100644
index 7187c5c89..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/AntlrUtilities.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.ANTLR.Utils
-{
- /// Utility functions for extending ANTLR types
- public static class AntlrUtilities
- {
- /// Gets a character based interval from a
- /// context to get the interval from
- /// Character based interval covered by the context
- /// This handles the standard EOF rule and translates that to an invalid interval
- public static Interval GetCharInterval( this ParserRuleContext ruleContext )
- {
- ArgumentNullException.ThrowIfNull( ruleContext );
-
- // if this is an EOF return an invalid interval
- if(ruleContext.Start.Type == Recognizer.Eof)
- {
- return Interval.Invalid;
- }
-
- int startChar = ruleContext.Start.StartIndex;
- int endChar = ruleContext.Stop.StopIndex - 1;
- return Interval.Of( Math.Min( startChar, endChar ), Math.Max( startChar, endChar ) );
- }
-
- /// Gets the source from a recognizer if it is available
- /// Recognizer to get the stream from
- /// The character stream or null if not available.
- public static ICharStream? GetSourceStream( this IRecognizer recognizer )
- {
- ArgumentNullException.ThrowIfNull( recognizer );
-
- return recognizer.InputStream != null && recognizer.InputStream is ITokenStream tokenStream
- ? tokenStream.TokenSource.InputStream
- : null;
- }
-
- /// Gets the source input text for a produced by an
- /// Rule context to get the source text from
- /// Recognizer that produced
- /// Source contents for the rule or an empty string if the source is not available
- public static string GetSourceText( this ParserRuleContext ruleContext, IRecognizer recognizer )
- {
- return ruleContext.GetSourceText( recognizer.GetSourceStream() );
- }
-
- /// Gets the source input text for a parsed from a stream
- /// Rule context to get the source text from
- /// The stream the rule was parsed from
- /// Source contents for the rule or an empty string if the source is not available
- public static string GetSourceText( this ParserRuleContext ruleContext, ICharStream? charStream )
- {
- if(charStream == null)
- {
- return string.Empty;
- }
-
- var span = ruleContext.GetCharInterval( );
- return span.a < 0 ? string.Empty : charStream.GetText( span );
- }
-
- /// Generates a Unique ID for a parse tree node
- /// parse tree to generate the id for
- /// ID for the node
- ///
- /// This is useful when generating various graph visualization file formats as
- /// they normally need unique IDs for each node to maintain proper references
- /// between the nodes.
- ///
- public static string GetUniqueNodeId( this IParseTree tree )
- {
- ArgumentNullException.ThrowIfNull( tree );
-
- var bldr = new StringBuilder( tree.GetHashCode( ).ToString( CultureInfo.InvariantCulture ) );
- if(tree.Parent != null)
- {
- bldr.Append( tree.Parent.GetChildIndex( tree ) );
- bldr.Append( tree.Parent.GetUniqueNodeId() );
- }
-
- return bldr.ToString();
- }
-
- /// Determines the index of a child item in the parent
- /// Parent tree to find the item in
- /// Item to determine the index of
- /// Zero based index in the parent or -1 if the item is not a child of
- public static int GetChildIndex( this IParseTree tree, IParseTree item )
- {
- ArgumentNullException.ThrowIfNull( tree );
-
- for(int i = 0; i < tree.ChildCount; ++i)
- {
- if(item == tree.GetChild( i ))
- {
- return i;
- }
- }
-
- return -1;
- }
-
- /// Enables enumeration of characters from a
- /// Builder to enumerate
- /// Enumerable for all the characters in the builder
- public static IEnumerable AsEnumerable( this StringBuilder bldr )
- {
- ArgumentNullException.ThrowIfNull( bldr );
-
- for(int i = 0; i < bldr.Length; ++i)
- {
- yield return bldr[ i ];
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.ANTLR.Utils/DebugTraceListener.cs b/src/Ubiquity.NET.ANTLR.Utils/DebugTraceListener.cs
deleted file mode 100644
index 6757e34eb..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/DebugTraceListener.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.ANTLR.Utils
-{
- /// Provides debug notification of all rule processing while parsing
- public class DebugTraceListener
- : IParseTreeListener
- {
- /// Initializes a new instance of the class.
- /// Parser to use to resolve names when generating messages
- public DebugTraceListener( Antlr4.Runtime.Parser parser )
- {
- Parser = parser;
- }
-
- ///
- public virtual void EnterEveryRule( ParserRuleContext ctx )
- {
- ArgumentNullException.ThrowIfNull( ctx );
-
- Trace.TraceInformation( $"enter[{ctx.SourceInterval}] {Parser.RuleNames[ ctx.RuleIndex ]} [{ctx.GetType().Name}] Lt(1)='{((ITokenStream)Parser.InputStream).LT( 1 ).Text}'" );
- }
-
- ///
- public virtual void ExitEveryRule( ParserRuleContext ctx )
- {
- ArgumentNullException.ThrowIfNull( ctx );
-
- Trace.TraceInformation( $"exit[{ctx.SourceInterval}] {Parser.RuleNames[ ctx.RuleIndex ]} [{ctx.GetType().Name}] Lt(1)='{((ITokenStream)Parser.InputStream).LT( 1 ).Text}'" );
- }
-
- ///
- public virtual void VisitErrorNode( IErrorNode node )
- {
- ArgumentNullException.ThrowIfNull( node );
-
- Trace.TraceInformation( "Error: '{0}'", node.ToStringTree() );
- }
-
- ///
- public virtual void VisitTerminal( ITerminalNode node )
- {
- ArgumentNullException.ThrowIfNull( node );
-
- var parserRuleContext = ( ParserRuleContext )node.Parent.RuleContext;
- IToken symbol = node.Symbol;
- Trace.TraceInformation( "Terminal: '{0}' rule {1}", symbol, Parser.RuleNames[ parserRuleContext.RuleIndex ] );
- }
-
- private readonly Antlr4.Runtime.Parser Parser;
- }
-}
diff --git a/src/Ubiquity.NET.ANTLR.Utils/GlobalNamespaceImports.cs b/src/Ubiquity.NET.ANTLR.Utils/GlobalNamespaceImports.cs
deleted file mode 100644
index 2a699c844..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/GlobalNamespaceImports.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.
-
-/*
-NOTE:
-While the MsBuild `ImplicitUsings` property is banned from this repo, the C# language feature of global usings is NOT.
-The build property will auto include an invisible and undiscoverable (without looking up obscure documentation)
-set of namespaces that is NOT consistent or controlled by the developer. THAT is what is BAD/BROKEN about that feature.
-By banning it's use and then providing a `GlobalNamespaceImports.cs` source file with ONLY global using statements ALL of
-that is eliminated. Such use of the language feature restores FULL control and visibility of the namespaces to the developer,
-where it belongs. For a good explanation of this problem see: https://rehansaeed.com/the-problem-with-csharp-10-implicit-usings/.
-For an explanation of the benefits of the language feature see: https://www.hanselman.com/blog/implicit-usings-in-net-6
-*/
-
-global using System;
-global using System.Collections.Generic;
-global using System.Collections.Immutable;
-global using System.Diagnostics;
-global using System.Globalization;
-global using System.IO;
-global using System.Text;
-
-global using Antlr4.Runtime;
-global using Antlr4.Runtime.Misc;
-global using Antlr4.Runtime.Tree;
-
-global using Ubiquity.NET.Extensions;
-global using Ubiquity.NET.Runtime.Utils;
diff --git a/src/Ubiquity.NET.ANTLR.Utils/LocationExtensions.cs b/src/Ubiquity.NET.ANTLR.Utils/LocationExtensions.cs
deleted file mode 100644
index de1ca1cff..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/LocationExtensions.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.ANTLR.Utils
-{
- /// Utility class to provide extensions for translation of ANTLR location data into a
- public static class LocationExtensions
- {
- /// Gets the for a given
- /// Parser rule context to get the location from
- /// for the context
- public static SourceRange GetSourceRange( this ParserRuleContext ctx )
- {
- ArgumentNullException.ThrowIfNull( ctx );
-
- return new SourceRange( new(ctx.Start.Line, ctx.Start.Column, ctx.Start.StartIndex)
- , new(ctx.Stop.Line, ctx.Stop.Column, ctx.Stop.StopIndex)
- );
- }
-
- /// Attempts to retrieve the from a
- /// Context to get the span from
- /// for this input context or a default constructed one
- ///
- /// Not all derived types will support line+col location information. This
- /// only tests for a and retrieves the location from that. The base
- /// RuleContext and other derived types simply get a default constructed location as the location is
- /// not known. (They only store location as an integral interval without the line+col information)
- ///
- public static SourceRange GetSourceRange( this RuleContext ctx )
- {
- ArgumentNullException.ThrowIfNull( ctx );
-
- if(ctx is ParserRuleContext ruleCtx)
- {
- ruleCtx.GetSourceRange();
- }
-
- // NOTE other RuleContext types may track position but a RuleContext itself
- // only tracks the integral position as an Interval (no line+col info!)
- return default;
- }
-
- /// Gets the source location information for a token an represents
- /// Terminal node
- /// Source span for the terminal's token
- public static SourceRange GetSourceRange( this ITerminalNode node )
- {
- ArgumentNullException.ThrowIfNull( node );
-
- return node.Symbol.GetSourceRange();
- }
-
- /// Gets the from an
- /// Token to get the location information for
- /// SourceLocation
- public static SourceRange GetSourceRange( this IToken token )
- {
- ArgumentNullException.ThrowIfNull( token );
-
- // TODO: Q: Should this account for a newline in the token?
- // A: Probably not, as a token can't span a newline.
- return new SourceRange(
- new(token.Line, token.Column, token.StartIndex),
- new(token.Line, token.Column + token.Text.Length, token.StopIndex)
- );
- }
- }
-}
diff --git a/src/Ubiquity.NET.ANTLR.Utils/ReadMe.md b/src/Ubiquity.NET.ANTLR.Utils/ReadMe.md
deleted file mode 100644
index 7abac0ebf..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/ReadMe.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# About
-This library provides general extensions to ANTLR including adapter bindings for the
-`Ubiquity.NET.Runtime` library.
-
-# Key usage
-* Get a SourceLocation from various ANTLR types (rule, tokens, terminals)
- - This provides an adaptation to the abstract source location
-* Debug trace listener
- - Provides debug TRACE support for any parser by listening for every rule and using
- Debug.Trace() to generate a string representation of that rule. This is VERY useful
- when developing or debugging a grammar.
-* Adapter for parse error listeners to a unified and abstract
- `Ubiquity.NET.Runtime.IParseErrorListener`.
- - This allows building consumers that deal with errors and remain independent of the
- parsing technology.
-* Extension functions that provides commonly used support for ANTLR
- - Get a character interval from a ParserRuleContext with support for the standard EOF
- rule.
- - Gets the source stream from an IRecognizer
- - Gets the source text from a rule context and recognizer that produced it.
- - Gets source text from a rule context and stream that it was parsed from.
- - Gets a unique ID for a parse tree
- * Useful for building graphs of the result of parsing as many graphing
- representations require a unique node id for every node in the graph.
-
diff --git a/src/Ubiquity.NET.ANTLR.Utils/Ubiquity.NET.ANTLR.Utils.csproj b/src/Ubiquity.NET.ANTLR.Utils/Ubiquity.NET.ANTLR.Utils.csproj
deleted file mode 100644
index 00a812d8b..000000000
--- a/src/Ubiquity.NET.ANTLR.Utils/Ubiquity.NET.ANTLR.Utils.csproj
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- net8.0
- 13
- enable
- True
- True
-
-
- true
- 4.9.0
- .NET Foundation,Ubiquity.NET
- false
- General use .NET extensions and utilities
- Extensions,.NET,Ubiquity.NET
- ReadMe.md
- https://github.com/UbiquityDotNET/Llvm.NET
- https://github.com/UbiquityDotNET/Llvm.NET.git
- git
- Apache-2.0 WITH LLVM-exception
- true
- snupkg
-
-
-
-
-
-
-
-
-
-
-
-
- all
- false
- Analyzer
-
-
-
-
-
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/AnalyzerConfigOptionsProviderExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/AnalyzerConfigOptionsProviderExtensions.cs
deleted file mode 100644
index 0fc338d3d..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/AnalyzerConfigOptionsProviderExtensions.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-// Mostly from https://github.com/Sergio0694/PolySharp/blob/main/src/PolySharp.SourceGenerators/Extensions/AnalyzerConfigOptionsProviderExtensions.cs
-// Reformatted and made to conform to repo guides
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Extension methods for the type.
- public static class AnalyzerConfigOptionsProviderExtensions
- {
- /// Checks whether the input property has a valid value.
- /// The input instance.
- /// The Build property name.
- /// The resulting property value, if invalid.
- /// Whether the target property is a valid value.
- public static bool IsValidBoolBuildProperty(
- this AnalyzerConfigOptionsProvider options,
- string propertyName,
- [NotNullWhen( false )] out string? propertyValue
- )
- {
- return !options.GlobalOptions.TryGetValue( $"{BuildProperty}.{propertyName}", out propertyValue )
- || string.IsNullOrEmpty( propertyValue )
- || string.Equals( propertyValue, bool.TrueString, StringComparison.OrdinalIgnoreCase )
- || string.Equals( propertyValue, bool.FalseString, StringComparison.OrdinalIgnoreCase );
- }
-
- /// Gets the value of a build property.
- /// The input instance.
- /// The build property name.
- /// The value of the specified build property.
- ///
- /// The return value is equivalent to a (case insensitive) '$(PropertyName)' == 'true' check.
- /// That is, any other value, including empty/not present, is considered .
- ///
- public static bool GetBoolBuildProperty( this AnalyzerConfigOptionsProvider options, string propertyName )
- {
- return options.GlobalOptions.TryGetValue( $"{BuildProperty}.{propertyName}", out string? propertyValue )
- && string.Equals( propertyValue, bool.TrueString, StringComparison.OrdinalIgnoreCase );
- }
-
- /// Gets the value of a Build property representing a semicolon-separated list of strings.
- /// The input instance.
- /// The build property name.
- /// The value of the specified build property.
- public static ImmutableArray GetStringArrayBuildProperty( this AnalyzerConfigOptionsProvider options, string propertyName )
- {
- return options.GlobalOptions.TryGetValue( $"{BuildProperty}.{propertyName}", out string? propertyValue )
- ? [ .. propertyValue.Split( ',', ';' ) ]
- : [];
- }
-
- // MSBuild properties that are visible to the compiler are available with the "build_property." prefix
- // See: https://andrewlock.net/creating-a-source-generator-part-13-providing-and-accessing-msbuild-settings-in-source-generators/
- private const string BuildProperty = "build_property";
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/BaseTypeDeclarationSyntaxExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/BaseTypeDeclarationSyntaxExtensions.cs
deleted file mode 100644
index 6ca2942b5..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/BaseTypeDeclarationSyntaxExtensions.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility type to provide extensions for
- public static class BaseTypeDeclarationSyntaxExtensions
- {
- // The following 2 extension methods are based on:
- // https://andrewlock.net/creating-a-source-generator-part-5-finding-a-type-declarations-namespace-and-type-hierarchy/
-
- /// Gets the declared namespace for a
- /// Syntax to get the namespace for
- /// Namespace of
- public static string GetDeclaredNamespace(this BaseTypeDeclarationSyntax syntax)
- {
- // If we don't have a namespace at all we'll return an empty string
- // This accounts for the "default namespace" case
- string nameSpace = string.Empty;
-
- // Get the containing syntax node for the type declaration
- // (could be a nested type, for example)
- SyntaxNode? potentialNamespaceParent = syntax.Parent;
-
- // Keep moving "out" of nested classes etc until we get to a namespace
- // or until we run out of parents
- while (potentialNamespaceParent != null
- && potentialNamespaceParent is not NamespaceDeclarationSyntax
- && potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax)
- {
- potentialNamespaceParent = potentialNamespaceParent.Parent;
- }
-
- // Build up the final namespace by looping until we no longer have a namespace declaration
- if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent)
- {
- // We have a namespace. Use that as the type
- nameSpace = namespaceParent.Name.ToString();
-
- // Keep moving "out" of the namespace declarations until there
- // are no more nested namespace declarations.
- while (true)
- {
- if (namespaceParent.Parent is not NamespaceDeclarationSyntax parent)
- {
- break;
- }
-
- // Add the outer namespace as a prefix to the final namespace
- nameSpace = $"{namespaceParent.Name}.{nameSpace}";
- namespaceParent = parent;
- }
- }
-
- // return the final namespace
- return nameSpace;
- }
-
- /// Gets the nested class name for a
- /// Syntax to get the name for
- /// Flag to indicate if the type itself is included in the name [Default:
- /// of the syntax or
- public static NestedClassName? GetNestedClassName( this BaseTypeDeclarationSyntax syntax, bool includeSelf = false)
- {
- // Try and get the parent syntax. If it isn't a type like class/struct, this will be null
- TypeDeclarationSyntax? parentSyntax = includeSelf ? syntax as TypeDeclarationSyntax : syntax.Parent as TypeDeclarationSyntax;
- NestedClassName? parentClassInfo = null;
-
- // We can only be nested in class/struct/record
-
- // Keep looping while we're in a supported nested type
- while (parentSyntax is not null)
- {
- // NOTE: due to bug https://github.com/dotnet/roslyn/issues/78042 this
- // is not using a local static function to evaluate this in the condition
- // of the while loop [Workaround: go back to "old" extension syntax...]
- var rawKind = parentSyntax.Kind();
- bool isAllowedKind
- = rawKind == SyntaxKind.ClassDeclaration
- || rawKind == SyntaxKind.StructDeclaration
- || rawKind == SyntaxKind.RecordDeclaration;
-
- if (!isAllowedKind)
- {
- break;
- }
-
- // Record the parent type keyword (class/struct etc), name, and constraints
- parentClassInfo = new NestedClassName(
- keyword: parentSyntax.Keyword.ValueText,
- name: parentSyntax.Identifier.ToString() + parentSyntax.TypeParameterList,
- constraints: parentSyntax.ConstraintClauses.ToString(),
- children: parentClassInfo is null ? [] : [parentClassInfo]); // set the child link (null initially)
-
- // Move to the next outer type
- parentSyntax = parentSyntax.Parent as TypeDeclarationSyntax;
- }
-
- // return a link to the outermost parent type
- return parentClassInfo;
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/CompilationExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/CompilationExtensions.cs
deleted file mode 100644
index eb631224e..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/CompilationExtensions.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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.
-
-// Mostly from: https://github.com/Sergio0694/PolySharp/blob/main/src/PolySharp.SourceGenerators/Extensions/CompilationExtensions.cs
-// Reformated and adapted to support repo guidelines
-
-using Microsoft.CodeAnalysis.VisualBasic;
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Structure for a runtime version
- /// Name of the runtime
- /// Version of the runtime
- [SuppressMessage( "StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Simple record" )]
- public readonly record struct RuntimeVersion( string RuntimeName, Version Version );
-
- /// Extension methods for the type.
- public static class CompilationExtensions
- {
- /// Checks whether a given compilation (assumed to be for C#) is using at least a given language version.
- /// The to consider for analysis.
- /// The minimum language version to check.
- /// Whether is using at least the specified language version.
- public static bool HasLanguageVersionAtLeastEqualTo( this Compilation compilation, Microsoft.CodeAnalysis.CSharp.LanguageVersion languageVersion )
- {
- return compilation is not CSharpCompilation csharpCompilation
- ? throw new ArgumentNullException( nameof( compilation ) )
- : csharpCompilation.LanguageVersion >= languageVersion;
- }
-
- /// Checks whether a given VB compilation is using at least a given language version.
- /// The to consider for analysis.
- /// The minimum language version to check.
- /// Whether is using at least the specified language version.
- [SuppressMessage( "StyleCop.CSharp.NamingRules", "SA1305:Field names should not use Hungarian notation", Justification = "not Hungarian" )]
- public static bool HasLanguageVersionAtLeastEqualTo( this Compilation compilation, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersion )
- {
- return compilation is not VisualBasicCompilation vbCompilation
- ? throw new ArgumentNullException( nameof( compilation ) )
- : vbCompilation.LanguageVersion >= languageVersion;
- }
-
- /// Gets the runtime version by extracting the version from the assembly implementing
- /// Compilation to get the version information from
- /// Version of the runtime the compilation is targetting
- public static RuntimeVersion GetRuntimeVersion(this Compilation self)
- {
- var objectType = self.GetSpecialType(SpecialType.System_Object);
- var runtimeAssembly = objectType.ContainingAssembly;
- return new(runtimeAssembly.Identity.Name, runtimeAssembly.Identity.Version);
- }
-
- /// Gets a value indicating wheter the compilation has a minium version of the runtime
- /// Compilation to test
- /// Minimum version accepted
- /// if the runtime version targetted by the compilation is at least ; otherwise
- public static bool HasRuntimeVersionAtLeast(this Compilation self, RuntimeVersion minVersion)
- {
- var runtimeVersion = GetRuntimeVersion(self);
- return runtimeVersion.RuntimeName == minVersion.RuntimeName && runtimeVersion.Version >= minVersion.Version;
- }
-
- /// Checks whether or not a type with a specified metadata name is accessible from a given instance.
- /// The to consider for analysis.
- /// The fully-qualified metadata type name to find.
- /// Whether a type with the specified metadata name can be accessed from the given compilation.
- ///
- /// This method enumerates candidate type symbols to find a match in the following order:
- /// 1) If only one type with the given name is found within the compilation and its referenced assemblies, check its accessibility.
- /// 2) If the current defines the symbol, check its accessibility.
- /// 3) Otherwise, check whether the type exists and is accessible from any of the referenced assemblies.
- ///
- public static bool HasAccessibleTypeWithMetadataName( this Compilation compilation, string fullyQualifiedMetadataName )
- {
- if(compilation is null)
- {
- throw new ArgumentNullException( nameof( compilation ) );
- }
-
- if(string.IsNullOrWhiteSpace( fullyQualifiedMetadataName ))
- {
- throw new ArgumentException( $"'{nameof( fullyQualifiedMetadataName )}' cannot be null or whitespace.", nameof( fullyQualifiedMetadataName ) );
- }
-
- // If there is only a single matching symbol, check its accessibility
- if(compilation.GetTypeByMetadataName( fullyQualifiedMetadataName ) is INamedTypeSymbol typeSymbol)
- {
- return compilation.IsSymbolAccessibleWithin( typeSymbol, compilation.Assembly );
- }
-
- // Otherwise, check all available types
- foreach(INamedTypeSymbol currentTypeSymbol in compilation.GetTypesByMetadataName( fullyQualifiedMetadataName ))
- {
- if(compilation.IsSymbolAccessibleWithin( currentTypeSymbol, compilation.Assembly ))
- {
- return true;
- }
- }
-
- return false;
- }
-
- /// Checks whether or not a type with a specified metadata name is accessible from a given instance.
- /// The to consider for analysis.
- /// The fully-qualified metadata type name to find.
- /// Name of the member
- /// Whether a type with the specified metadata name can be accessed from the given compilation.
- ///
- /// This method enumerates candidate type symbols to find a match in the following order:
- /// 1) If only one type with the given name is found within the compilation and its referenced assemblies, check its accessibility.
- /// 2) If the current defines the symbol, check its accessibility.
- /// 3) Otherwise, check whether the type exists and is accessible from any of the referenced assemblies.
- ///
- public static bool HasAccessibleMember( this Compilation compilation, string fullyQualifiedMetadataName, string memberName )
- {
- // If there is only a single matching symbol, check its accessibility
- if(compilation.GetTypeByMetadataName( fullyQualifiedMetadataName ) is INamedTypeSymbol typeSymbol)
- {
- return compilation.IsSymbolAccessibleWithin( typeSymbol, compilation.Assembly )
- && compilation.HasAccessibleMemberWithin( typeSymbol, memberName, compilation.Assembly);
- }
-
- // Otherwise, check all available types
- foreach(INamedTypeSymbol currentTypeSymbol in compilation.GetTypesByMetadataName( fullyQualifiedMetadataName ))
- {
- if(compilation.IsSymbolAccessibleWithin( currentTypeSymbol, compilation.Assembly )
- && compilation.HasAccessibleMemberWithin( currentTypeSymbol, memberName, compilation.Assembly)
- )
- {
- return true;
- }
- }
-
- return false;
- }
-
- /// Tests if a has a type with an accessible member of a given name
- /// to test
- /// Type symbol for the type to test
- /// Name of the member to test for
- /// Symbol to test if the member is accessible within
- /// Symbol to use for "protected access" [default: null]
- /// if the member is accesible and
- public static bool HasAccessibleMemberWithin(
- this Compilation self,
- ITypeSymbol typeSymbol,
- string memberName,
- ISymbol within,
- ITypeSymbol? throughType = null
- )
- {
- if(self is null)
- {
- throw new ArgumentNullException( nameof( self ) );
- }
-
- if(typeSymbol is null)
- {
- throw new ArgumentNullException( nameof( typeSymbol ) );
- }
-
- if(string.IsNullOrEmpty( memberName ))
- {
- throw new ArgumentException( $"'{nameof( memberName )}' cannot be null or empty.", nameof( memberName ) );
- }
-
- if(within is null)
- {
- throw new ArgumentNullException( nameof( within ) );
- }
-
- var memberSymbol = typeSymbol.GetMembers().Where(s=>s.Name == memberName).FirstOrDefault();
- return memberSymbol is not null
- && self.IsSymbolAccessibleWithin(memberSymbol, within, throughType);
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/DiagnosticInfo.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/DiagnosticInfo.cs
deleted file mode 100644
index fe67ebd7a..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/DiagnosticInfo.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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.
-
-// Modified from idea in blog post: https://andrewlock.net/creating-a-source-generator-part-9-avoiding-performance-pitfalls-in-incremental-generators/
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Contains diagnostic information collected for reporting to the host
- ///
- /// This is an equatable type and therefore is legit for use in generators/analyzers where
- /// that is needed for caching. A is not, so this record bundles
- /// the parameters needed for creation of one and defers the construction until needed.
- ///
- public sealed record DiagnosticInfo
- {
- /// Initializes a new instance of the class.
- /// Descriptor for the diagnostic
- /// Location in the source file that triggered this diagnostic
- /// Args for the message
- public DiagnosticInfo(DiagnosticDescriptor descriptor, Location? location, params IEnumerable msgArgs)
- {
- Descriptor = descriptor;
- Location = location;
- Params = msgArgs.ToImmutableArray();
- }
-
- /// Gets the parameters for this diagnostic
- public EquatableArray Params { get; }
-
- /// Gets the descriptor for this diagnostic
- public DiagnosticDescriptor Descriptor { get; }
-
- // Location is an abstract type but all derived types implement IEquatable where T is Location
- // Thus a location is equatable even though the base abstract type doesn't implement that interface.
-
- /// Gets the location of the source of this diagnostic
- public Location? Location { get; }
-
- /// Factory to create a from the information contained in this holder
- /// that represents this information
- public Diagnostic CreateDiagnostic()
- {
- return Diagnostic.Create(Descriptor, Location, Params.ToArray());
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/EquatableArray.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/EquatableArray.cs
deleted file mode 100644
index 29a5c8e3f..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/EquatableArray.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-// 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.
-
-#pragma warning disable SA1642 // Constructor summary documentation should begin with standard text
-#pragma warning disable SA1615 // Element return value should be documented
-#pragma warning disable SA1604 // Element documentation should have summary
-#pragma warning disable SA1611 // Element parameters should be documented
-#pragma warning disable CA1000 // Do not declare static members on generic types
-#pragma warning disable CA2225 // Operator overloads have named alternates
-
-// ORIGINALLY FROM: https://github.com/CommunityToolkit/dotnet/blob/7b53ae23dfc6a7fb12d0fc058b89b6e948f48448/src/CommunityToolkit.Mvvm.SourceGenerators/Helpers/EquatableArray%7BT%7D.cs
-
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Extensions for .
- public static class EquatableArray
- {
- /// Creates an instance from a given .
- /// The type of items in the input array.
- /// The input instance.
- /// An instance from a given .
- public static EquatableArray AsEquatableArray(this ImmutableArray array)
- where T : IEquatable
- {
- return array.IsDefault ? throw new ArgumentNullException(nameof(array))
- : new(array);
- }
- }
-
- ///
- /// An immutable, equatable array. This is equivalent to but with value equality of members support.
- ///
- /// The type of values in the array.
- public readonly struct EquatableArray
- : IEquatable>
- , IEnumerable
- where T : IEquatable
- {
- ///
- /// The underlying array.
- ///
- private readonly T[]? array;
-
- ///
- /// Creates a new instance.
- ///
- /// The input to wrap.
- public EquatableArray(ImmutableArray array)
- {
- this.array = Unsafe.As, T[]?>(ref array);
- }
-
- ///
- /// Gets a reference to an item at a specified position within the array.
- ///
- /// The index of the item to retrieve a reference to.
- /// A reference to an item at a specified position within the array.
- public ref readonly T this[int index]
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => ref AsImmutableArray().ItemRef(index);
- }
-
- ///
- /// Gets a value indicating whether the current array is empty.
- ///
- public bool IsEmpty
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => AsImmutableArray().IsEmpty;
- }
-
- /// Gets the length of the array
- public int Length => array?.Length ?? 0;
-
- ///
- public bool Equals(EquatableArray array)
- {
- return AsSpan().SequenceEqual(array.AsSpan());
- }
-
- ///
- public override bool Equals([NotNullWhen(true)] object? obj)
- {
- return obj is EquatableArray array && Equals(this, array);
- }
-
- ///
- public override int GetHashCode()
- {
- if (this.array is not T[] array)
- {
- return 0;
- }
-
- HashCode hashCode = default;
-
- foreach (T item in array)
- {
- hashCode.Add(item);
- }
-
- return hashCode.ToHashCode();
- }
-
- ///
- /// Gets an instance from the current .
- ///
- /// The from the current .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ImmutableArray AsImmutableArray()
- {
- return Unsafe.As>(ref Unsafe.AsRef(in array));
- }
-
- ///
- /// Creates an instance from a given .
- ///
- /// The input instance.
- /// An instance from a given .
- public static EquatableArray FromImmutableArray(ImmutableArray array)
- {
- return new(array);
- }
-
- ///
- /// Returns a wrapping the current items.
- ///
- /// A wrapping the current items.
- public ReadOnlySpan AsSpan()
- {
- return AsImmutableArray().AsSpan();
- }
-
- ///
- /// Copies the contents of this instance to a mutable array.
- ///
- /// The newly instantiated array.
- public T[] ToArray()
- {
- return [.. AsImmutableArray()];
- }
-
- ///
- /// Gets an value to traverse items in the current array.
- ///
- /// An value to traverse items in the current array.
- public ImmutableArray.Enumerator GetEnumerator()
- {
- return AsImmutableArray().GetEnumerator();
- }
-
- ///
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)AsImmutableArray()).GetEnumerator();
- }
-
- ///
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)AsImmutableArray()).GetEnumerator();
- }
-
- ///
- /// Implicitly converts an to .
- ///
- /// An instance from a given .
- public static implicit operator EquatableArray(ImmutableArray array)
- {
- return FromImmutableArray(array);
- }
-
- ///
- /// Implicitly converts an to .
- ///
- /// An instance from a given .
- public static implicit operator ImmutableArray(EquatableArray array)
- {
- return array.AsImmutableArray();
- }
-
- ///
- /// Checks whether two values are the same.
- ///
- /// The first value.
- /// The second value.
- /// Whether and are equal.
- public static bool operator ==(EquatableArray left, EquatableArray right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Checks whether two values are not the same.
- ///
- /// The first value.
- /// The second value.
- /// Whether and are not equal.
- public static bool operator !=(EquatableArray left, EquatableArray right)
- {
- return !left.Equals(right);
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/GlobalNamespaceImports.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/GlobalNamespaceImports.cs
deleted file mode 100644
index ffd720fe7..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/GlobalNamespaceImports.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-/*
-NOTE:
-While the MsBuild `ImplicitUsings` property is banned from this repo, the C# language feature of global usings is NOT.
-The build property will auto include an invisible and undiscoverable (without looking up obscure documentation)
-set of namespaces that is NOT consistent or controlled by the developer. THAT is what is BAD/BROKEN about that feature.
-By banning it's use and then providing a `GlobalNamespaceImports.cs` source file with ONLY global using statements ALL of
-that is eliminated. Such use of the language feature restores FULL control and visibility of the namespaces to the developer,
-where it belongs. For a good explanation of this problem see: https://rehansaeed.com/the-problem-with-csharp-10-implicit-usings/.
-For an explanation of the benefits of the language feature see: https://www.hanselman.com/blog/implicit-usings-in-net-6
-*/
-
-// BUG: False positive from IDE0005 - Using directive is unnecessary
-// Attempts to remove/sort are at least able to figure it out and do the right thing.
-// Bug seems to be related to multi-targetting.
-#pragma warning disable IDE0005
-
-global using System;
-global using System.CodeDom.Compiler;
-global using System.Collections;
-global using System.Collections.Generic;
-global using System.Collections.Immutable;
-global using System.Diagnostics.CodeAnalysis;
-global using System.IO;
-global using System.Linq;
-global using System.Reflection;
-global using System.Runtime.CompilerServices;
-global using System.Text;
-
-global using Microsoft.CodeAnalysis;
-global using Microsoft.CodeAnalysis.CSharp;
-global using Microsoft.CodeAnalysis.CSharp.Syntax;
-global using Microsoft.CodeAnalysis.Diagnostics;
-global using Microsoft.CodeAnalysis.Text;
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/GlobalSuppressions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/GlobalSuppressions.cs
deleted file mode 100644
index 2b0ab7675..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/GlobalSuppressions.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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.
-
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project.
-// Project-level suppressions either have no target or are given
-// a specific target and scoped to a namespace, type, member, etc.
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/MemberDeclarationSyntaxExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/MemberDeclarationSyntaxExtensions.cs
deleted file mode 100644
index 2177bf75c..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/MemberDeclarationSyntaxExtensions.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility class to provide extensions for
- public static class MemberDeclarationSyntaxExtensions
- {
- /// Determines if a contains a specified attribute or not
- /// to test
- /// name of the attribute
- /// if the attribute is found or if not
- /// is
- public static bool HasAttribute(this MemberDeclarationSyntax self, string attributeName)
- {
- return self is not null
- ? self.TryGetAttribute(attributeName, out _)
- : throw new ArgumentNullException(nameof(self));
- }
-
- /// Tries to get an from a
- /// The to get the attribute from
- /// name of the attribute
- /// resulting or if not found
- /// if the attribute is found or if not
- public static bool TryGetAttribute(
- this MemberDeclarationSyntax self,
- string attributeName,
- [NotNullWhen(true)] out AttributeSyntax? value
- )
- {
- value = null;
- string shortName = attributeName;
- if (attributeName.EndsWith("Attribute"))
- {
- shortName = shortName[..^9];
- }
- else
- {
- attributeName += "Attribute";
- }
-
- var q = from attributeList in self.AttributeLists
- from attribute in attributeList.Attributes
- let name = attribute.GetIdentifierName()
- where name == attributeName || name == shortName
- select attribute;
-
- value = q.FirstOrDefault();
- return value != null;
- }
-
- /// Determines if a declartion has an extern modifier
- /// to test
- /// if has the modifier or not
- /// is null
- public static bool IsExtern(this MemberDeclarationSyntax self)
- {
- return self is not null
- ? self.Modifiers.HasExtern()
- : throw new ArgumentNullException(nameof(self));
- }
-
- /// Determines if a declartion has a partial modifier
- ///
- public static bool IsPartial(this MemberDeclarationSyntax self)
- {
- return self is not null
- ? self.Modifiers.HasPartialKeyword()
- : throw new ArgumentNullException(nameof(self));
- }
-
- /// Determines if a declartion has a static modifier
- ///
- public static bool IsStatic(this MemberDeclarationSyntax self)
- {
- return self is not null
- ? self.Modifiers.HasStatic()
- : throw new ArgumentNullException(nameof(self));
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/MethodDeclarationSyntaxExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/MethodDeclarationSyntaxExtensions.cs
deleted file mode 100644
index 2f4198212..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/MethodDeclarationSyntaxExtensions.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility class to provide extensions for
- public static class MethodDeclarationSyntaxExtensions
- {
- // LibraryImportAttribute - intentionally NOT reported as a P/Invoke
- // It uses different qualifiers and, technically, is NOT a P/Invoke
- // signature (It's a generated marshaling function with a nested private
- // P/Invoke using NO marshaling)
-
- /// Determines if a method declaration is a P/Invoke
- /// The to test
- /// if is a P/Invoke declaration or if not
- ///
- /// LibraryImportAttribute is intentionally NOT reported as a P/Invoke. It uses different qualifiers and,
- /// technically, is NOT a P/Invoke signature (It's a marker for a Roslyn source generator. The generated function
- /// contains the marshaling with a nested private P/Invoke using NO marshaling)
- ///
- public static bool IsPInvoke(this MethodDeclarationSyntax self)
- {
- return self.IsStatic()
- && self.IsExtern()
- && self.HasAttribute("System.Runtime.InteropServices.DllImportAttribute");
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/NestedClassName.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/NestedClassName.cs
deleted file mode 100644
index 7aea1b6ef..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/NestedClassName.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-// 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.
-
-// Originally FROM: https://andrewlock.net/creating-a-source-generator-part-5-finding-a-type-declarations-namespace-and-type-hierarchy/
-// Modified to support IEquatable for caching
-// Additional functionality as needed to generalize it.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Cacheable storage of nested class names for use in source generation
- public sealed class NestedClassName
- : IEquatable
- {
- /// Initializes a new instance of the class.
- /// Keyword for this declaration
- /// Name of the type
- /// Constraints for this type
- /// Names of any nested child types to form hiearachies
- ///
- /// is normally one of ("class", "struct", "interface", "record [class|struct]?").
- ///
- public NestedClassName(string keyword, string name, string constraints, params IEnumerable children)
- {
- Keyword = keyword;
- Name = name;
- Constraints = constraints;
- Children = children.ToImmutableArray().AsEquatableArray();
- }
-
- /// Gets child nested types
- public EquatableArray Children { get; }
-
- /// Gets the keyword for this type
- ///
- /// This is normally one of ("class", "struct", "interface", "record [class|struct]?"
- ///
- public string Keyword { get; }
-
- /// Gets the name of the nested type
- public string Name { get; }
-
- /// Gets the constraints for a nested type
- public string Constraints { get; }
-
- /// Gets a value indicating whether this name contains constraints
- public bool HasConstraints => !string.IsNullOrWhiteSpace(Constraints);
-
- /// Compares this instance with another
- /// Value to compare this instance with
- /// if the is equal to this instance
- ///
- /// This is, at worst, a recursive O(n) operation! However, since it is used for nested types
- /// the actual depth is statistically rather small and nearly always 0 (Children is empty).
- /// Deeply nested type declarations is a VERY rare anti-pattern so not a real world problem.
- ///
- public bool Equals(NestedClassName other)
- {
- if (other == null)
- {
- return false;
- }
-
- if (ReferenceEquals(this, other))
- {
- return true;
- }
-
- // NOTE: This is a recursive O(n) operation!
- return Equals(Children, other.Children)
- && Name.Equals( other.Name, StringComparison.Ordinal )
- && Constraints.Equals( other.Constraints, StringComparison.Ordinal );
- }
-
- ///
- public override bool Equals(object obj)
- {
- return obj is NestedClassName parentClass && Equals(parentClass);
- }
-
- ///
- public override int GetHashCode()
- {
- return HashCode.Combine(Children, Keyword, Name, Constraints);
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/Result.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/Result.cs
deleted file mode 100644
index 68af2179f..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/Result.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Container for a result or an error descriptor ()
- /// Value contained in the result [Constrained to ]
- ///
- ///
- /// It is debatable if an incremental generator should produce diagnostics. The official
- /// cookbook
- /// recommends against it [Section: "Issue diagnostics"]. Instead it recommends use of an analyzer. While it
- /// doesn't say what a generator is supposed to do in the event of an input error explicitly, it is implied
- /// that it should silently ignore them.
- ///
- /// This type allows generating diagnostics in the final source production stage of the pipeline by plumbing
- /// through all of the available data AND diagnostics via this generic record. This acts as a sort of
- /// discriminated union of results or diagnostics (or possibly a combination of both). All while maintaining
- /// support for caching with .
- ///
- ///
- public readonly record struct Result
- where T : IEquatable
- {
- /// Initializes a new instance of the struct from a value [No diagnostics]
- /// Value of the result
- public Result(T value)
- : this(value, [])
- {
- }
-
- /// Initializes a new instance of the struct from diagnostics
- /// Information describing the diagnostics for this result
- public Result(params IEnumerable diagnostics)
- : this(default, [.. diagnostics])
- {
- }
-
- /// Initializes a new instance of the struct from a nullable value and set of potentially empty diagnostics
- /// Value of the result (may be null to indicate no results)
- /// Array of to describe any diagnostics/warnings encountered while producing
- ///
- /// This is the most generalized from of constructor. It supports BOTH a value and diagnostics as it is possible that
- /// a value is producible, but there are warnings or other informative diagnostics to include with it. Attempts to construct
- /// a result with no value and no diagnostics throws an exception.
- ///
- /// Both and are or empty
- public Result(T? value, ImmutableArray diagnostics)
- {
- if (value is null && diagnostics.IsDefaultOrEmpty)
- {
- throw new ArgumentException($"Either {nameof(Value)} or {nameof(diagnostics)} must contain a value");
- }
-
- Value = value;
- Diagnostics = diagnostics;
- }
-
- /// Gets the value produced for this result or if no value produced
- public T? Value { get; init; } = default;
-
- /// Gets a value indicating whether a value was produced for this result
- public bool HasValue => Value is not null;
-
- /// Gets the diagnostics produced for this result (if any)
- /// This may provide an empty array but is never
- public EquatableArray Diagnostics { get; init; } = ImmutableArray.Empty;
-
- /// Gets a value indicating whether this result contains any diagnostics
- /// This is a shorthand for testing the length of the property
- public bool HasDiagnostics => !Diagnostics.IsEmpty;
-
- /// Report all diagnostics to the provided
- /// to report the diagnostics to
- ///
- /// This supports the deferral of reporting with a collection of cahceable . This allows
- /// for a generatr to report critical internal problems.
- ///
- public void ReportDiagnostics(SourceProductionContext ctx)
- {
- foreach (var di in Diagnostics)
- {
- ctx.ReportDiagnostic(di.CreateDiagnostic());
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/RoslynExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/RoslynExtensions.cs
deleted file mode 100644
index ba45e641a..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/RoslynExtensions.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility class for general Roslyn extensions
- ///
- /// This is a place-holder for extensions that don't fit anywhere else and don't really warrant their own type/file.
- ///
- public static class RoslynExtensions
- {
- /// Gets an identifier name or () if the is not
- /// to get the identifier from
- /// Identifier name
- /// is
- [SuppressMessage( "Style", "IDE0046:Convert to conditional expression", Justification = "Nested conditionals are NOT simpler" )]
- public static string GetIdentifierName(this AttributeSyntax self)
- {
- if(self is null)
- {
- throw new ArgumentNullException(nameof(self));
- }
-
- return self.Name is not IdentifierNameSyntax identifier
- ? string.Empty
- : identifier.Identifier.ValueText;
- }
-
- /// Adds a source file from a manifest resource
- /// The to add the source to
- /// Assembly hosting the resource
- /// Name of the resource
- /// Hint name for the generated file
- /// Encoding for the source [Default: ]
- public static void AddSourceFromResource(
- this IncrementalGeneratorPostInitializationContext self,
- Assembly resourceAssembly,
- string resourceName,
- string hintName,
- Encoding? encoding = null
- )
- {
- encoding ??= Encoding.UTF8;
- using var reader = new StreamReader(resourceAssembly.GetManifestResourceStream(resourceName), encoding);
- self.AddSource(hintName, SourceText.From(reader, checked((int)reader.BaseStream.Length), encoding));
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/SourceProductionContextExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/SourceProductionContextExtensions.cs
deleted file mode 100644
index d48f94280..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/SourceProductionContextExtensions.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility class to provide extensions for a
- public static class SourceProductionContextExtensions
- {
- /// Reports deferred diagnostics for a
- /// Type of the result values
- /// The context to report any diagnostics to
- /// The result
- ///
- /// if has no diagnostics associated with it this is a NOP.
- ///
- public static void ReportDiagnostic(this SourceProductionContext self, Result result)
- where T : IEquatable
- {
- if(result.HasDiagnostics)
- {
- for(int i = 0; i < result.Diagnostics.Length; ++i)
- {
- self.ReportDiagnostic(result.Diagnostics[i]);
- }
- }
- }
-
- /// Reports a diagnostic to
- /// The context to report the diagnostic to
- /// Cached info to report
- public static void ReportDiagnostic( this SourceProductionContext self, DiagnosticInfo info)
- {
- self.ReportDiagnostic(info.CreateDiagnostic());
- }
-
- /// Reports a diagnostic to
- /// The context to report the diagnostic to
- /// Descriptor of the diagnostic
- /// Message arguments
- public static void ReportDiagnostic( this SourceProductionContext self, DiagnosticDescriptor descriptor, params object[] messageArgs)
- {
- self.ReportDiagnostic(Diagnostic.Create(descriptor, null, messageArgs));
- }
-
- /// Reports a diagnostic to
- /// The context to report the diagnostic to
- /// Location of the source of this diagnostic
- /// Descriptor for the diagnostic
- /// Argumnets, if any, for the diagnostic message
- public static void ReportDiagnostic(
- this SourceProductionContext self,
- Location location,
- DiagnosticDescriptor descriptor,
- params object[] messageArgs
- )
- {
- self.ReportDiagnostic(Diagnostic.Create(descriptor, location, messageArgs));
- }
-
- /// Reports a diagnostic to
- /// The context to report the diagnostic to
- /// Node as the source of the diagnostic
- /// Descriptor for the diagnostic
- /// Argumnets, if any, for the diagnostic message
- public static void ReportDiagnostic(
- this SourceProductionContext self,
- CSharpSyntaxNode node,
- DiagnosticDescriptor descriptor,
- params object[] messageArgs
- )
- {
- self.ReportDiagnostic(node.GetLocation(), descriptor, messageArgs);
- }
-
- /// Report diagnostics for results to
- /// Type of the result
- /// The context to report the diagnostic to
- /// Array of for the results
- public static void ReportDiagnostics( this SourceProductionContext self, ImmutableArray> results)
- where T : IEquatable
- {
- for(int i = 0; i < results.Length; ++i)
- {
- self.ReportDiagnostic(results[i]);
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/StringBuilderText.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/StringBuilderText.cs
deleted file mode 100644
index 628ea851a..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/StringBuilderText.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// A implementation over a
- ///
- /// This provides a implementation over a
- /// it provides access to the underlying builder to allow construction of an
- /// to manage indentation in the output. Manual generation of the output with indentation tracking is the
- /// recommended approach to generating source output.
- ///
- ///
- public class StringBuilderText
- : SourceText
- {
- /// Initializes a new instance of the class
- /// Builder to use for building strings
- /// Encoding to use for the strings
- /// Hash algorithm to use for debug symbols in the source
- public StringBuilderText(StringBuilder builder, Encoding encoding, SourceHashAlgorithm algorithm = SourceHashAlgorithm.Sha1)
- : base(checksumAlgorithm: algorithm)
- {
- Builder = builder;
- InternalEncoding = encoding;
- }
-
- /// Initializes a new instance of the class
- /// Encoding to use for the strings
- /// Hash algorithm to use for debug symbols in the source
- ///
- /// This constructor overload will create a new as the underlying
- /// store for the strings. This is likely the most common case.
- ///
- public StringBuilderText(Encoding encoding, SourceHashAlgorithm algorithm = SourceHashAlgorithm.Sha1)
- : this(new StringBuilder(), encoding, algorithm)
- {
- }
-
- /// Creates a new over the internal
- /// The newly created
- ///
- /// The created, does NOT dispose of or invalidate the underlying
- /// . This allows things like
- /// to work even after is called.
- /// The created writer is commonly wrapped in an instance of
- /// for generating source output in a source generator.
- ///
- public StringWriter CreateWriter()
- {
- return new StringWriter(Builder);
- }
-
- /// Gets the internal builder
- public StringBuilder Builder { get; init; }
-
- ///
- public override char this[int position] => Builder[position];
-
- ///
- public override Encoding Encoding => InternalEncoding;
-
- ///
- public override int Length => Builder.Length;
-
- ///
- public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
- {
- Builder.CopyTo(sourceIndex, destination, destinationIndex, count);
- }
-
- /// Converts the specified span in the underlying builder into a string
- /// Span to convert
- /// Text from the builder as a string
- public override string ToString(TextSpan span)
- {
- return Builder.ToString(span.Start, span.Length);
- }
-
- private readonly Encoding InternalEncoding;
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/SyntaxTokenListExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/SyntaxTokenListExtensions.cs
deleted file mode 100644
index bf0287dd9..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/SyntaxTokenListExtensions.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility class for extensions to
- public static class SyntaxTokenListExtensions
- {
- /// Gets a value indicating whether has the "extern" keyword
- /// to test
- /// if the keyword is found if not
- public static bool HasExtern(this SyntaxTokenList self)
- {
- return self.Any(SyntaxKind.ExternKeyword);
- }
-
- /// Gets a value indicating whether has the "partial" keyword
- ///
- public static bool HasPartialKeyword(this SyntaxTokenList self)
- {
- return self.Any(SyntaxKind.PartialKeyword);
- }
-
- /// Gets a value indicating whether has the "static" keyword
- ///
- public static bool HasStatic(this SyntaxTokenList self)
- {
- return self.Any(SyntaxKind.StaticKeyword);
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/TypeSyntaxExtensions.cs b/src/Ubiquity.NET.CodeAnalysis.Utils/TypeSyntaxExtensions.cs
deleted file mode 100644
index 4088b132c..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/TypeSyntaxExtensions.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CodeAnalysis.Utils
-{
- /// Utility class to provide extensions for
- public static class TypeSyntaxExtensions
- {
- /// Tests if is a string
- /// to test
- /// if is a string and if not
- public static bool IsString(this TypeSyntax? self)
- {
- return (self is PredefinedTypeSyntax pts && pts.Keyword.IsKind(SyntaxKind.StringKeyword))
- || (self is QualifiedNameSyntax qns && qns.Left.ToString() == "System" && qns.Right.ToString() == "String");
- }
-
- /// Tests if is a void
- /// to test
- /// if is a void and if not
- public static bool IsVoid(this TypeSyntax? self)
- {
- return self is PredefinedTypeSyntax pts
- && pts.Keyword.IsKind(SyntaxKind.VoidKeyword);
- }
- }
-}
diff --git a/src/Ubiquity.NET.CodeAnalysis.Utils/Ubiquity.NET.CodeAnalysis.Utils.csproj b/src/Ubiquity.NET.CodeAnalysis.Utils/Ubiquity.NET.CodeAnalysis.Utils.csproj
deleted file mode 100644
index 0d7dabb50..000000000
--- a/src/Ubiquity.NET.CodeAnalysis.Utils/Ubiquity.NET.CodeAnalysis.Utils.csproj
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
- netstandard2.0
- enable
-
-
- preview
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
diff --git a/src/Ubiquity.NET.CommandLine.UT/ArgumentExceptionReporterTests.cs b/src/Ubiquity.NET.CommandLine.UT/ArgumentExceptionReporterTests.cs
deleted file mode 100644
index 9e94e6a57..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/ArgumentExceptionReporterTests.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.Text;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-using Ubiquity.NET.CommandLine;
-
-namespace Ubiquity.NET.Commandline.UT
-{
- [TestClass]
- public class ArgumentExceptionReporterTests
- {
- private const string ParamExpressionName = "expression";
- private const string VerboseMessage = "This is a verbose";
- private const string InformationMessage = "This is an Information level message";
- private const string WarningMessage = "This is a warning";
- private const string ErrorMessage = "This is an error";
-
- [TestMethod]
- public void ArgumentExceptionReporterTest( )
- {
- var reporter = new ArgumentExceptionReporter(ParamExpressionName);
- Assert.IsNotNull( reporter );
- Assert.AreEqual( ParamExpressionName, reporter.ArgumentExpression );
- Assert.AreEqual( MsgLevel.Error, reporter.Level );
- Assert.AreEqual( Encoding.Unicode, reporter.Encoding );
- }
-
- [TestMethod]
- public void ReportTest( )
- {
- var reporter = new ArgumentExceptionReporter(ParamExpressionName);
-
- // should not throw for a Verbose level message
- var verboseMsg = new DiagnosticMessage()
- {
- Level = MsgLevel.Verbose,
- Text = VerboseMessage,
- };
-
- reporter.Report( verboseMsg );
-
- // should not throw for an Information level message
- var informationMsg = new DiagnosticMessage()
- {
- Level = MsgLevel.Information,
- Text = InformationMessage,
- };
-
- reporter.Report( verboseMsg );
-
- // should not throw for a warning
- var warningMsg = new DiagnosticMessage()
- {
- Level = MsgLevel.Warning,
- Text = WarningMessage,
- };
-
- reporter.Report( warningMsg );
-
- // should only throw for an error
- var errorMsg = new DiagnosticMessage()
- {
- Level = MsgLevel.Error,
- Text = ErrorMessage,
- };
-
- var ex = Assert.ThrowsExactly(()=>reporter.Report(errorMsg));
- Assert.AreSame( ParamExpressionName, ex.ParamName );
- Assert.StartsWith( ErrorMessage, ex.Message );
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine.UT/AssemblyInfo.cs b/src/Ubiquity.NET.CommandLine.UT/AssemblyInfo.cs
deleted file mode 100644
index f3266f005..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-// In SDK-style projects such as this one, several assembly attributes that were historically
-// defined in this file are now automatically added during build and populated with
-// values defined in project properties. For details of which attributes are included
-// and how to customize this process see: https://aka.ms/assembly-info-properties
-
-// Setting ComVisible to false makes the types in this assembly not visible to COM
-// components. If you need to access a type in this assembly from COM, set the ComVisible
-// attribute to true on that type.
-[assembly: ComVisible( false )]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM.
-[assembly: Guid( "994905c9-5cea-480a-b9fa-1458c5fc04d5" )]
-
-[assembly: CLSCompliant( false )]
-
-[assembly: Parallelize( Scope = ExecutionScope.ClassLevel )]
-[assembly: ExcludeFromCodeCoverage]
diff --git a/src/Ubiquity.NET.CommandLine.UT/CommandLineTests.cs b/src/Ubiquity.NET.CommandLine.UT/CommandLineTests.cs
deleted file mode 100644
index 229c375f8..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/CommandLineTests.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.CommandLine;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Ubiquity.NET.CommandLine.UT
-{
- [TestClass]
- public class CommandLineTests
- {
- [TestMethod]
- public void CommandLine_parse_with_version_option_only_succeeds( )
- {
- var settings = CreateTestSettings();
- var result = ArgsParsing.Parse(["--version"], settings);
-
- Assert.HasCount( 0, result.Errors, "Version alone should not procue errors" );
-
- var versionOption = result.GetVersionOption();
- Assert.IsNotNull(versionOption);
- Assert.AreEqual( versionOption.Action, result.Action);
- }
-
- [TestMethod]
- public void CommandLine_with_help_option_only_succeeds( )
- {
- var settings = CreateTestSettings();
-
- var result = ArgsParsing.Parse(["--help"], settings);
- Assert.HasCount( 0, result.Errors );
- }
-
- [TestMethod]
- public void CommandLine_with_unknown_option_has_errors( )
- {
- var settings = CreateTestSettings();
- ParseResult result = ArgsParsing.Parse(["--FooBar"], settings );
- Assert.HasCount( 2, result.Errors, "Errors should include missing Required, and invalid param" );
- }
-
- [TestMethod]
- public void CommandLine_with_known_option_and_version_has_errors( )
- {
- var settings = CreateTestSettings();
- ParseResult result = ArgsParsing.Parse(["--version", "--option1"], settings );
-
- Assert.HasCount( 1, result.Errors, "Should be one error (--version must be set alone) [Other errors ignored for --version]" );
- }
-
- [TestMethod]
- [Ignore("https://github.com/dotnet/command-line-api/issues/2664")]
- public void CommandLine_with_known_option_requiring_arg_and_version_has_errors( )
- {
- var settings = CreateTestSettings();
- ParseResult result = ArgsParsing.Parse(["--option1", "--version"], settings );
-
- // until https://github.com/dotnet/command-line-api/issues/2664 is resolved this will fail
- Assert.HasCount( 2, result.Errors, "Should be one error (--version must be set alone, missing arg for --option1)" );
- }
-
- internal static CmdLineSettings CreateTestSettings( DefaultOption defaultOptions = DefaultOption.Help | DefaultOption.Version )
- {
- return new CmdLineSettings()
- {
- DefaultOptions = defaultOptions,
- };
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine.UT/GlobalSuppressions.cs b/src/Ubiquity.NET.CommandLine.UT/GlobalSuppressions.cs
deleted file mode 100644
index a79c00f1d..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/GlobalSuppressions.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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.
-
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project.
-// Project-level suppressions either have no target or are given
-// a specific target and scoped to a namespace, type, member, etc.
-
-using System.Diagnostics.CodeAnalysis;
-
-[assembly: SuppressMessage( "StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Unit Tests" )]
-[assembly: SuppressMessage( "StyleCop.CSharp.DocumentationRules", "SA1652:Enable XML documentation output", Justification = "Unit Tests" )]
diff --git a/src/Ubiquity.NET.CommandLine.UT/ModuleFixtures.cs b/src/Ubiquity.NET.CommandLine.UT/ModuleFixtures.cs
deleted file mode 100644
index d54a29323..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/ModuleFixtures.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-#if USE_MODULE_FIXTURES
-using System;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Ubiquity.NET.CommandLine.UT
-{
- // Provides common location for one time initialization for all tests in this assembly
- [TestClass]
- public static class ModuleFixtures
- {
- [AssemblyInitialize]
- public static void AssemblyInitialize( TestContext ctx )
- {
- ArgumentNullException.ThrowIfNull( ctx );
- }
-
- [AssemblyCleanup]
- public static void AssemblyCleanup( )
- {
- }
- }
-}
-#endif
diff --git a/src/Ubiquity.NET.CommandLine.UT/RawApiTests.cs b/src/Ubiquity.NET.CommandLine.UT/RawApiTests.cs
deleted file mode 100644
index 888b32dd8..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/RawApiTests.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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.CommandLine;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Ubiquity.NET.CommandLine.UT
-{
- /// This is mostly for validation.understanding of the underlying RAW API as well as a good place to put "samples" for bug reports
- [TestClass]
- public class RawApiTests
- {
- [TestMethod]
- [Ignore( "https://github.com/dotnet/command-line-api/issues/2664" )]
- public void RawApi_Version_Error_tests( )
- {
- var rootCommand = new RootCommand("Test Root")
- {
- new Option("--option1")
- {
- Description = "Test option `",
- Required = true,
- },
- };
-
- var result = rootCommand.Parse(["--FooBar", "--version"]);
- Assert.HasCount( 3, result.Errors, "Errors should account for, bogus arg (`--FooBar`), missing required arg (`--option1`), AND that `--version` should be solo" );
- }
-
- [TestMethod]
- [Ignore( "https://github.com/dotnet/command-line-api/issues/2664" )]
- public void RawApi_Help_Error_tests( )
- {
- var rootCommand = new RootCommand("Test Root")
- {
- new Option("--option1")
- {
- Description = "Test option",
- Required = true,
- },
- };
-
- var result = rootCommand.Parse(["--FooBar", "--help"]);
- var helpOption = result.GetHelpOption();
- Assert.IsNotNull(helpOption);
- Assert.AreEqual(helpOption.Action, result.Action);
- Assert.HasCount( 3, result.Errors, "Errors should account for bogus arg (`--FooBar`), missing required arg (`--option1`), AND that `--version` should be solo" );
- }
-
- [TestMethod]
- public void RawApi_Version_Only_with_required_has_no_errors( )
- {
- var rootCommand = new RootCommand("Test Root")
- {
- new Option("--option1")
- {
- Description = "Test option `",
- Required = true,
- },
- };
-
- var result = rootCommand.Parse(["--version"]);
- Assert.HasCount( 0, result.Errors, "Should not be any errors" );
- }
-
- [TestMethod]
- [Ignore("https://github.com/dotnet/command-line-api/issues/2664")]
- public void RawApi_Version_with_required_option_has_errors( )
- {
- var rootCommand = new RootCommand("Test Root")
- {
- new Option("--option1")
- {
- Description = "Test option `",
- Required = true,
- },
- };
-
- ParseResult result = rootCommand.Parse(["--version", "--option1"]);
-
- // Known bug in runtime lib. This assert will fail - result.Errors.Count == 1!
- // result.Errors:
- // [0]{--version option cannot be combined with other arguments.}
- // [1]{Required argument missing for option: '--option1'.}
- Assert.HasCount( 2, result.Errors, "Should be two errors (version not used solo, missing arg)" );
-
- // try with arguments in reversed order (--version is later)
- result = rootCommand.Parse(["--option1", "--version"]);
-
- // result.Action == null! [BUG]
- // result.Errors.Count == 0! [BUG]
- Assert.HasCount( 2, result.Errors, "Should be two errors (version not used solo, missing arg)" );
- result = rootCommand.Parse("--option1 --version");
-
- // Known bug in runtime lib. This assert will fail - result.Errors.Count == 0!
- // result.Action == null! [BUG]
- // result.Errors.Count == 0! [BUG]
- Assert.HasCount( 2, result.Errors, "Should be two errors (version not used solo, missing arg)" );
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine.UT/SettingsTestExtensions.cs b/src/Ubiquity.NET.CommandLine.UT/SettingsTestExtensions.cs
deleted file mode 100644
index 5b17167ab..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/SettingsTestExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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.Collections.Immutable;
-using System.IO;
-
-namespace Ubiquity.NET.CommandLine.UT
-{
- internal static class SettingsTestExtensions
- {
- public static ImmutableArray GetOutput( this StringWriter self )
- {
- ArgumentNullException.ThrowIfNull( self );
- string underlyingString = self.ToString();
- return string.IsNullOrWhiteSpace( underlyingString )
- ? []
- : [ .. underlyingString.Split( self.NewLine, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries ) ];
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine.UT/TestOptions.cs b/src/Ubiquity.NET.CommandLine.UT/TestOptions.cs
deleted file mode 100644
index b87f1c62b..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/TestOptions.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine.UT
-{
- internal partial class TestOptions
- {
- public string Option1 { get; init; } = string.Empty;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine.UT/TestOptions.g.cs b/src/Ubiquity.NET.CommandLine.UT/TestOptions.g.cs
deleted file mode 100644
index 531e436fb..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/TestOptions.g.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.CommandLine;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Ubiquity.NET.CommandLine.UT
-{
- // FUTURE: Generate this with source generator from attributes in other partial declaration
- internal partial class TestOptions
- : ICommandLineOptions
- {
- public static TestOptions Bind( ParseResult parseResult )
- {
- return new()
- {
- Option1 = parseResult.GetValue(Descriptors.Option1),
- };
- }
-
- public static AppControlledDefaultsRootCommand BuildRootCommand( CmdLineSettings settings )
- {
- return new( settings, "Test option root command")
- {
- Descriptors.Option1,
- };
- }
-
- internal static class Descriptors
- {
- internal static Option Option1
- = new("--option1")
- {
- Description = "Test Option",
- Required = true, // Should have no impact on Help/Version
- };
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine.UT/Ubiquity.NET.CommandLine.UT.csproj b/src/Ubiquity.NET.CommandLine.UT/Ubiquity.NET.CommandLine.UT.csproj
deleted file mode 100644
index dcafb15ac..000000000
--- a/src/Ubiquity.NET.CommandLine.UT/Ubiquity.NET.CommandLine.UT.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- net8.0
- false
- True
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Ubiquity.NET.CommandLine/AppControlledDefaultsRootCommand.cs b/src/Ubiquity.NET.CommandLine/AppControlledDefaultsRootCommand.cs
deleted file mode 100644
index a78573455..000000000
--- a/src/Ubiquity.NET.CommandLine/AppControlledDefaultsRootCommand.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Extension of that allows app control of defaults that are otherwise forced
- ///
- /// This type is derived from and offers no additional behavior beyond the construction.
- /// The constructor will adapt the command based on the provided. This moves the
- /// hard coded defaults into an app controlled domain. The default constructed settings matches the behavior of
- /// 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.
- ///
- [SuppressMessage( "Design", "CA1010:Generic interface should also be implemented", Justification = "Collection initialization" )]
- public class AppControlledDefaultsRootCommand
- : RootCommand
- {
- /// Initializes a new instance of the class.
- /// Description of this root command
- /// Settings to apply for the command parsing
- public AppControlledDefaultsRootCommand( CmdLineSettings settings, string description = "" )
- : base( description )
- {
- ArgumentNullException.ThrowIfNull(settings);
-
- // RootCommand constructor already adds HelpOption and VersionOption so remove them
- // unless specified by caller.
- var removeableOptions = from o in Options
- where (o is HelpOption && !settings.DefaultOptions.HasFlag(DefaultOption.Help))
- || (o is VersionOption && !settings.DefaultOptions.HasFlag(DefaultOption.Version))
- select o;
-
- // .ToArray forces duplication of the enumeration to prevent exception from modifying
- // the underlying list while enumerating.
- foreach(var o in removeableOptions.ToArray())
- {
- Options.Remove( o );
- }
-
- // RootCommand constructor adds the "SuggestDirective" directive.
- if(!settings.DefaultDirectives.HasFlag( DefaultDirective.Suggest ))
- {
- // Remove default added and start clean.
- Directives.Clear();
- }
-
- // Add additional directives based on app controlled settings
- if(settings.DefaultDirectives.HasFlag( DefaultDirective.Diagram ))
- {
- Add( new DiagramDirective() );
- }
-
- if(settings.DefaultDirectives.HasFlag( DefaultDirective.EnvironmentVariables ))
- {
- Add( new EnvironmentVariablesDirective() );
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/ArgsParsing.cs b/src/Ubiquity.NET.CommandLine/ArgsParsing.cs
deleted file mode 100644
index af5b31595..000000000
--- a/src/Ubiquity.NET.CommandLine/ArgsParsing.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Results of invoking the default handlers for or
- /// Indicates whether the caller should exit (either it was handled successfully or an error was reported)
- /// Exit code from the invocation (only valid if is
- [SuppressMessage( "StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Simple record used by this type" )]
- public readonly record struct DefaultHandlerInvocationResult( bool ShouldExit, int ExitCode );
-
- /// Static utility class to provide parsing of command lines
- public static class ArgsParsing
- {
- /// Parses the command line
- /// Type of value to bind the results to [Must implement ]
- /// args array for the command line
- /// Settings for the parse
- /// Results of the parse
- ///
- /// Additional steps might include:
- ///
- /// 1) App specific Validation/semantic analysis
- /// 2) Binding of results to an app specific type
- /// 3) Act on the results as proper for the application
- /// a. This might include actions parsed but generally isolating the various stages is an easier to understand/maintain model
- /// b. Usually this is just app specific code that uses the bound results to adapt behavior
- ///
- ///
- /// This isolation of stages fosters clean implementation AND allows for variances not considered or accounted for in the
- /// parsing library. (For instance mutual exclusion of options etc...) validation is an APP specific thing. There
- /// may well be common validations available for re-use. But ultimately the relationships of all options etc... are dependent
- /// on the app and sometimes the runtime environment. (i.e., Should an app maintain strict adherence to a command line options
- /// even when such options/patterns are NOT the norm on that environment/OS?)
- /// The system already confuses the help and version "options" as they are conceptually
- /// "commands" in terms of that library. To be fair, the POSIX description it is based on confuses the point as well. This
- /// ambiguity continues by attaching actions and validation to many symbols. While that might seem like it's a good thing,
- /// almost every app needs to customize the behavior. Some apps simply can't do so using the current models. Thus, this
- /// implementation simply removes the actions and validation to leave both stages to the calling application as it keeps
- /// things clearer when stages are unique
- ///
- ///
- public static ParseResult Parse( string[] args, CmdLineSettings? settings = null )
- where T : ICommandLineOptions
- {
- settings ??= new CmdLineSettings();
- RootCommand rootCommand = T.BuildRootCommand(settings);
- return rootCommand.Parse( args, settings );
- }
-
- /// Invokes default options ( or )
- /// Result of parse
- /// settings to determine if enabled (optimizes implementation to a skip if none set)
- /// Reporter to use to report any diagnostics (Including the "output" of the option)
- /// Results of the invocation (see remarks for details).
- ///
- /// The results of invoking defaults is a tuple of a flag indicating if the app should exit - default command handled,
- /// and the exit code for the application. The exit code is undefined if the flag indicates the app should not exit (e.g., not
- /// handled). If it is defined, then that is what the app should return. It may be 0 if the command had no errors. But if there
- /// was an error with the execution of the default option
- ///
- public static DefaultHandlerInvocationResult InvokeDefaultOptions(
- this ParseResult parseResult,
- CmdLineSettings settings,
- IDiagnosticReporter diagnosticReporter
- )
- {
- // OPTIMIZATION: skip this if not selected by settings
- if(!settings.DefaultOptions.HasFlag( DefaultOption.Help ) && !settings.DefaultOptions.HasFlag( DefaultOption.Version ))
- {
- return new( false, 0 );
- }
-
- // Find the options and only invoke the results action if it is one of the option's.
- // Sadly, there is no other way to provide the invocation configuration besides the
- // Invoke method on the results type.
- var helpOption = parseResult.GetHelpOption();
- var versionOption = parseResult.GetVersionOption();
- if((helpOption?.Action != null && parseResult.Action == helpOption.Action)
- || (versionOption?.Action != null && parseResult.Action == versionOption.Action)
- )
- {
- int exitCode = parseResult.Invoke(diagnosticReporter.CreateConfig());
- return new( true, exitCode );
- }
-
- // action doesn't match; "no-app-exit"
- // NOTE: Action won't match if it is for parse errors...
- return new( false, 0 );
- }
-
- /// Reports any error found during parsing
- /// Results of the parse
- /// Reporter to report parse errors to
- /// if errors found and if not
- public static bool ReportErrors( this ParseResult parseResult, IDiagnosticReporter diagnosticReporter )
- {
- if(parseResult.HasErrors())
- {
- foreach(var err in parseResult.Errors)
- {
- // CONSIDER: extract location from error?
- diagnosticReporter.Error( CultureInfo.CurrentCulture, err.Message );
- }
-
- return true;
- }
-
- return false;
- }
-
- /// Tries to parse a command line, and binds the results to a value
- /// Type of the value to bind the results to
- /// Arguments to parse
- /// settings to use for the parse
- /// Reporter to use for diagnostic reporting
- /// Resulting value if parsed successfully
- /// Exit code for the process (only valid when return is (see remarks)
- /// if the app should continue and if not
- ///
- /// Since this wraps several common operations, some of which may require exiting the app, the return value
- /// has the semantics of "App should continue". In the event of parse errors or failures in invocation of
- /// the default options the result is a with an set to
- /// a proper exit code value. (non-zero for errors and zero for success even though the app should still
- /// exit)
- ///
- /// This wraps the common pattern of parsing a command line, invoking default options, and binding the results of a parse
- /// using a standard .NET "try pattern". The invocation of default options may return with
- /// set to 0. This indicates the parse was successful AND that the default option was
- /// run successfully and the app should exit.
- ///
- /// In short, this wraps the following sequence of common operations and exiting on completion of
- /// any operation with errors or successful invocation of default options:
- /// 1)
- /// 2)
- /// 3)
- /// 4)
- ///
- /// The is set to the exit code for the app on failures. This code indicates the
- /// parse errors and is the result of invoking which, as of the current release,
- /// is always 1, though this behavior is not documented and therefore subject to change. Thus, calling applications
- /// should ***NOT*** rely on this value and instead use their own value to indicate a parse error that is documented
- /// and stable.
- ///
- public static bool TryParse(
- string[] args,
- CmdLineSettings? settings,
- IDiagnosticReporter diagnosticReporter,
- [MaybeNullWhen( false )] out T boundValue,
- out int exitCode
- )
- where T : ICommandLineOptions
- {
- settings ??= new CmdLineSettings();
- boundValue = default;
- RootCommand rootCommand = T.BuildRootCommand(settings);
- ParseResult parseResult = rootCommand.Parse( args, settings );
-
- // Special case the default options (Help/Version) before checking for reported errors
- // as errors about missing required params when the defaults are used is actually "normal"
- // (Ridiculously stupid, but considered normal by owners of System.CommandLine [sigh...])
- var invokeResults = parseResult.InvokeDefaultOptions(settings, diagnosticReporter);
- if(invokeResults.ShouldExit)
- {
- exitCode = invokeResults.ExitCode;
- return false;
- }
-
- if(parseResult.Action is ParseErrorAction pea)
- {
- pea.ShowHelp = settings.ShowHelpOnErrors;
- pea.ShowTypoCorrections = settings.ShowTypoCorrections;
- exitCode = pea.Invoke(parseResult);
- return false;
- }
-
- boundValue = T.Bind( parseResult );
- exitCode = 0;
- return true;
- }
-
- ///
- public static bool TryParse( string[] args, CmdLineSettings settings, [MaybeNullWhen( false )] out T boundValue, out int exitCode )
- where T : ICommandLineOptions
- {
- return TryParse( args, settings, new ConsoleReporter( MsgLevel.Information ), out boundValue, out exitCode );
- }
-
- ///
- public static bool TryParse( string[] args, [MaybeNullWhen( false )] out T boundValue, out int exitCode )
- where T : ICommandLineOptions
- {
- return TryParse( args, settings: null, new ConsoleReporter( MsgLevel.Information ), out boundValue, out exitCode );
- }
-
- ///
- public static bool TryParse( string[] args, IDiagnosticReporter diagnosticReporter, [MaybeNullWhen( false )] out T boundValue, out int exitCode )
- where T : ICommandLineOptions
- {
- return TryParse( args, settings: null, diagnosticReporter, out boundValue, out exitCode );
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/ArgumentExceptionReporter.cs b/src/Ubiquity.NET.CommandLine/ArgumentExceptionReporter.cs
deleted file mode 100644
index b46f70b4b..000000000
--- a/src/Ubiquity.NET.CommandLine/ArgumentExceptionReporter.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Implementation of that throws for any errors reported.
- public class ArgumentExceptionReporter
- : IDiagnosticReporter
- {
- /// Initializes a new instance of the class.
- /// Expression for the argument to throw exceptions for
- public ArgumentExceptionReporter( string exp )
- {
- ArgumentExpression = exp;
- }
-
- /// Gets the expression for the argument to throw exceptions for
- public string ArgumentExpression { get; }
-
- ///
- public MsgLevel Level => MsgLevel.Error;
-
- ///
- public Encoding Encoding => Encoding.Unicode;
-
- /// Any diagnostics with will throw an argument exception
- ///
- public void Report( DiagnosticMessage diagnostic )
- {
- if(this.IsEnabled(diagnostic.Level))
- {
- throw new ArgumentException(diagnostic.ToString(), ArgumentExpression);
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/CmdLineSettings.cs b/src/Ubiquity.NET.CommandLine/CmdLineSettings.cs
deleted file mode 100644
index 5eb446679..000000000
--- a/src/Ubiquity.NET.CommandLine/CmdLineSettings.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Flags to determine the default Options for an
- [Flags]
- public enum DefaultOption
- {
- /// No default options used
- None = 0,
-
- /// Include the default help option
- Help,
-
- /// Include the default version option
- Version,
- }
-
- /// Flags to determine the default directives supported for an
- [Flags]
- public enum DefaultDirective
- {
- /// No default directives included
- None = 0,
-
- /// Include support for
- Suggest,
-
- /// Include support for
- Diagram,
-
- /// Include support for
- EnvironmentVariables,
- }
-
- /// Contains settings for parsing a command line
- ///
- /// This is effectively an extension to adding control
- /// of the default options and directives. This is used with
- /// to adapt the defaults otherwise forced by . Of particular interest is the
- /// which, if not set uses the default from
- /// which is not publicly available. If the value
- /// is set to then no replacer is used or supported. If it is set to a non-null value
- /// then that replacer is used.
- /// The default values follows the default behaviors of the underlying library. This ensures the
- /// principle of least surprise while allowing for explicit overrides
- ///
- public class CmdLineSettings
- {
- /// Gets a value indicating whether errors reported should also show the help message [Default: ]
- /// This has a default, which is the opposite of the default from
- public bool ShowHelpOnErrors { get; init; } = true;
-
- /// Gets a value indicating whether errors reported should also show Typo corrections [Default: ]
- /// This has a default, which is the opposite of the default from
- public bool ShowTypoCorrections { get; init; } = false;
-
- ///
- public bool EnablePosixBundling { get; init; } = true;
-
- /// Gets a value that indicates the default options to include
- ///
- /// Default handling includes and .
- /// This allows overriding that to specify behavior as needed.
- ///
- public DefaultOption DefaultOptions { get; init; } = DefaultOption.Help | DefaultOption.Version;
-
- /// Gets a value that indicates the default Directives to include
- ///
- /// Default handling includes .
- /// This allows overriding that to specify behavior as needed.
- ///
- public DefaultDirective DefaultDirectives { get; init; } = DefaultDirective.Suggest;
-
- /// Gets a response file token replacer. [Default: internal common token replacement]
- ///
- /// Unless explicitly set the default behavior, which is not otherwise accessible, is used.
- ///
- /// Any option preceded by a '@' will trigger a call to this delegate if specified. The `tokenToReplace`
- /// parameter to the delegate is the characters following, but not including, the leading '@'. The default
- /// assumes that is a file name containing the command in a `Response` file. The default is normally what
- /// is used but, since it isn't directly accessible, this class helps in expressing the behavior.
- ///
- ///
- public TryReplaceToken? ResponseFileTokenReplacer
- {
- get;
- init
- {
- field = value;
- HasCustomeResponseFileBehavior = true;
- }
- }
-
- /// Constructs a new based on this instance
- /// new from this instance
- public ParserConfiguration ToParserConfiguration( )
- {
- ParserConfiguration retVal = new()
- {
- EnablePosixBundling = EnablePosixBundling,
- };
-
- // Don't set the behavior unless explicitly specified as the default
- // is not publicly accessible (and therefore cannot be expressed as
- // a value for this type).
- if(HasCustomeResponseFileBehavior)
- {
- retVal.ResponseFileTokenReplacer = ResponseFileTokenReplacer;
- }
-
- return retVal;
- }
-
- private bool HasCustomeResponseFileBehavior = false;
-
- /// Implicitly constructs a new based on an instance of
- /// The settings to build the configuration from
- public static implicit operator ParserConfiguration( CmdLineSettings self )
- {
- return self.ToParserConfiguration();
- }
-
- /// Gets a settings with defaults for options and directives removed
- ///
- /// The "default" support for help and version is rather inflexible and an "all or nothing"
- /// approach. (with late bug fix hacks [https://github.com/dotnet/command-line-api/issues/2659]
- /// to resolve issues). Thus, this simply removes them and leaves it to the calling app to
- /// specify them explicitly as a custom option. Then validation is customized to handle
- /// behavior as desired by the app.
- ///
- public static CmdLineSettings NoDefaults { get; }
- = new()
- {
- DefaultDirectives = DefaultDirective.None,
- DefaultOptions = DefaultOption.None,
- ResponseFileTokenReplacer = null,
- EnablePosixBundling = false,
- };
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/ColoredConsoleReporter.cs b/src/Ubiquity.NET.CommandLine/ColoredConsoleReporter.cs
deleted file mode 100644
index ec2c10061..000000000
--- a/src/Ubiquity.NET.CommandLine/ColoredConsoleReporter.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Implementation of that uses colorized console output
- public sealed class ColoredConsoleReporter
- : ConsoleReporter
- {
- /// Initializes a new instance of the class
- /// Level of messages to enable for this reporter [Default:
- /// Provides the color mapping for the message levels this reporter will use (see remarks)
- ///
- /// (or a default if ) is set as the property.
- ///
- /// The default colors, if not provided via , are:
- ///
- /// LevelDescription
- ///
- ///
- ///
- ///
- ///
- ///
- /// Any level not in is reported using .
- ///
- ///
- [SetsRequiredMembers]
- public ColoredConsoleReporter( MsgLevel level = MsgLevel.Information, ImmutableDictionary? colorMapping = null)
- : base(level)
- {
- ColorMap = colorMapping ?? ImmutableDictionary.Empty;
- }
-
- /// Gets the to colorMapping used for coloring
- public ImmutableDictionary ColorMap
- {
- get => field.IsEmpty ? DefaultColorMap : field;
- init
- {
- ArgumentNullException.ThrowIfNull(value);
- field = value;
- }
- }
-
- /// Gets the default color map for this type
- public static ImmutableDictionary DefaultColorMap { get; }
- = new DictionaryBuilder
- {
- [MsgLevel.Verbose] = Color.LtBlue,
- [MsgLevel.Information] = Color.Default,
- [MsgLevel.Warning] = Color.LtYellow,
- [MsgLevel.Error] = Color.LtRed,
- }.ToImmutable();
-
- ///
- /// This implementation will apply ANSI color code sequences to each message based on .
- ///
- ///
- protected override void ReportMessage( MsgLevel level, string msg )
- {
- if(!ColorMap.TryGetValue(level, out AnsiCode? color))
- {
- color = Color.Default;
- }
-
- // use base to write to the correct stream
- base.ReportMessage( level, $"{color}{msg}{Reset.All}" );
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/ConsoleReporter.cs b/src/Ubiquity.NET.CommandLine/ConsoleReporter.cs
deleted file mode 100644
index bfea22793..000000000
--- a/src/Ubiquity.NET.CommandLine/ConsoleReporter.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Implementation of that reports messages to a
- ///
- /// Messages with a of are reported to the console's
- /// writer, while other levels, if enabled, are reported to the console's writer.
- ///
- public class ConsoleReporter
- : TextWriterReporter
- {
- /// Initializes a new instance of the class.
- /// Level of messages to enable for this reporter [Default:
- ///
- /// Any message reported with a level that is greater than or equal to
- /// is enabled, and thus reported.
- ///
- /// The stream is used for . Any other message level
- /// goes to .
- ///
- ///
- [SetsRequiredMembers]
- public ConsoleReporter( MsgLevel level = MsgLevel.Information)
- : base(level, Console.Error, Console.Out, Console.Out, Console.Out)
- {
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/DiagnosticMessage.cs b/src/Ubiquity.NET.CommandLine/DiagnosticMessage.cs
deleted file mode 100644
index bf3c6eb51..000000000
--- a/src/Ubiquity.NET.CommandLine/DiagnosticMessage.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Tool Message category
- public enum MsgLevel
- {
- /// All channels off
- None = 0,
-
- /// Verbose messages (or higher) are enabled
- Verbose = 100,
-
- /// Informational messages (or higher) are enabled.
- Information = 200,
-
- /// Warning messages (or higher) are enabled. [This is the default value]
- Warning = 300, // Default level is warning & error only
-
- /// Error messages (or higher) are enabled.
- Error = 400,
- }
-
- /// Diagnostic message for reporting diagnostics as part of end-user facing experience (UX)
- ///
- /// must NOT be localized. It is required to universally identify a
- /// particular message. should be localized if the source tool supports
- /// localization.
- /// Diagnostic codes () are of the form <prefix><number>
- /// (example: FOO01234). This is a unique identifier for the message that allows a user to reference
- /// it for support or other diagnostic analysis. The <prefix> portion of the code indicates
- /// the application source of the message.
- ///
- public readonly record struct DiagnosticMessage
- : IFormattable
- {
- /// Gets the origin of the message
- public Uri? Origin { get; init; }
-
- /// Gets the location in source for the origin of this message
- public SourceRange? Location { get; init; }
-
- /// Gets the subcategory of the message
- public string? Subcategory { get; init; }
-
- /// Gets the Level/Category of the message
- public MsgLevel Level { get; init; }
-
- /// Gets the code for the message (No spaces)
- public string? Code
- {
- get;
- init
- {
- if(value is not null && value.Any( ( c ) => char.IsWhiteSpace( c ) ))
- {
- throw new ArgumentException( "If provided, code must not contain whitespace", nameof( value ) );
- }
-
- field = value;
- }
- }
-
- /// Gets the text of the message
- public string Text
- {
- get;
- init
- {
- ArgumentNullException.ThrowIfNull(value);
- field = value;
- }
- }
-
- /// Formats this instance using the general runtime specific format
- /// Formatted string for the message
- public override string ToString( )
- {
- // use runtime default formatting
- return ToString("G", CultureInfo.CurrentCulture);
- }
-
- ///
- ///
- /// Accepted format strings are:
- /// "M" for MSBuild format (used for Windows/MSBUILD build tools).
- /// "G" for runtime specific (For Windows, this is the same as the MSBuild format['M'])
- /// [Format strings for other runtimes TBD (L:Linux, A:Apple ... ????)]
- ///
- public string ToString( string? format, IFormatProvider? formatProvider )
- {
- formatProvider ??= CultureInfo.CurrentCulture;
- return format switch
- {
- "M" => FormatMsBuild( formatProvider ),
- "G" => FormatRuntime( formatProvider ),
- _ => throw new FormatException($"{format} is not a valid format specifier for {nameof(DiagnosticMessage)}")
- };
- }
-
- private string FormatMsBuild(IFormatProvider formatProvider)
- {
- if(Origin is null || string.IsNullOrWhiteSpace(Origin.AbsoluteUri))
- {
- return Text;
- }
-
- string locString = string.Empty;
- if(Location is not null)
- {
- locString = Location.Value.ToString( "M", formatProvider );
- }
-
- // account for optional values with leading space.
- string subCat = Subcategory is not null ? $" {Subcategory}" : string.Empty;
- string code = Code is not null ? $" {Code}" : string.Empty;
- string origin = Origin.IsFile ? Origin.LocalPath : Origin.ToString();
- return $"{origin}{locString} :{subCat} {Level}{code} : {Text}";
- }
-
- [SuppressMessage( "Style", "IDE0046:Convert to conditional expression", Justification = "Place holder for future work" )]
- [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:BlockStatementsMustNotContainEmbeddedComments", Justification = "Reviewed.")]
- private string FormatRuntime(IFormatProvider formatProvider)
- {
- if(OperatingSystem.IsWindows())
- {
- return FormatMsBuild(formatProvider);
- }
- else // TODO: Adjust this to format based on styles of additional runtimes
- {
- // for now - always use MSBUILD format
- return FormatMsBuild(formatProvider);
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/DiagnosticMessageCollection.cs b/src/Ubiquity.NET.CommandLine/DiagnosticMessageCollection.cs
deleted file mode 100644
index 263048320..000000000
--- a/src/Ubiquity.NET.CommandLine/DiagnosticMessageCollection.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Reporter that collects diagnostic information without reporting it in any UI/UX
- public class DiagnosticMessageCollection
- : IDiagnosticReporter
- , IReadOnlyCollection
- {
- /// Initializes a new instance of the class.
- /// Minimal reporting level for this collector [Default is to collect all messaged
- public DiagnosticMessageCollection( MsgLevel level = MsgLevel.Error )
- {
- Level = level;
- }
-
- ///
- public MsgLevel Level { get; }
-
- ///
- public Encoding Encoding => Encoding.Unicode;
-
- ///
- public int Count => Messages.Count;
-
- ///
- public void Report( DiagnosticMessage diagnostic )
- {
- if(this.IsEnabled( Level ))
- {
- Messages = Messages.Add( diagnostic );
- }
- }
-
- ///
- public IEnumerator GetEnumerator( )
- {
- return ((IEnumerable)Messages).GetEnumerator();
- }
-
- ///
- IEnumerator IEnumerable.GetEnumerator( )
- {
- return ((IEnumerable)Messages).GetEnumerator();
- }
-
- /// Gets the current list of messages received by this collector
- public ImmutableList Messages { get; private set; } = [];
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/DiagnosticReporterExtensions.cs b/src/Ubiquity.NET.CommandLine/DiagnosticReporterExtensions.cs
deleted file mode 100644
index 3ae5eb52c..000000000
--- a/src/Ubiquity.NET.CommandLine/DiagnosticReporterExtensions.cs
+++ /dev/null
@@ -1,725 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Extensions to for specific message levels
- public static class DiagnosticReporterExtensions
- {
- /// Gets a value indicating whether the specified level (and higher) messages are enabled
- /// Reporter to test
- /// Level to test if enabled
- /// if the level or higher messages are enabled or if not
- public static bool IsEnabled( this IDiagnosticReporter self, MsgLevel level )
- {
- return self.Level <= level;
- }
-
- #region Report
-
- /// Reports a message
- /// Reporter to use in reporting the message
- /// Message level
- /// Message text
- public static void Report( this IDiagnosticReporter self, MsgLevel level, string msg )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- var diagnostic = new DiagnosticMessage()
- {
- Origin = null,
- Location = default,
- Subcategory = default,
- Level = level,
- Code = default,
- Text = msg
- };
-
- self.Report( diagnostic );
- }
-
- /// Reports a message using an interpolated string
- /// Reporter to use in reporting the message
- /// Message level
- /// Origin for the source of this diagnostic
- /// Location in source relating to the diagnostic
- /// Interpolated string for the message (processed via )
- ///
- /// The will optimize (short circuit) the interpolation based on the value of
- /// . If a level is not enabled, then the handler will short circuit the rest of the
- /// interpolation. Thus, any methods with side effects may not be called and callers should not depend on them happening
- /// in all cases.
- ///
- public static void Report(
- this IDiagnosticReporter self,
- MsgLevel level,
- Uri? origin,
- SourceRange location,
- [InterpolatedStringHandlerArgument( "self", "level" )] DiagnosticReporterInterpolatedStringHandler handler
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(handler.IsEnabled)
- {
- var diagnostic = new DiagnosticMessage()
- {
- Origin = origin,
- Location = location,
- Subcategory = default,
- Level = level,
- Code = default,
- Text = handler.GetFormattedText()
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a message using an interpolated string
- /// Reporter to use in reporting the message
- /// Message level
- /// Location in source relating to the diagnostic
- /// Interpolated string for the message (processed via )
- ///
- /// The will optimize (short circuit) the interpolation based on the value of
- /// . If a level is not enabled, then the handler will short circuit the rest of the
- /// interpolation. Thus, any methods with side effects may not be called and callers should not depend on them happening
- /// in all cases.
- ///
- public static void Report(
- this IDiagnosticReporter self,
- MsgLevel level,
- SourceRange location,
- [InterpolatedStringHandlerArgument( "self", "level" )] DiagnosticReporterInterpolatedStringHandler handler
- )
- {
- Report(self, level, null, location, handler);
- }
-
- /// Reports a message using an interpolated string
- /// Reporter to use in reporting the message
- /// Message level
- /// Interpolated string for the message (processed via )
- ///
- /// The will optimize (short circuit) the interpolation based on the value of
- /// . If a level is not enabled, then the handler will short circuit the rest of the
- /// interpolation. Thus, any methods with side effects may not be called and callers should not depend on them happening
- /// in all cases.
- ///
- public static void Report(
- this IDiagnosticReporter self,
- MsgLevel level,
- [InterpolatedStringHandlerArgument( "self", "level" )] DiagnosticReporterInterpolatedStringHandler handler
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(handler.IsEnabled)
- {
- var diagnostic = new DiagnosticMessage()
- {
- Origin = null,
- Location = default,
- Subcategory = default,
- Level = level,
- Code = default,
- Text = handler.GetFormattedText()
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a message using classic string formatting
- /// Reporter to use in reporting the message
- /// Message level
- /// Origin for the source of this diagnostic
- /// Location in source relating to the diagnostic
- /// Format string for the message
- /// Arguments for the message
- public static void Report(
- this IDiagnosticReporter self,
- MsgLevel level,
- Uri? origin,
- SourceRange location,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- var diagnostic = new DiagnosticMessage()
- {
- Origin = origin,
- Location = location,
- Subcategory = default,
- Level = level,
- Code = default,
- Text = args.Length == 0 ? fmt : string.Format( CultureInfo.CurrentCulture, fmt, args )
- };
-
- self.Report( diagnostic );
- }
-
- /// Reports a message using classic string formatting
- /// Reporter to use in reporting the message
- /// Message level
- /// Location in source relating to the diagnostic
- /// Format string for the message
- /// Arguments for the message
- public static void Report(
- this IDiagnosticReporter self,
- MsgLevel level,
- SourceRange location,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Report(self, level, null, location, fmt, args);
- }
-
- /// Reports multiple diagnostics to the reporter
- /// Reporter to report the diagnostics to
- /// DIagnostics to report. This is a 'params' value so it is variadic in languages that support such a thing
- public static void Report( this IDiagnosticReporter self, params IEnumerable diagnostics )
- {
- foreach(var dm in diagnostics)
- {
- self.Report( dm );
- }
- }
- #endregion
-
- #region MsgLevel.Error
-
- // maintainer's note: Doc comments are inherited from the "Error" implementation (except the summary)
- // and therefore the verbiage of the full comments should remain neutral.
-
- /// Reports a level message to
- /// Reporter to report message to
- /// Identifier code for this message
- /// Location in the origin that this message refers to
- /// Origin of the diagnostic (Usually the origin is a File, but may be anything or nothing)
- /// Subcategory for this message
- /// Format provider to use when formatting the string
- /// Format string for the message
- /// Arguments for the message
- ///
- /// The reporter () may filter out any messages reported for this level. The
- /// is NOT applied to unless the level for the message is
- /// enabled. This helps reduce the overhead of producing the final formatted string if it is ignored anyway.
- ///
- public static void Error(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(self.IsEnabled(MsgLevel.Error))
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Error,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = string.Format(formatProvider, fmt, args),
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a a level message to
- /// Reporter to report message to
- /// Identifier code for this message
- /// Location in the origin that this message refers to
- /// Origin of the diagnostic (Usually the origin is a File, but may be anything or nothing)
- /// Subcategory for this message
- /// Interpolated string for the message (processed via )
- ///
- /// The reporter () may filter out any messages reported for this level. The
- /// is NOT applied to format the final message unless the level for the message is
- /// enabled. This helps reduce the overhead of producing the final formatted string if it is ignored anyway.
- ///
- public static void Error(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- [InterpolatedStringHandlerArgument( "self" )] ErrorReportingInterpolatedStringHandler handler
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(handler.IsEnabled)
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Error,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = handler.GetFormattedText()
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a level message to
- /// Reporter to report message to
- /// Exception to report
- /// Identifier code for this message
- /// Location in the origin that this message refers to
- /// Origin of the diagnostic (Usually the origin is a File, but may be anything or nothing)
- /// Subcategory for this message
- ///
- /// The reporter () may filter out any messages reported for level.
- ///
- public static void Error(
- this IDiagnosticReporter self,
- Exception ex,
- string? code = null,
- SourceRange location = default,
- Uri? origin = null,
- string? subCategory = null
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(self.IsEnabled(MsgLevel.Error))
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Error,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = ex.Message,
- };
-
- self.Report( diagnostic );
- }
- }
-
- ///
- public static void Error(
- this IDiagnosticReporter self,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Error(self, code: null, location: default, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Error(
- this IDiagnosticReporter self,
- SourceRange location,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Error(self, code: null, location, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Error(
- this IDiagnosticReporter self,
- [InterpolatedStringHandlerArgument( "self" )] ErrorReportingInterpolatedStringHandler handler
- )
- {
- Error(self, code: null, location: default, origin: null, subCategory: null, handler);
- }
-
- ///
- public static void Error(
- this IDiagnosticReporter self,
- SourceRange location,
- [InterpolatedStringHandlerArgument( "self" )] ErrorReportingInterpolatedStringHandler handler
- )
- {
- Error(self, code: null, location, origin: null, subCategory: null, handler);
- }
-
- // doc comments don't inherit param correctly, see: https://github.com/dotnet/roslyn/issues/67326#issuecomment-3452843800
-
- ///
- /// Reporter to report message to
- /// Message to report
- /// Location in the origin that this message refers to
- ///
- public static void Error(this IDiagnosticReporter self, string msg, SourceRange location = default)
- {
- Error(self, code: null, location, origin: null, subCategory: null, formatProvider: null, msg /*, args...*/);
- }
- #endregion
-
- #region MsgLevel.Warning
-
- /// Reports a level message to
- ///
- public static void Warning(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(self.IsEnabled(MsgLevel.Warning))
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Warning,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = string.Format(formatProvider, fmt, args),
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a level message to
- ///
- public static void Warning(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- [InterpolatedStringHandlerArgument( "self" )] WarningReportingInterpolatedStringHandler handler
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(handler.IsEnabled)
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Warning,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = handler.GetFormattedText()
- };
-
- self.Report( diagnostic );
- }
- }
-
- ///
- public static void Warning(
- this IDiagnosticReporter self,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Warning(self, code: null, location: default, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Warning(
- this IDiagnosticReporter self,
- SourceRange location,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Warning(self, code: null, location, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Warning(
- this IDiagnosticReporter self,
- [InterpolatedStringHandlerArgument( "self" )] WarningReportingInterpolatedStringHandler handler
- )
- {
- Warning(self, code: null, location: default, origin: null, subCategory: null, handler);
- }
-
- ///
- public static void Warning(
- this IDiagnosticReporter self,
- SourceRange location,
- [InterpolatedStringHandlerArgument( "self" )] WarningReportingInterpolatedStringHandler handler
- )
- {
- Warning(self, code: null, location, origin: null, subCategory: null, handler);
- }
-
- // doc comments don't inherit param correctly, see: https://github.com/dotnet/roslyn/issues/67326#issuecomment-3452843800
-
- ///
- /// Reporter to report message to
- /// Message to report
- /// Location in the origin that this message refers to
- ///
- public static void Warning( this IDiagnosticReporter self, string msg, SourceRange location = default )
- {
- Warning( self, code: null, location, origin: null, subCategory: null, formatProvider: null, msg /*, args...*/);
- }
- #endregion
-
- #region MsgLevel.Information
-
- /// Reports a level message to
- ///
- public static void Information(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(self.IsEnabled(MsgLevel.Information))
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Information,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = string.Format(formatProvider, fmt, args),
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a level message to
- ///
- public static void Information(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- [InterpolatedStringHandlerArgument( "self" )] InformationReportingInterpolatedStringHandler handler
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(handler.IsEnabled)
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Information,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = handler.GetFormattedText()
- };
-
- self.Report( diagnostic );
- }
- }
-
- ///
- public static void Information(
- this IDiagnosticReporter self,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Information(self, code: null, location: default, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Information(
- this IDiagnosticReporter self,
- SourceRange location,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Information(self, code: null, location, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Information(
- this IDiagnosticReporter self,
- [InterpolatedStringHandlerArgument( "self" )] InformationReportingInterpolatedStringHandler handler
- )
- {
- Information(self, code: null, location: default, origin: null, subCategory: null, handler);
- }
-
- ///
- public static void Information(
- this IDiagnosticReporter self,
- SourceRange location,
- [InterpolatedStringHandlerArgument( "self" )] InformationReportingInterpolatedStringHandler handler
- )
- {
- Information(self, code: null, location, origin: null, subCategory: null, handler);
- }
-
- // doc comments don't inherit param correctly, see: https://github.com/dotnet/roslyn/issues/67326#issuecomment-3452843800
-
- ///
- /// Reporter to report message to
- /// Message to report
- /// Location in the origin that this message refers to
- ///
- public static void Information( this IDiagnosticReporter self, string msg, SourceRange location = default )
- {
- Information( self, code: null, location, origin: null, subCategory: null, formatProvider: null, msg /*, args...*/);
- }
-
- #endregion
-
- #region MsgLevel.Verbose
-
- /// Reports a level message to
- ///
- public static void Verbose(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(self.IsEnabled(MsgLevel.Verbose))
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Verbose,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = string.Format(formatProvider, fmt, args),
- };
-
- self.Report( diagnostic );
- }
- }
-
- /// Reports a level message to
- ///
- public static void Verbose(
- this IDiagnosticReporter self,
- string? code,
- SourceRange location,
- Uri? origin,
- string? subCategory,
- [InterpolatedStringHandlerArgument( "self" )] VerboseReportingInterpolatedStringHandler handler
- )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- if(handler.IsEnabled)
- {
- var diagnostic = new DiagnosticMessage()
- {
- Code = code,
- Level = MsgLevel.Verbose,
- Location = location,
- Origin = origin,
- Subcategory = subCategory,
- Text = handler.GetFormattedText()
- };
-
- self.Report( diagnostic );
- }
- }
-
- ///
- public static void Verbose(
- this IDiagnosticReporter self,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Verbose(self, code: null, location: default, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Verbose(
- this IDiagnosticReporter self,
- SourceRange location,
- IFormatProvider? formatProvider,
- [StringSyntax( StringSyntaxAttribute.CompositeFormat )] string fmt,
- params object[] args
- )
- {
- Verbose(self, code: null, location, origin: null, subCategory: null, formatProvider, fmt, args);
- }
-
- ///
- public static void Verbose(
- this IDiagnosticReporter self,
- [InterpolatedStringHandlerArgument( "self" )] VerboseReportingInterpolatedStringHandler handler
- )
- {
- Verbose(self, code: null, location: default, origin: null, subCategory: null, handler);
- }
-
- ///
- public static void Verbose(
- this IDiagnosticReporter self,
- SourceRange location,
- [InterpolatedStringHandlerArgument( "self" )] VerboseReportingInterpolatedStringHandler handler
- )
- {
- Verbose(self, code: null, location, origin: null, subCategory: null, handler);
- }
-
- // doc comments don't inherit param correctly, see: https://github.com/dotnet/roslyn/issues/67326#issuecomment-3452843800
-
- ///
- /// Reporter to report message to
- /// Message to report
- /// Location in the origin that this message refers to
- ///
- public static void Verbose( this IDiagnosticReporter self, string msg, SourceRange location = default )
- {
- Verbose( self, code: null, location, origin: null, subCategory: null, formatProvider: null, msg /*, args...*/);
- }
- #endregion
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/GlobalNamespaceImports.cs b/src/Ubiquity.NET.CommandLine/GlobalNamespaceImports.cs
deleted file mode 100644
index 6e1097b80..000000000
--- a/src/Ubiquity.NET.CommandLine/GlobalNamespaceImports.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.
-
-/*
-NOTE:
-While the MsBuild `ImplicitUsings` property is banned from this repo, the C# language feature of global usings is NOT.
-The build property will auto include an invisible and undiscoverable (without looking up obscure documentation)
-set of namespaces that is NOT consistent or controlled by the developer. THAT is what is BAD/BROKEN about that feature.
-By banning it's use and then providing a `GlobalNamespaceImports.cs` source file with ONLY global using statements ALL of
-that is eliminated. Such use of the language feature restores FULL control and visibility of the namespaces to the developer,
-where it belongs. For a good explanation of this problem see: https://rehansaeed.com/the-problem-with-csharp-10-implicit-usings/.
-For an explanation of the benefits of the language feature see: https://www.hanselman.com/blog/implicit-usings-in-net-6
-*/
-
-global using System;
-global using System.Collections;
-global using System.Collections.Generic;
-global using System.Collections.Immutable;
-global using System.CommandLine;
-global using System.CommandLine.Completions;
-global using System.CommandLine.Help;
-global using System.CommandLine.Invocation;
-global using System.CommandLine.Parsing;
-global using System.ComponentModel;
-global using System.Diagnostics.CodeAnalysis;
-global using System.Globalization;
-global using System.IO;
-global using System.Linq;
-global using System.Runtime.CompilerServices;
-global using System.Text;
-
-global using AnsiCodes;
-
-global using Ubiquity.NET.CommandLine.InterpolatedStringHandlers;
-global using Ubiquity.NET.Extensions;
diff --git a/src/Ubiquity.NET.CommandLine/ICommandLineOptions.cs b/src/Ubiquity.NET.CommandLine/ICommandLineOptions.cs
deleted file mode 100644
index 97b290c46..000000000
--- a/src/Ubiquity.NET.CommandLine/ICommandLineOptions.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Interface for a root command in command line parsing
- /// Type of the command (CRTP)
- ///
- /// This only contains a static interface and thus requires the static abstract feature of the runtime.
- /// (.NET 7 or later) It is used to constrain methods to those that have static methods that are specifically
- /// designed for command line parsing.
- ///
- public interface ICommandLineOptions
- where T : ICommandLineOptions
- {
- /// Binds the results of the parse to a new instance of
- /// Results of the parse to bind
- /// Newly constructed instance of with properties bound from
- ///
- /// The implementation of this method allows pure source code AOT (Zero-Runtime-Reflection) binding.
- /// Normally this is generated by a source generator to leverage compile time reflection. But for simple
- /// applications hand generation is often used. (Until a generator is implemented that's the only
- /// option actually).
- ///
- /// Thrown when required argument or option was not parsed or has no default value configured.
- public static abstract T Bind( ParseResult parseResult );
-
- /// Builds a new for parsing the command line
- /// Settings to use for parsing
- /// New instance for
- ///
- ///
- /// The settings determine the default Options and Directives, etc... to add or remove from the command.
- /// contains hard coded defaults without any construction
- /// configuration. takes care of adding or removing things
- /// based on the to make the defaults app controlled.
- ///
- /// Normally, this just creates an instance of and initializes
- /// it with all of the s for a given command line
- /// The implementation of this method allows pure source code AOT (Zero-Runtime-Reflection) description.
- /// Normally this is generated by a source generator to leverage compile time reflection. But for simple
- /// applications hand generation is often used. (Until a generator is implemented that's the only
- /// option actually).
- ///
- public static abstract AppControlledDefaultsRootCommand BuildRootCommand( CmdLineSettings settings );
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/IDiagnosticReporter.cs b/src/Ubiquity.NET.CommandLine/IDiagnosticReporter.cs
deleted file mode 100644
index c73dc56b7..000000000
--- a/src/Ubiquity.NET.CommandLine/IDiagnosticReporter.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Interface for UX message reporting
- ///
- /// Unlike logging, which is meant for developers/administrator diagnostics,
- /// this interface is focused solely on text based (typically command line)
- /// end user facing experiences. The idea is that UX is distinct
- /// from any logging and should not be mixed or confused as they have very different
- /// uses/intents.
- ///
- public interface IDiagnosticReporter
- {
- /// Gets the current reporting level for this reporter
- MsgLevel Level { get; }
-
- /// Gets the encoding used for this reporter
- Encoding Encoding { get; }
-
- /// Report a message as defined by the implementation
- /// Message to report
- void Report( DiagnosticMessage diagnostic );
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/DiagnosticReporterInterpolatedStringHandler.cs b/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/DiagnosticReporterInterpolatedStringHandler.cs
deleted file mode 100644
index 1789550b4..000000000
--- a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/DiagnosticReporterInterpolatedStringHandler.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine.InterpolatedStringHandlers
-{
- /// Interpolated string handler for an
- ///
- /// This handler will use the state of the to filter messages
- /// as interpolated strings. If the channel for the message is not enabled, then the handler filters
- /// the entire message and can skip even constructing the parameterized elements (unless it is the first
- /// one [Limit of how Handlers work in .NET]). The limitation of the first is further restricted to the
- /// first "thing" interpolated including a string literal. Thus, the parameterized elements are not generated
- /// if the channel isn't enabled unless the element is the first thing in the interpolated string. In that
- /// case only, the first entry is evaluated.
- ///
- /// Apps should NOT depend on the subtleties of interpolated parameter evaluation to guarantee invocation
- /// (or not) of side effects. This is a "best-effort" optimization. In particular, apps should assume that
- /// a parameterized value may or may not be executed (i.e., non-deterministic). Therefore, it cannot assume
- /// (one way or another) that the side-effects of evaluation have, or have not, occurred.
- ///
- /// Despite lots of samples (for preview variants) that use a 'ref struct', this is NOT
- /// a by ref like type. This is to allow use interpolating async parameters.
- ///
- [InterpolatedStringHandler]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Not relevant for an interpolated string handler" )]
- public readonly struct DiagnosticReporterInterpolatedStringHandler
- {
- /// Initializes a new instance of the struct.
- /// Length of the literal
- /// Sadly .NET doesn't document this, or much else in relation to interpolated string handlers
- /// "this" reference for the reporter. (Mapped via InterpolatedStringHandlerArgument applied to method)
- /// Reporting level parameter to report for. (Mapped via InterpolatedStringHandlerArgument applied to method)
- /// Format provider
- ///
- /// The may not have the level enabled. This is used to ONLY process the interpolated string
- /// if the reporter has the level enabled. Thus, it may produce NO message at all if not enabled.
- ///
- public DiagnosticReporterInterpolatedStringHandler(
- int literalLength,
- int formattedCount,
- IDiagnosticReporter reporter,
- MsgLevel level,
- IFormatProvider? formatProvider = null
- )
- {
- FormatProvider = formatProvider ?? CultureInfo.CurrentCulture;
- Builder = reporter.IsEnabled( level ) ? new( literalLength ) : null;
- }
-
- /// Gets a value indicating whether this handler is enabled
- public bool IsEnabled => Builder is not null;
-
- /// Gets the format provider used by this interpolated string handler
- public IFormatProvider FormatProvider { get; }
-
- /// Appends a literal value to the results of interpolating a string
- /// literal value to append
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// reporting level is enabled for a given reporter.
- ///
- public bool AppendLiteral( string s )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( s );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// reporting level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString() );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// format string for formatting the value
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// reporting level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t, string format )
- where T : IFormattable
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString( format, FormatProvider ) );
- return true;
- }
-
- /// Gets the full results of interpolation
- /// Results of the interpolation (thus far)
- public string GetFormattedText( )
- {
- return Builder?.ToString() ?? string.Empty;
- }
-
- private readonly StringBuilder? Builder;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/ErrorReportingInterpolatedStringHandler.cs b/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/ErrorReportingInterpolatedStringHandler.cs
deleted file mode 100644
index 52ba40aa8..000000000
--- a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/ErrorReportingInterpolatedStringHandler.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine.InterpolatedStringHandlers
-{
- /// Interpolated string handler for an using a fixed
- ///
- /// This handler will use the state of the to filter messages
- /// as interpolated strings. If the channel for the message is not enabled, then the handler filters
- /// the entire message and can skip even constructing the parameterized elements (unless it is the first
- /// one [Limit of how Handlers work in .NET]). The limitation of the first is further restricted to the
- /// first "thing" interpolated including a string literal. Thus, the parameterized elements are not generated
- /// if the channel isn't enabled unless the element is the first thing in the interpolated string. In that
- /// case only the first entry is evaluated.
- ///
- /// Apps should NOT depend on the subtleties of interpolated parameter evaluation to guarantee invocation
- /// (or not) of side effects. This is a "best-effort" optimization. In particular, apps should assume that
- /// a parameterized value may or may not be executed (i.e., non-deterministic). Therefore, it cannot assume
- /// (one way or another) that the side-effects of evaluation have, or have not, occurred.
- ///
- /// Despite lots of samples (for preview variants) that use a 'ref struct', this is NOT
- /// a by ref like type. This is to allow use interpolating async parameters.
- ///
- [InterpolatedStringHandler]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Not relevant for an interpolated string handler" )]
- public readonly struct ErrorReportingInterpolatedStringHandler
- {
- /// Initializes a new instance of the struct.
- /// Length of the literal
- /// Sadly .NET doesn't document this, or much else in relation to interpolated string handlers
- /// "this" reference for the reporter. (Mapped via InterpolatedStringHandlerArgument applied to method)
- ///
- /// The may not have the level enabled. This is used to ONLY process the interpolated string
- /// if the reporter has the level enabled. Thus, it may produce NO message at all if not enabled.
- ///
- public ErrorReportingInterpolatedStringHandler( int literalLength, int formattedCount, IDiagnosticReporter reporter )
- {
- Builder = reporter.IsEnabled( MsgLevel.Error ) ? new( literalLength ) : null;
- }
-
- /// Gets a value indicating whether this handler is enabled
- public bool IsEnabled => Builder is not null;
-
- /// Appends a literal value to the results of interpolating a string
- /// literal value to append
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public bool AppendLiteral( string s )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( s );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString() );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// format string for formatting the value
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t, string format )
- where T : IFormattable
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString( format, null ) );
- return true;
- }
-
- /// Gets the full results of interpolation
- /// Results of the interpolation (thus far)
- public string GetFormattedText( )
- {
- return Builder?.ToString() ?? string.Empty;
- }
-
- private readonly StringBuilder? Builder;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/InformationReportingInterpolatedStringHandler.cs b/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/InformationReportingInterpolatedStringHandler.cs
deleted file mode 100644
index 23ad5009c..000000000
--- a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/InformationReportingInterpolatedStringHandler.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine.InterpolatedStringHandlers
-{
- /// Interpolated string handler for an using a fixed
- ///
- /// This handler will use the state of the to filter messages
- /// as interpolated strings. If the channel for the message is not enabled, then the handler filters
- /// the entire message and can skip even constructing the parameterized elements (unless it is the first
- /// one [Limit of how Handlers work in .NET]). The limitation of the first is further restricted to the
- /// first "thing" interpolated including a string literal. Thus, the parameterized elements are not generated
- /// if the channel isn't enabled unless the element is the first thing in the interpolated string. In that
- /// case only the first entry is evaluated.
- ///
- /// Apps should NOT depend on the subtleties of interpolated parameter evaluation to guarantee invocation
- /// (or not) of side effects. This is a "best-effort" optimization. In particular, apps should assume that
- /// a parameterized value may or may not be executed (i.e., non-deterministic). Therefore, it cannot assume
- /// (one way or another) that the side-effects of evaluation have, or have not, occurred.
- ///
- /// Despite lots of samples (for preview variants) that use a 'ref struct', this is NOT
- /// a by ref like type. This is to allow use interpolating async parameters.
- ///
- [InterpolatedStringHandler]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Not relevant for an interpolated string handler" )]
- public readonly struct InformationReportingInterpolatedStringHandler
- {
- /// Initializes a new instance of the struct.
- /// Length of the literal
- /// Sadly .NET doesn't document this, or much else in relation to interpolated string handlers
- /// "this" reference for the reporter. (Mapped via InterpolatedStringHandlerArgument applied to method)
- ///
- /// The may not have the level enabled. This is used to ONLY process the interpolated string
- /// if the reporter has the level enabled. Thus, it may produce NO message at all if not enabled.
- ///
- public InformationReportingInterpolatedStringHandler( int literalLength, int formattedCount, IDiagnosticReporter reporter )
- {
- Builder = reporter.IsEnabled( MsgLevel.Information ) ? new( literalLength ) : null;
- }
-
- /// Gets a value indicating whether this handler is enabled
- public bool IsEnabled => Builder is not null;
-
- /// Appends a literal value to the results of interpolating a string
- /// literal value to append
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public bool AppendLiteral( string s )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( s );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString() );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// format string for formatting the value
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t, string format )
- where T : IFormattable
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString( format, null ) );
- return true;
- }
-
- /// Gets the full results of interpolation
- /// Results of the interpolation (thus far)
- public string GetFormattedText( )
- {
- return Builder?.ToString() ?? string.Empty;
- }
-
- private readonly StringBuilder? Builder;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/VerboseReportingInterpolatedStringHandler.cs b/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/VerboseReportingInterpolatedStringHandler.cs
deleted file mode 100644
index 0e5e06900..000000000
--- a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/VerboseReportingInterpolatedStringHandler.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine.InterpolatedStringHandlers
-{
- /// Interpolated string handler for an using a fixed
- ///
- /// This handler will use the state of the to filter messages
- /// as interpolated strings. If the channel for the message is not enabled, then the handler filters
- /// the entire message and can skip even constructing the parameterized elements (unless it is the first
- /// one [Limit of how Handlers work in .NET]). The limitation of the first is further restricted to the
- /// first "thing" interpolated including a string literal. Thus, the parameterized elements are not generated
- /// if the channel isn't enabled unless the element is the first thing in the interpolated string. In that
- /// case only the first entry is evaluated.
- ///
- /// Apps should NOT depend on the subtleties of interpolated parameter evaluation to guarantee invocation
- /// (or not) of side effects. This is a "best-effort" optimization. In particular, apps should assume that
- /// a parameterized value may or may not be executed (i.e., non-deterministic). Therefore, it cannot assume
- /// (one way or another) that the side-effects of evaluation have, or have not, occurred.
- ///
- /// Despite lots of samples (for preview variants) that use a 'ref struct', this is NOT
- /// a by ref like type. This is to allow use interpolating async parameters.
- ///
- [InterpolatedStringHandler]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Not relevant for an interpolated string handler" )]
- public readonly struct VerboseReportingInterpolatedStringHandler
- {
- /// Initializes a new instance of the struct.
- /// Length of the literal
- /// Sadly .NET doesn't document this, or much else in relation to interpolated string handlers
- /// "this" reference for the reporter. (Mapped via InterpolatedStringHandlerArgument applied to method)
- ///
- /// The may not have the level enabled. This is used to ONLY process the interpolated string
- /// if the reporter has the level enabled. Thus, it may produce NO message at all if not enabled.
- ///
- public VerboseReportingInterpolatedStringHandler( int literalLength, int formattedCount, IDiagnosticReporter reporter )
- {
- Builder = reporter.IsEnabled( MsgLevel.Verbose ) ? new( literalLength ) : null;
- }
-
- /// Gets a value indicating whether this handler is enabled
- public bool IsEnabled => Builder is not null;
-
- /// Appends a literal value to the results of interpolating a string
- /// literal value to append
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public bool AppendLiteral( string s )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( s );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString() );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// format string for formatting the value
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t, string format )
- where T : IFormattable
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString( format, null ) );
- return true;
- }
-
- /// Gets the full results of interpolation
- /// Results of the interpolation (thus far)
- public string GetFormattedText( )
- {
- return Builder?.ToString() ?? string.Empty;
- }
-
- private readonly StringBuilder? Builder;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/WarningReportingInterpolatedStringHandler.cs b/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/WarningReportingInterpolatedStringHandler.cs
deleted file mode 100644
index 6bfc64371..000000000
--- a/src/Ubiquity.NET.CommandLine/InterpolatedStringHandlers/WarningReportingInterpolatedStringHandler.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine.InterpolatedStringHandlers
-{
- /// Interpolated string handler for an using a fixed
- ///
- /// This handler will use the state of the to filter messages
- /// as interpolated strings. If the channel for the message is not enabled, then the handler filters
- /// the entire message and can skip even constructing the parameterized elements (unless it is the first
- /// one [Limit of how Handlers work in .NET]). The limitation of the first is further restricted to the
- /// first "thing" interpolated including a string literal. Thus, the parameterized elements are not generated
- /// if the channel isn't enabled unless the element is the first thing in the interpolated string. In that
- /// case only the first entry is evaluated.
- ///
- /// Apps should NOT depend on the subtleties of interpolated parameter evaluation to guarantee invocation
- /// (or not) of side effects. This is a "best-effort" optimization. In particular, apps should assume that
- /// a parameterized value may or may not be executed (i.e., non-deterministic). Therefore, it cannot assume
- /// (one way or another) that the side-effects of evaluation have, or have not, occurred.
- ///
- /// Despite lots of samples (for preview variants) that use a 'ref struct', this is NOT
- /// a by ref like type. This is to allow use interpolating async parameters.
- ///
- [InterpolatedStringHandler]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Not relevant for an interpolated string handler" )]
- public readonly struct WarningReportingInterpolatedStringHandler
- {
- /// Initializes a new instance of the struct.
- /// Length of the literal
- /// Sadly .NET doesn't document this, or much else in relation to interpolated string handlers
- /// "this" reference for the reporter. (Mapped via InterpolatedStringHandlerArgument applied to method)
- ///
- /// The may not have the level enabled. This is used to ONLY process the interpolated string
- /// if the reporter has the level enabled. Thus, it may produce NO message at all if not enabled.
- ///
- public WarningReportingInterpolatedStringHandler( int literalLength, int formattedCount, IDiagnosticReporter reporter )
- {
- Builder = reporter.IsEnabled( MsgLevel.Warning ) ? new( literalLength ) : null;
- }
-
- /// Gets a value indicating whether this handler is enabled
- public bool IsEnabled => Builder is not null;
-
- /// Appends a literal value to the results of interpolating a string
- /// literal value to append
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public bool AppendLiteral( string s )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( s );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t )
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString() );
- return true;
- }
-
- /// Appends an interpolated value to the result of interpolation
- /// Type of the interpolated value
- /// Value to format
- /// format string for formatting the value
- /// if the interpolation should continue with other conversions or if not.
- ///
- /// The return is used to short circuit all other calls to interpolation, thus, this implementation returns if the
- /// level is enabled for a given reporter.
- ///
- public readonly bool AppendFormatted( T t, string format )
- where T : IFormattable
- {
- if(!IsEnabled)
- {
- return false;
- }
-
- Builder?.Append( t?.ToString( format, null ) );
- return true;
- }
-
- /// Gets the full results of interpolation
- /// Results of the interpolation (thus far)
- public string GetFormattedText( )
- {
- return Builder?.ToString() ?? string.Empty;
- }
-
- private readonly StringBuilder? Builder;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/PackageReadMe.md b/src/Ubiquity.NET.CommandLine/PackageReadMe.md
deleted file mode 100644
index 6f41b0910..000000000
--- a/src/Ubiquity.NET.CommandLine/PackageReadMe.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Ubiquity.NET.CommandLine
-Common Text based (console) UX support. This provides a number of support classes for
-Text based UI/UXm including command line parsing extensions. This is generally only relevant
-for console based apps.
-
-Example Command line parsing:
-``` C#
-var reporter = new ColoredConsoleReporter(MsgLevel.Information);
-if(!ArgsParsing.TryParse( args, reporter, out Options? options, out int exitCode ))
-{
- return exitCode;
-}
-
-// ...
-
-// Options is a class that has properties for all parsed commands, arguments and options
-// Allowing for validation of them all in context (including each other)
-// App can then dispatch behavior based on the commands/options etc... as needed.
-// NO ASSUMPTION IS MADE ABOUT THE USE OF COMMANDS NOR THE BEHAVIOR OF THEM. The app
-// is entirely in control of how they are used.
-```
-
-## Supported Functionality
-`IDiagnosticReporter` interface is at the core of the UX. It is similar in many ways to many
-of the logging interfaces available. The primary distinction is with the ***intention*** of
-use. `IDiagnosticReporter` specifically assumes the use for UI/UX rather than a
-debugging/diagnostic log. These have VERY distinct use cases and purposes and generally show
-very different information. (Not to mention the overlly complex requirements of
-the anti-pattern DI container assumed in `Microsoft.Extensions.Logging`)
-
-### Messages
-All messages for the UX use a simple immutable structure to store the details of a message
-represented as `DiagnosticMessage`.
-
-### Pre-Built Reporters
-There are a few pre-built implementation of the `IDiagnosticReporter` interface.
-* `TextWriterReporter`
- * Base class for writing UX to a `TextWriter`
-* `ConsoleReporter`
- * Reporter that reports errors to `Console.Error` and all other nessages to
- `Console.Out`
-* `ColoredConsoleReporter`
- * `ConsoleReporter` that colorizes output using ANSI color codes
- * Colors are customizable, but contains a common default
-
diff --git a/src/Ubiquity.NET.CommandLine/ParseResultExtensions.cs b/src/Ubiquity.NET.CommandLine/ParseResultExtensions.cs
deleted file mode 100644
index bcac7428c..000000000
--- a/src/Ubiquity.NET.CommandLine/ParseResultExtensions.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- // This does NOT use the new C# 14 extension syntax due to several reasons
- // 1) Code lens does not work https://github.com/dotnet/roslyn/issues/79006 [Sadly marked as "not planned" - e.g., dead-end]
- // 2) MANY analyzers get things wrong and need to be supressed (CA1000, CA1034, and many others [SAxxxx])
- // 3) Many tools (like docfx don't support the new syntax yet)
- // 4) No clear support for Caller* attributes ([CallerArgumentExpression(...)]).
- //
- // Bottom line it's a good idea with an incomplete implementation lacking support
- // in the overall ecosystem. Don't use it unless you absolutely have to until all
- // of that is sorted out.
-
- /// Utility extension methods for command line parsing
- public static class ParseResultExtensions
- {
- /// Gets a value indicating whether has any errors
- /// Result to test for errors
- /// value indicating whether has any errors
- public static bool HasErrors(this ParseResult self) => self.Errors.Count > 0;
-
- /// Gets the optional from the result of a parse
- /// Result of parse to get the option from
- /// if found or
- public static HelpOption? GetHelpOption(this ParseResult self)
- {
- var helpOptions = from r in self.CommandResult.RecurseWhileNotNull(r => r.Parent as CommandResult)
- from o in r.Command.Options.OfType()
- select o;
-
- return helpOptions.FirstOrDefault();
- }
-
- /// Gets the optional from the result of a parse
- /// Result of parse to get the option from
- /// if found or
- public static VersionOption? GetVersionOption(this ParseResult self)
- {
- var versionOptions = from r in self.CommandResult.RecurseWhileNotNull(r => r.Parent as CommandResult)
- from o in r.Command.Options.OfType()
- select o;
-
- return versionOptions.FirstOrDefault();
- }
-
- // shamelessly "borrowed" from: https://github.com/dotnet/dotnet/blob/8c7b3dcd2bd657c11b12973f1214e7c3c616b174/src/command-line-api/src/System.CommandLine/Help/HelpBuilderExtensions.cs#L42
- internal static IEnumerable RecurseWhileNotNull( this T? source, Func next )
- where T : class
- {
- while(source is not null)
- {
- yield return source;
-
- source = next( source );
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/ReportingSettings.cs b/src/Ubiquity.NET.CommandLine/ReportingSettings.cs
deleted file mode 100644
index b6cc26e5f..000000000
--- a/src/Ubiquity.NET.CommandLine/ReportingSettings.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- // internal extension for IDiagnosticReporter
- internal static class ReportingSettings
- {
- // Create an InvocationConiguration that wraps an IDiagnosticReporter
- public static InvocationConfiguration CreateConfig( this IDiagnosticReporter self )
- {
- ArgumentNullException.ThrowIfNull( self );
-
- return new()
- {
- EnableDefaultExceptionHandler = false,
- Error = new ReportingTextWriter( self, MsgLevel.Error ),
- Output = new ReportingTextWriter( self, MsgLevel.Information ),
- };
- }
- }
-
- // TextWriter that wraps an IDiagnosticReporter for a given level
- // This is an implementation of the GoF "Adapter Pattern"
- [SuppressMessage( "StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "File scoped..." )]
- file class ReportingTextWriter
- : TextWriter
- {
- public ReportingTextWriter( IDiagnosticReporter diagnosticReporter, MsgLevel level )
- {
- Reporter = diagnosticReporter;
- MsgLevel = level;
- Builder = new();
- }
-
- public override Encoding Encoding => Reporter.Encoding;
-
- public MsgLevel MsgLevel { get; }
-
- public override void Write(string? value)
- {
- if (value == Environment.NewLine)
- {
- WriteLine();
- }
- else
- {
- base.Write(value);
- }
- }
-
- public override void WriteLine( )
- {
- Reporter.Report( MsgLevel, Builder.ToString() );
- Builder.Clear();
- }
-
- public override void Write( char value )
- {
- Builder.Append( value );
- }
-
- private readonly IDiagnosticReporter Reporter;
- private readonly StringBuilder Builder;
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/SymbolValidationExtensions.cs b/src/Ubiquity.NET.CommandLine/SymbolValidationExtensions.cs
deleted file mode 100644
index 8154283b5..000000000
--- a/src/Ubiquity.NET.CommandLine/SymbolValidationExtensions.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Utility class to provide extensions for validation of options and arguments
- public static class SymbolValidationExtensions
- {
- /// Fluent function to add a validator to an
- /// Type of Option to add the validator to
- /// The option to add the validator to
- /// validator to add
- /// for fluent use
- public static T AddValidator( this T self, Action validator )
- where T : Option
- {
- ArgumentNullException.ThrowIfNull( self );
- self.Validators.Add( validator );
- return self;
- }
-
- /// Fluent function to add a validator to an
- /// Type of Option to add the validator to
- /// The option to add the validator to
- /// validator to add
- /// for fluent use
- public static T AddValidator( this T self, Action validator )
- where T : Argument
- {
- ArgumentNullException.ThrowIfNull( self );
- self.Validators.Add( validator );
- return self;
- }
-
- /// Add validation for an existing file only
- /// Option to add the validation to
- /// for fluent use
- ///
- /// This is similar to
- /// but it is constrained to specifically files AND enhances the error message to
- /// provide more details to aid user in correcting the problem.
- ///
- public static Option AcceptExistingFileOnly( this Option self )
- {
- self.AddValidator( ValidateFileExists );
- return self;
- }
-
- ///
- public static Argument AcceptExistingFileOnly( this Argument self )
- {
- self.AddValidator( ValidateFileExists );
- return self;
- }
-
- /// Add validation for an existing file only
- /// Type of value for the argument
- /// Option to add the validation to
- /// for fluent use
- ///
- /// This is similar to
- /// but it is constrained to specifically files AND enhances the error message to
- /// provide more details to aid user in correcting the problem.
- ///
- public static Argument AcceptExistingFileOnly( this Argument self )
- where T : IEnumerable
- {
- self.AddValidator( ValidateFileExists );
- return self;
- }
-
- /// Option validator for an Option's tokens that ensures each represents an existing file
- /// result to validate
- ///
- /// This is simply a parse validation sanity check for common usage errors. It is explicitly NOT
- /// a security check/test!. Apps MUST NOT assume anything about the file beyond the fact that it
- /// existed AT THE TIME this validation ran. It might not exist when needed, might have been replaced
- /// since, or may exist as or been replaced by a link to something else. None of those scenarios is
- /// verified or prevented by this.
- ///
- public static void ValidateFileExists( OptionResult result )
- {
- string optionName = result.Option.HelpName ?? result.Option.Name;
- foreach(var token in result.Tokens)
- {
- if(!File.Exists( token.Value ))
- {
- result.AddError( $"File '{token.Value}' specified for '{optionName}' does not exist" );
- return;
- }
- }
- }
-
- /// Argument validator for an Arguments's tokens that ensures each represents an existing file
- /// result to validate
- ///
- /// This is simply a parse validation sanity check for common usage errors. It is explicitly NOT
- /// a security check/test!. Apps MUST NOT assume anything about the file beyond the fact that it
- /// existed AT THE TIME this validation ran. It might not exist when needed, might have been replaced
- /// since, or may exist as or been replaced by a link to something else. None of those scenarios is
- /// verified or prevented by this.
- ///
- public static void ValidateFileExists( ArgumentResult result )
- {
- string optionName = result.Argument.HelpName ?? result.Argument.Name;
- foreach(var token in result.Tokens)
- {
- if(!File.Exists( token.Value ))
- {
- result.AddError( $"File '{token.Value}' specified for '{optionName}' does not exist" );
- return;
- }
- }
- }
-
- /// Extension method to add the validator
- /// Option to add the validator for
- /// for fluent use
- public static Option AcceptExistingFolderOnly( this Option self )
- {
- self.AddValidator( ValidateFolderExists );
- return self;
- }
-
- /// Option validator for an Option's tokens that ensures each represents an existing Folder
- /// result to validate
- ///
- /// This is simply a parse validation sanity check for common usage errors. It is explicitly NOT
- /// a security check/test!. Apps MUST NOT assume anything about the folder beyond the fact that it
- /// existed AT THE TIME this validation ran. It might not exist when needed, might have been replaced
- /// since, or may exist as or been replaced by a link to something else later. None of those scenarios
- /// is verified or prevented by this.
- ///
- public static void ValidateFolderExists( OptionResult result )
- {
- string optionName = result.Option.HelpName ?? result.Option.Name;
- foreach(var token in result.Tokens)
- {
- if(!Directory.Exists( token.Value ))
- {
- result.AddError( $"Folder '{token.Value}' specified for '{optionName}' does not exist" );
- return;
- }
- }
- }
-
- /// Extension method to add the validator
- /// Option to add the validator for
- /// for fluent use
- public static Option EnsureFolder( this Option self )
- {
- self.AddValidator(EnsureFolderExists);
- return self;
- }
-
- /// Option validator for an Option's tokens that ensures each Folder exists (creates it if not present)
- /// result to validate
- ///
- /// This is a parse validation that will create a directory that does not exist. It is explicitly NOT a security
- /// check/test!. Apps MUST NOT assume anything about the folder beyond the fact that it existed AT THE TIME this
- /// validation ran. It might not exist when needed, might have been replaced since, or may exist as or been
- /// replaced by a link to something else later or even deleted later. None of those scenarios is verified or
- /// prevented by this.
- ///
- public static void EnsureFolderExists( OptionResult result )
- {
- string value = result.Option.HelpName ?? result.Option.Name;
- foreach (Token token in result.Tokens)
- {
- if (!Directory.Exists(token.Value))
- {
- try
- {
- Directory.CreateDirectory(token.Value);
- }
- catch(Exception ex) when (IsDirectoryCreationException(ex))
- {
- result.AddError($"Attempt to create directory '{token.Value}' resulted in {ex.Message}");
- }
-
- break;
- }
- }
- }
-
- // returns true if the exception is one of the documented types for Directory.CreateDirectory().
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static bool IsDirectoryCreationException(Exception ex)
- {
- return ex is IOException or
- UnauthorizedAccessException or
- ArgumentException or
- PathTooLongException or
- DirectoryNotFoundException or
- NotSupportedException;
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/TextWriterReporter.cs b/src/Ubiquity.NET.CommandLine/TextWriterReporter.cs
deleted file mode 100644
index faed113c3..000000000
--- a/src/Ubiquity.NET.CommandLine/TextWriterReporter.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.CommandLine
-{
- /// Base class for reporting diagnostics via an instance of
- public class TextWriterReporter
- : IDiagnosticReporter
- {
- /// Initializes a new instance of the class.
- /// Reporting level for this reporter (any message with an equal or greater level is reported)
- /// Error writer
- /// Warning writer
- /// Information writer
- /// Verbose writer
- [SetsRequiredMembers]
- public TextWriterReporter(
- MsgLevel level,
- TextWriter? error = null,
- TextWriter? warning = null,
- TextWriter? information = null,
- TextWriter? verbose = null
- )
- {
- ArgumentNullException.ThrowIfNull(error);
-
- Level = level;
- Error = error ?? TextWriter.Null;
- Warning = warning ?? TextWriter.Null;
- Information = information ?? TextWriter.Null;
- Verbose = verbose ?? TextWriter.Null;
- }
-
- /// Gets the Error writer for this reporter
- public required TextWriter Error
- {
- get;
- init
- {
- ArgumentNullException.ThrowIfNull(value);
- field = value;
- }
- }
-
- /// Gets the warning writer for this reporter
- public TextWriter Warning
- {
- get;
- init
- {
- ArgumentNullException.ThrowIfNull(value);
- field = value;
- }
- }
-
- /// Gets the information writer for this reporter
- public TextWriter Information
- {
- get;
- init
- {
- ArgumentNullException.ThrowIfNull(value);
- field = value;
- }
- }
-
- /// Gets the verbose writer for this reporter
- public TextWriter Verbose
- {
- get;
- init
- {
- ArgumentNullException.ThrowIfNull(value);
- field = value;
- }
- }
-
- ///
- public MsgLevel Level { get; init; }
-
- ///
- public Encoding Encoding => Error.Encoding;
-
- ///
- ///
- /// This implementation will test if the of the
- /// message is enabled. If so, then a call is made to the virtual
- /// with the results of as the message text.
- ///
- public void Report( DiagnosticMessage diagnostic )
- {
- if(!this.IsEnabled( diagnostic.Level ))
- {
- return;
- }
-
- ReportMessage(diagnostic.Level, diagnostic.ToString());
- }
-
- /// Virtual method to report a message formatted as a string
- /// Level of the message
- /// Message formatted as a string
- ///
- /// The default base implementation will simply redirect messages based on to
- /// the writer for . It is possible that such a writer is
- /// and the messages go nowhere.
- ///
- /// Invalid/Unknown level - should never hit this, internal or derived type error if it does.
- protected virtual void ReportMessage(MsgLevel level, string msg)
- {
- var writer = level switch
- {
- MsgLevel.Error => Error,
- MsgLevel.Warning => Warning,
- MsgLevel.Information => Information,
- MsgLevel.Verbose => Verbose,
- MsgLevel.None => null,
- _ => throw new InvalidEnumArgumentException(nameof(level), (int)level, typeof(MsgLevel))
- };
-
- // A message level of None is always ignored, this will not occur normally as that level is
- // NEVER enabled. But, if a derived type ever calls this directly it might not check for enabled.
- // Additionally, not all streams are guaranteed non-null, so this will ignore any that are.
- writer?.WriteLine(msg);
- }
- }
-}
diff --git a/src/Ubiquity.NET.CommandLine/Ubiquity.NET.CommandLine.csproj b/src/Ubiquity.NET.CommandLine/Ubiquity.NET.CommandLine.csproj
deleted file mode 100644
index 2268b0246..000000000
--- a/src/Ubiquity.NET.CommandLine/Ubiquity.NET.CommandLine.csproj
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
- net8.0
- enable
-
- preview
- True
-
-
- true
- 4.9.0
- .NET Foundation,Ubiquity.NET
- false
- General use Support for Command line parsing based on System.CommandLine
- Extensions,.NET,Ubiquity.NET, Console
- PackageReadMe.md
- https://github.com/UbiquityDotNET/Llvm.NET
- https://github.com/UbiquityDotNET/Llvm.NET.git
- git
- Apache-2.0 WITH LLVM-exception
- true
- snupkg
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- all
- false
- Analyzer
-
-
-
-
diff --git a/src/Ubiquity.NET.Extensions.UT/AssemblyExtensionsTests.cs b/src/Ubiquity.NET.Extensions.UT/AssemblyExtensionsTests.cs
deleted file mode 100644
index 2281d08df..000000000
--- a/src/Ubiquity.NET.Extensions.UT/AssemblyExtensionsTests.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.Reflection;
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class AssemblyExtensionsTests
- {
- [TestMethod]
-#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
- public void GetInformationalVersion_with_null_throws( )
- {
- var ex = Assert.ThrowsExactly( ()=> _ = AssemblyExtensions.GetInformationalVersion( null ) );
- Assert.AreEqual("null", ex.ParamName, "CallerExpressionArgumentAttribute should provide the expression used");
-
- ex = Assert.ThrowsExactly( ()=> _ = AssemblyExtensions.GetInformationalVersion( null, "self" ) );
- Assert.AreEqual( "self", ex.ParamName, "explicit value for CallerExpressionArgumentAttribute should override it" );
- }
-#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
-
- [TestMethod]
- public void GetInformationalVersion_succeeds( )
- {
- var thisAsm = typeof( AssemblyExtensionsTests ).Assembly;
-
- var assemblyVersionAttribute = thisAsm.GetCustomAttribute();
-
- string expected = assemblyVersionAttribute is not null
- ? assemblyVersionAttribute.InformationalVersion
- : thisAsm.GetName().Version?.ToString() ?? string.Empty;
-
- string actual = thisAsm.GetInformationalVersion();
- Assert.AreEqual( expected, actual );
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/AssemblyInfo.cs b/src/Ubiquity.NET.Extensions.UT/AssemblyInfo.cs
deleted file mode 100644
index a4d0b1392..000000000
--- a/src/Ubiquity.NET.Extensions.UT/AssemblyInfo.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.
-
-// In SDK-style projects such as this one, several assembly attributes that were historically
-// defined in this file are now automatically added during build and populated with
-// values defined in project properties. For details of which attributes are included
-// and how to customise this process see: https://aka.ms/assembly-info-properties
-
-// Setting ComVisible to false makes the types in this assembly not visible to COM
-// components. If you need to access a type in this assembly from COM, set the ComVisible
-// attribute to true on that type.
-
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM.
-
-[assembly: Guid("312c3354-ea8c-4819-8823-ac78064c645c")]
-
-// Tests are so trivial they perform better when not individually parallelized.
-// Unfortunately this is an assembly wide choice and not class or method level
-// see: https://github.com/microsoft/testfx/issues/5555#issuecomment-3448956323
-[assembly: Parallelize( Scope = ExecutionScope.ClassLevel )]
-
-// can't use this at assembly level as it isn't supported there for downlevel... [Sigh...]
-//[assembly: ExcludeFromCodeCoverage]
-
-// NOTE: use of this and `internal` test classes results in a flurry of
-// error CA1812: '' is an internal class that is apparently never instantiated. If so, remove the code from the assembly.
-// If this class is intended to contain only static members, make it 'static' (Module in Visual Basic).
-// (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1812)
-// In other words, not worth the bother...
-// [assembly: DiscoverInternals]
diff --git a/src/Ubiquity.NET.Extensions.UT/DictionaryBuilderTests.cs b/src/Ubiquity.NET.Extensions.UT/DictionaryBuilderTests.cs
deleted file mode 100644
index 730e9f8e5..000000000
--- a/src/Ubiquity.NET.Extensions.UT/DictionaryBuilderTests.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class DictionaryBuilderTests
- {
- [TestMethod]
- public void Inintialization_of_KvpArray_is_successfull( )
- {
- ImmutableDictionary testDictionary = new DictionaryBuilder()
- {
- ["one"] = 1,
- ["two"] = 2,
- }.ToImmutable();
-
- Assert.AreEqual( 1, testDictionary[ "one" ] );
- Assert.AreEqual( 2, testDictionary[ "two" ] );
- }
-
- [TestMethod]
- public void Getting_enumerator_from_KvpArrayBuilder_throws( )
- {
- var testBuilder = new DictionaryBuilder()
- {
- ["one"] = 1,
- ["two"] = 2,
- };
-
- Assert.ThrowsExactly( ( ) =>
- {
-#pragma warning disable IDISP004 // Don't ignore created IDisposable
- // NOT disposable, no idea where the analyzer gets this from but System.Collections.IEnumerator
- // does not implement IDisposable. [Methods is supposed to throw anyway]
- _ = testBuilder.GetEnumerator();
-#pragma warning restore IDISP004 // Don't ignore created IDisposable
- }
- , "Syntactic sugar only for initialization" );
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/DisposableActionTests.cs b/src/Ubiquity.NET.Extensions.UT/DisposableActionTests.cs
deleted file mode 100644
index b993dae93..000000000
--- a/src/Ubiquity.NET.Extensions.UT/DisposableActionTests.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class DisposableActionTests
- {
- [TestMethod]
- public void DisposableAction_CreateNOP_succeeds( )
- {
- using var disp = DisposableAction.CreateNOP();
- Assert.IsNotNull(disp);
- }
-
- [TestMethod]
- public void DisposableAction_with_null_Action_throws( )
- {
- var ex = Assert.ThrowsExactly(static ()=>
- {
-#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
- // Testing explicit case of null param.
- using var x = new DisposableAction(null);
-#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
- } );
- Assert.IsNotNull( ex );
- Assert.AreEqual("null", ex.ParamName);
- }
-
- [TestMethod]
- [System.Diagnostics.CodeAnalysis.SuppressMessage( "IDisposableAnalyzers.Correctness", "IDISP017:Prefer using", Justification = "Explicit testing" )]
- public void DisposableAction_called_correctly()
- {
- bool actionCalled = false;
-
- var raiiAction = new DisposableAction( ()=> actionCalled = true );
- raiiAction.Dispose(); // Should trigger call to action
-
- Assert.IsTrue(actionCalled);
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/FluentValidation/ExceptionValidationExtensionsTests.cs b/src/Ubiquity.NET.Extensions.UT/FluentValidation/ExceptionValidationExtensionsTests.cs
deleted file mode 100644
index ff0021d38..000000000
--- a/src/Ubiquity.NET.Extensions.UT/FluentValidation/ExceptionValidationExtensionsTests.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// 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 Ubiquity.NET.Extensions.FluentValidation;
-
-namespace Ubiquity.NET.Extensions.UT.FluentValidation
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class ExceptionValidationExtensionsTests
- {
- [TestMethod]
- public void ThrowIfNull_throws_expected_exception_when_null( )
- {
- var ex = Assert.ThrowsExactly(()=>
- {
- ExceptionValidationExtensions.ThrowIfNull( null );
- } );
- Assert.AreEqual("null", ex.ParamName, "parameter name should match input expression");
- }
-
- [TestMethod]
- public void ThrowIfNull_does_not_throw_on_non_null_input()
- {
- const string input = "This is a test";
-
- Assert.AreSame(input, ExceptionValidationExtensions.ThrowIfNull(input), "Fluent API should return input value on success" );
- }
-
- [TestMethod]
- public void ThrowIfNull_reports_exception_whith_provided_expression( )
- {
- const string exp = "My-Expression";
- var ex = Assert.ThrowsExactly(()=>
- {
- ExceptionValidationExtensions.ThrowIfNull( null, exp );
- } );
- Assert.AreEqual( exp, ex.ParamName, "parameter name should match input expression" );
- }
-
- [TestMethod]
- public void ThrowIfNotDefined_does_not_throw_for_defined_value()
- {
- Assert.AreEqual(TestEnum.Max, ExceptionValidationExtensions.ThrowIfNotDefined(TestEnum.Max), "Fluent API should return input value on success" );
- }
-
- [TestMethod]
- public void ThrowIfOutOfRange_does_not_throw_for_inrange_values( )
- {
- double value = 1.0;
- double min = 0.0;
- double max = 2.0;
-
- Assert.AreEqual(value, ExceptionValidationExtensions.ThrowIfOutOfRange(value, min, max), "Fluent API should return input value on success");
- }
-
- [TestMethod]
- public void ThrowIfOutOfRange_throws_for_out_of_range_values( )
- {
- double value = 2.0;
- double min = 1.0;
- double max = 1.5;
-
- var ex = Assert.ThrowsExactly(()=>
- {
- _ = ExceptionValidationExtensions.ThrowIfOutOfRange( value, min, max );
- } );
- Assert.AreEqual(value, ex.ActualValue);
- Assert.AreEqual(nameof(value), ex.ParamName);
- }
-
- [TestMethod]
- public void ThrowIfOutOfRange_throws_with_custom_expression_for_out_of_range_values( )
- {
- double value = 2.0;
- double min = 1.0;
- double max = 1.5;
-
- const string exp = "My Expression";
- var ex = Assert.ThrowsExactly(()=>
- {
- _ = ExceptionValidationExtensions.ThrowIfOutOfRange( value, min, max, exp );
- } );
- Assert.AreEqual( value, ex.ActualValue );
- Assert.AreEqual( exp, ex.ParamName );
- }
-
- [TestMethod]
- public void ThrowIfNotDefined_throws_for_undefined_values( )
- {
- var temp = (TestEnum)4;
- var ex = Assert.ThrowsExactly( ( ) =>
- {
- ExceptionValidationExtensions.ThrowIfNotDefined(temp);
- } );
- Assert.AreEqual(nameof(temp), ex.ParamName, "parameter name should match input expression" );
-
- var temp2 = (TestByteEnum)4;
- var ex2 = Assert.ThrowsExactly( ( ) =>
- {
- ExceptionValidationExtensions.ThrowIfNotDefined(temp2);
- } );
- Assert.AreEqual( nameof( temp2 ), ex2.ParamName, "parameter name should match input expression" );
-
- // This still fits an int so the normal constructor that sets paramName is available
- var temp3 = (TestU64Enum)int.MaxValue;
- var ex3 = Assert.ThrowsExactly( ( ) =>
- {
- ExceptionValidationExtensions.ThrowIfNotDefined(temp3);
- } );
- Assert.AreEqual( nameof( temp3 ), ex3.ParamName, "parameter name should match input expression" );
-
- // This can't fit into an int so, the exception constructor that does not provide paramName is
- // the only option :( [But at least this scenario is VERY rare in the real world]
- var temp4 = (TestU64Enum)(UInt64.MaxValue - 1);
- var ex4 = Assert.ThrowsExactly( ( ) =>
- {
- ExceptionValidationExtensions.ThrowIfNotDefined(temp4);
- } );
- Assert.IsNull( ex4.ParamName, "parameter name not available for non-int formattable enums" );
- }
-
- private enum TestEnum // default underling type is Int32
- {
- Zero,
- One,
- Two,
- Max = int.MaxValue
- }
-
- private enum TestByteEnum
- : byte
- {
- Zero,
- One,
- Two,
- Max = byte.MaxValue
- }
-
- private enum TestU64Enum
- : UInt64
- {
- Zero,
- One,
- Two,
- Max = UInt64.MaxValue
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/GlobalNamespaceImports.cs b/src/Ubiquity.NET.Extensions.UT/GlobalNamespaceImports.cs
deleted file mode 100644
index d21b98d8c..000000000
--- a/src/Ubiquity.NET.Extensions.UT/GlobalNamespaceImports.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-/*
-NOTE:
-While the MsBuild `ImplicitUsings` property is banned from this repo, the C# language feature of global usings is NOT.
-The build property will auto include an invisible and undiscoverable (without looking up obscure documentation)
-set of namespaces that is NOT consistent or controlled by the developer. THAT is what is BAD/BROKEN about that feature.
-By banning it's use and then providing a `GlobalNamespaceImports.cs` source file with ONLY global using statements ALL of
-that is eliminated. Such use of the language feature restores FULL control and visibility of the namespaces to the developer,
-where it belongs. For a good explanation of this problem see: https://rehansaeed.com/the-problem-with-csharp-10-implicit-usings/.
-For an explanation of the benefits of the language feature see: https://www.hanselman.com/blog/implicit-usings-in-net-6
-*/
-
-// BUG: False positive from IDE0005 - Using directive is unnecessary
-// Attempts to remove/sort are at least able to figure it out and do the right thing.
-// Bug seems to be related to multi-targetting.
-#pragma warning disable IDE0005
-
-global using System;
-global using System.Collections.Generic;
-global using System.Collections.Immutable;
-global using System.ComponentModel;
-global using System.Diagnostics.CodeAnalysis;
-global using System.Runtime.InteropServices;
-
-global using Microsoft.VisualStudio.TestTools.UnitTesting;
diff --git a/src/Ubiquity.NET.Extensions.UT/GlobalSuppressions.cs b/src/Ubiquity.NET.Extensions.UT/GlobalSuppressions.cs
deleted file mode 100644
index caa5d65f9..000000000
--- a/src/Ubiquity.NET.Extensions.UT/GlobalSuppressions.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.
-
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project.
-// Project-level suppressions either have no target or are given
-// a specific target and scoped to a namespace, type, member, etc.
-
-[assembly: SuppressMessage( "StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Test module" )]
diff --git a/src/Ubiquity.NET.Extensions.UT/KvpArrayBuilderTests.cs b/src/Ubiquity.NET.Extensions.UT/KvpArrayBuilderTests.cs
deleted file mode 100644
index ebbf1a5d9..000000000
--- a/src/Ubiquity.NET.Extensions.UT/KvpArrayBuilderTests.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class KvpArrayBuilderTests
- {
- [TestMethod]
- public void Inintialization_of_KvpArray_is_successfull( )
- {
- ImmutableArray> testArray = new KvpArrayBuilder()
- {
- ["one"] = 1,
- ["two"] = 2,
- }.ToImmutable();
-
- Assert.AreEqual( "one", testArray[ 0 ].Key);
- Assert.AreEqual( 1, testArray[ 0 ].Value );
-
- Assert.AreEqual( "two", testArray[ 1 ].Key );
- Assert.AreEqual( 2, testArray[ 1 ].Value );
- }
-
- [TestMethod]
- public void Getting_enumerator_from_KvpArrayBuilder_throws( )
- {
- var testBuilder = new KvpArrayBuilder()
- {
- ["one"] = 1,
- ["two"] = 2,
- };
-
- Assert.ThrowsExactly(()=>
- {
-#pragma warning disable IDISP004 // Don't ignore created IDisposable
- // NOT disposable, no idea where the analyzer gets this from but System.Collections.IEnumerator
- // does not implement IDisposable. [Methods is supposed to throw anyway]
- _ = testBuilder.GetEnumerator();
-#pragma warning restore IDISP004 // Don't ignore created IDisposable
- }
- , "Syntactic sugar only for initialization");
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/PolyFillExceptionValidatorsTests.cs b/src/Ubiquity.NET.Extensions.UT/PolyFillExceptionValidatorsTests.cs
deleted file mode 100644
index fc3dda87f..000000000
--- a/src/Ubiquity.NET.Extensions.UT/PolyFillExceptionValidatorsTests.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-// 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.
-
-// .NET 7 added the various exception static methods for parameter validation
-// This will back fill them for earlier versions.
-//
-// NOTE: C #14 extension keyword support is required to make this work.
-#if !NET7_0_OR_GREATER
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class PolyFillExceptionValidatorsTests
- {
-#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
- [TestMethod]
- public void ThrowIfNullOrWhiteSpace_throws_if_null_or_whitespace( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNullOrWhiteSpace( null ));
- Assert.AreEqual( "null", ex.ParamName, "Compiler should provide expression as name" );
-
- ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNullOrWhiteSpace( null, "self" ) );
- Assert.AreEqual( "self", ex.ParamName, "explicit name should override compiler" );
-
- var argEx = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNullOrWhiteSpace(" \t "));
- Assert.AreEqual( "\" \\t \"", argEx.ParamName, "Compiler should provide expression as name" );
-
- argEx = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNullOrWhiteSpace( " \t ", "self" ) );
- Assert.AreEqual( "self", argEx.ParamName, "explicit name should override compiler" );
-
- argEx = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNullOrWhiteSpace( string.Empty ) );
- Assert.AreEqual( "string.Empty", argEx.ParamName, "Compiler should provide expression as name" );
-
- argEx = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNullOrWhiteSpace( string.Empty, "self" ) );
- Assert.AreEqual( "self", argEx.ParamName, "explicit name should override compiler" );
- }
-
- [TestMethod]
- public void ThrowIfNull_throws_if_null( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNull( null ));
- Assert.AreEqual( "null", ex.ParamName, "Compiler should provide expression as name" );
-
- ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNull( null, "self" ) );
- Assert.AreEqual( "self", ex.ParamName, "explicit name should override compiler" );
- }
-#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
-
- [TestMethod]
- public void ThrowIf_throws_as_expected( )
- {
- object instance = new();
-
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIf(true, instance));
- Assert.AreEqual( "System.Object", ex.ObjectName );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIf( false, instance );
- }
-
- [TestMethod]
- public void ArgumentOutOfRangeExcpetion_ThrowIfEqual_operates_as_expected( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfEqual(1, 1));
- Assert.AreEqual( "1", ex.ParamName );
- Assert.AreEqual( 1, ex.ActualValue );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIfEqual( 1, 0 );
- }
-
- [TestMethod]
- public void ArgumentOutOfRangeExcpetion_ThrowIfNotEqual_operates_as_expected( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfNotEqual(1, 0));
- Assert.AreEqual( "1", ex.ParamName );
- Assert.AreEqual( 1, ex.ActualValue );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIfNotEqual( 1, 1 );
- }
-
- [TestMethod]
- public void ArgumentOutOfRangeExcpetion_ThrowIfGreaterThan_operates_as_expected( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfGreaterThan(1, 0));
- Assert.AreEqual( "1", ex.ParamName );
- Assert.AreEqual( 1, ex.ActualValue );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIfGreaterThan( 0, 1 );
- }
-
- [TestMethod]
- public void ArgumentOutOfRangeExcpetion_ThrowIfGreaterThanOrEqual_operates_as_expected( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfGreaterThanOrEqual(1, 1));
- Assert.AreEqual( "1", ex.ParamName );
- Assert.AreEqual( 1, ex.ActualValue );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIfGreaterThanOrEqual( 0, 1 );
- }
-
- [TestMethod]
- public void ArgumentOutOfRangeExcpetion_ThrowIfLessThan_operates_as_expected( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfLessThan(0, 1));
- Assert.AreEqual( "0", ex.ParamName );
- Assert.AreEqual( 0, ex.ActualValue );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIfLessThan( 1, 0 );
- }
-
- [TestMethod]
- public void ArgumentOutOfRangeExcpetion_ThrowIfLessThanOrEqual_operates_as_expected( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillExceptionValidators.ThrowIfLessThanOrEqual(1, 1));
- Assert.AreEqual( "1", ex.ParamName );
- Assert.AreEqual( 1, ex.ActualValue );
-
- // should not throw
- PolyFillExceptionValidators.ThrowIfLessThanOrEqual( 1, 0 );
- }
- }
-}
-#endif
diff --git a/src/Ubiquity.NET.Extensions.UT/PolyFillOperatingSystemTests.cs b/src/Ubiquity.NET.Extensions.UT/PolyFillOperatingSystemTests.cs
deleted file mode 100644
index 7092894f4..000000000
--- a/src/Ubiquity.NET.Extensions.UT/PolyFillOperatingSystemTests.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- public sealed class PolyFillOperatingSystemTests
- {
- [TestMethod]
- public void IsWindows_reports_correct_value( )
- {
- bool isWindows = Environment.OSVersion.Platform switch
- {
- PlatformID.Win32S or
- PlatformID.Win32Windows or
- PlatformID.Win32NT or
- PlatformID.WinCE => true,
- _ => false,
- };
-
- Assert.AreEqual(isWindows, OperatingSystem.IsWindows());
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/PolyFillStringExtensionsTests.cs b/src/Ubiquity.NET.Extensions.UT/PolyFillStringExtensionsTests.cs
deleted file mode 100644
index 9d9d4e56a..000000000
--- a/src/Ubiquity.NET.Extensions.UT/PolyFillStringExtensionsTests.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.
-
-#if !NET6_0_OR_GREATER
-// need to import the namespace to allow implicit access to extensions
-using System.Text;
-#endif
-
-namespace Ubiquity.NET.Extensions.UT
-{
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class PolyFillStringExtensionsTests
- {
- // since these are ONLY an extension with runtime's prior to .NET 6
- // test the handling. For .NET6 or later, that's up to .NET itself to test
-#if !NET6_0_OR_GREATER
-#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
- [TestMethod]
- public void Methods_throw_on_invalid_input( )
- {
- var ex = Assert.ThrowsExactly( ( ) => PolyFillStringExtensions.ReplaceLineEndings( null ));
- Assert.AreEqual( "self", ex.ParamName );
-
- ex = Assert.ThrowsExactly( ( ) => PolyFillStringExtensions.ReplaceLineEndings( null, "replacement" ));
- Assert.AreEqual( "self", ex.ParamName );
-
- ex = Assert.ThrowsExactly( ( ) => PolyFillStringExtensions.ReplaceLineEndings( "source text", null ) );
- Assert.AreEqual( "replacementText", ex.ParamName );
- }
-#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
-#endif
-
- // Technically this tests both poly filled and official implementations, but validates the
- // assumptions that exist betweeen them. If both pass then the poly fill is replicating the
- // tested behavior of the official runtime implementation. (If, perhaps, less performant...)
-
- [TestMethod]
- public void ReplaceLineEndings_uses_Environment_newlines( )
- {
- const string inputMixedLines = "line0\r\nline1\rline2\nline3\fline4\u0085line5\u2028line6\u2029";
- string expected = "line0" + Environment.NewLine
- + "line1" + Environment.NewLine
- + "line2" + Environment.NewLine
- + "line3" + Environment.NewLine
- + "line4" + Environment.NewLine
- + "line5" + Environment.NewLine
- + "line6" + Environment.NewLine;
-
- string actual = inputMixedLines.ReplaceLineEndings();
- Assert.AreEqual(expected, actual);
- }
-
- [TestMethod]
- public void ReplaceLineEndings_uses_provided_string( )
- {
- const string inputMixedLines = "line0\r\nline1\rline2\nline3\fline4\u0085line5\u2028line6\u2029";
- const string expected = "line0line1line2line3line4line5line6";
-
- string actual = inputMixedLines.ReplaceLineEndings("");
- Assert.AreEqual( expected, actual );
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/StringNormalizerTests.cs b/src/Ubiquity.NET.Extensions.UT/StringNormalizerTests.cs
deleted file mode 100644
index e310727fd..000000000
--- a/src/Ubiquity.NET.Extensions.UT/StringNormalizerTests.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.UT
-{
- // NOTE: Test output will include special characters for CR (U+240D) and LF (U+240A) characters that makes it easy to visualize
- // line ending differences.
- //
- // Example:
- // Assert.AreEqual failed. Expected string length 51 but was 52. 'expected' expression: 'expectedOutput', 'actual' expression: 'systemNormalizedInput'.
- // Expected: "This is a line␊This is anotherline␊And..."
- // But was: "This is a line␍␊This is anotherline␍An..."
- // -------------------------^
-
- // NOTE: In C# the string "line1\nLine2" has exactly what was put in the string
- // That is, it contains a SINGLE LF '\n' character. NOT an environment
- // specific "newline". Thus, if a string needs to represent a platform specific
- // newline sequence it can use `Environment.NewLine` or `string.ReplaceLineEndings()`.
- // The docs on `ReplaceLineEndings()` are silent on the point of input forms
- // replaced. However, spelunking the code indicates it follows Unicode standard §5.8,
- // Recommendation R4 and Table 5-2 (CR, LF, CRLF, NEL, LS, FF, PS). Explicitly excluded
- // is VT. Thus, that will normalize ANY newline sequence to the form expected by the
- // environment.
- // Unfortunately, ReplaceLineEndings() is NOT available in downlevel runtimes...
-
- [TestClass]
- [ExcludeFromCodeCoverage]
- public sealed class StringNormalizerTests
- {
- [TestMethod]
- public void System_line_ending_detected_correctly( )
- {
- Assert.AreEqual( OsDefaultLineEnding, StringNormalizer.SystemLineEndings);
- }
-
- [TestMethod]
- public void Normalize_with_default_endings_does_nothing( )
- {
- string testInput = "This is a line" + Environment.NewLine + "And so is this"; // Platform sepecific
- string normalizedOutput = testInput.NormalizeLineEndings(StringNormalizer.SystemLineEndings);
- Assert.AreSame(testInput, normalizedOutput, "Should return same instance (zero copy)");
- }
-
- [TestMethod]
- public void Normalize_with_alternate_endings_produces_new_string( )
- {
- string testInput = "This is a line"+ Environment.NewLine + "And so is this"; // Platform sepecific
- const string expectedOutput = "This is a line\rAnd so is this";
-
- // CR Only is not the default for any currently supported runtinme for .NET so this
- // remains a platform neutral test - verify that assumption!
- // See also: System_line_ending_detected_correctly()
- Assert.AreNotEqual(LineEndingKind.CarriageReturn, StringNormalizer.SystemLineEndings, "TEST ERROR: CR is default line ending for this runtime!");
-
- string normalizedOutput = testInput.NormalizeLineEndings(LineEndingKind.CarriageReturn);
- Assert.AreEqual(expectedOutput, normalizedOutput);
- }
-
- [TestMethod]
- public void Normalize_with_mixed_input_succeeds()
- {
- const string mixedInput = "This is a line\r\nThis is anotherline\rAnd aonther line";
- string expectedOutput = "This is a line"+ Environment.NewLine + "This is anotherline"+ Environment.NewLine + "And aonther line"; // Platform sepecific
- string systemNormalizedInput = mixedInput.NormalizeLineEndings(LineEndingKind.MixedOrUnknownEndings, StringNormalizer.SystemLineEndings);
- Assert.AreEqual(expectedOutput, systemNormalizedInput);
- }
-
- // Technincally Mac OS prior to OS X (Lion) use CR, but .NET does not
- // support those older versions. Thus, this only treats Windows as the
- // "odd man out", everything else uses LF.
- private static LineEndingKind OsDefaultLineEnding
- => OperatingSystem.IsWindows()
- ? LineEndingKind.CarriageReturnLineFeed
- : LineEndingKind.LineFeed;
- }
-}
diff --git a/src/Ubiquity.NET.Extensions.UT/Ubiquity.NET.Extensions.UT.csproj b/src/Ubiquity.NET.Extensions.UT/Ubiquity.NET.Extensions.UT.csproj
deleted file mode 100644
index d3d73d298..000000000
--- a/src/Ubiquity.NET.Extensions.UT/Ubiquity.NET.Extensions.UT.csproj
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- net8.0;net481
-
- preview
- false
- True
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Ubiquity.NET.Extensions/AssemblyExtensions.cs b/src/Ubiquity.NET.Extensions/AssemblyExtensions.cs
deleted file mode 100644
index 552ed2092..000000000
--- a/src/Ubiquity.NET.Extensions/AssemblyExtensions.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions
-{
- /// Utility class to provide extensions for consumers
- [SuppressMessage( "Design", "CA1034:Nested types should not be visible", Justification = "Extension" )]
- public static class AssemblyExtensions
- {
- // VS2026 builds of this are OK, however VS2019, command line/PR/CI builds will generate an error.
- // The VS builds use the VS provided MSBuild, while the command line uses the .NET Core build.
- // This is just another example of why the `extension` keyword is "not yet ready for prime time".
- // Too many things don't support it properly yet so use needs justification as the ONLY option and
- // HEAVY testing to ensure all the issues are accounted for.
- // [Hopefully, that works itself out in short order as it's a mostly useless feature unless fully supported]
-#if COMPILER_SUPPORTS_CALLER_ATTRIBUES_ON_EXTENSION
- extension(Assembly self)
- {
- /// Gets the informational version from an assembly
- /// Expresssion for the assembly to retrieve the attribute data from; normally provided by compiler
- /// String contents from the in the assembly or
- [SuppressMessage( "Performance", "CA1822:Mark members as static", Justification = "Instance extension" )]
- public string GetInformationalVersion( [CallerArgumentExpression( nameof( self ) )] string? exp = null )
- {
- ArgumentNullException.ThrowIfNull( self, exp );
-
- var assemblyVersionAttribute = self.GetCustomAttribute();
-
- return assemblyVersionAttribute is not null
- ? assemblyVersionAttribute.InformationalVersion
- : self.GetName().Version?.ToString() ?? string.Empty;
- }
- }
-#else
- /// Gets the informational version from an assembly
- /// Assembly to extract the version from
- /// Expresssion for the assembly to retrieve the attribute data from; normally provided by compiler
- /// String contents from the in the assembly or
- public static string GetInformationalVersion(this Assembly self, [CallerArgumentExpression( nameof( self ) )] string? exp = null )
- {
- ArgumentNullException.ThrowIfNull( self, exp );
-
- var assemblyVersionAttribute = self.GetCustomAttribute();
-
- return assemblyVersionAttribute is not null
- ? assemblyVersionAttribute.InformationalVersion
- : self.GetName().Version?.ToString() ?? string.Empty;
- }
-#endif
-
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/DictionaryBuilder.cs b/src/Ubiquity.NET.Extensions/DictionaryBuilder.cs
deleted file mode 100644
index 9ade8101b..000000000
--- a/src/Ubiquity.NET.Extensions/DictionaryBuilder.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions
-{
- /// Simple type to support direct creation of an immutable array via
- /// Type of the key
- /// Type of the value
- ///
- ///
- /// For unknown reasons does not have an equivalent
- /// to (Perhaps because there is none for a dictionary?)
- /// the normal behavior of initializing a mutable dictionary and then converting it to immutable
- /// has sub-par performance as it needs to allocate the mutable form, add the members, then allocate
- /// the immutable form and COPY all the members. This includes the overhead of building and maintaining
- /// the hash codes for all the keys - just to copy it and destroy it... MUCH better performance is achieved
- /// by building the dictionary directly then converting it into the final immutable form.
- ///
- /// This implementation is based on a post on StackOverflow by Ian Griffiths (updated for latest language
- /// and runtime version functionality). It provides collection initialization support for
- /// .
- ///
- ///
- [SuppressMessage( "Design", "CA1010:Generic interface should also be implemented", Justification = "IEnumerable is unused but must exist to support collection initializers" )]
- [SuppressMessage( "Naming", "CA1710:Identifiers should have correct suffix", Justification = "It is the correct suffix" )]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Equality not relevant for a builder" )]
- public readonly struct DictionaryBuilder( )
- : IEnumerable
- where TKey : notnull
- {
- /// Add a key+value pair into the dictionary
- /// Key for the entry
- /// Value for the entry
- public void Add( TKey key, TValue value )
- {
- Builder.Add( key, value );
- }
-
- /// Indexer to set the value of an entry
- /// Key value to set
- /// Value to set for the
- /// Value type [Ignored for set only support]
- [SuppressMessage( "Design", "CA1044:Properties should not be write only", Justification = "This type is ONLY for building immutable dictionaries" )]
- public TValue this[ TKey key ]
- {
- set => Builder[ key ] = value;
- }
-
- ///
- [MustUseReturnValue]
- public ImmutableDictionary ToImmutable( )
- {
- return Builder.ToImmutable();
- }
-
- ///
- /// Always; Do not use this method. It exists only to allow compile time initializer syntax.
- public IEnumerator GetEnumerator( )
- {
- // Only implementing IEnumerable because collection initializer
- // syntax is unavailable if you don't.
- throw new NotImplementedException();
- }
-
- private readonly ImmutableDictionary.Builder Builder = ImmutableDictionary.CreateBuilder();
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/DisposableAction.cs b/src/Ubiquity.NET.Extensions/DisposableAction.cs
deleted file mode 100644
index a214fed35..000000000
--- a/src/Ubiquity.NET.Extensions/DisposableAction.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions
-{
- /// Disposable type that runs a specified action on dispose
- ///
- /// This is used in RAII pattern style code instead of try/finally. It is most
- /// valuable when the scope extends beyond a single function (as a return of
- /// ) where a try/finally simply won't work.
- ///
- public sealed class DisposableAction
- : IDisposable
- {
- /// Initializes a new instance of the class.
- /// Action to run when is called.
- /// Expression for any exceptions; default normally provided by compiler as expression for
- public DisposableAction( Action onDispose, [CallerArgumentExpression(nameof(onDispose))] string? exp = null )
- {
- OnDispose = onDispose ?? throw new ArgumentNullException( exp );
- }
-
- /// Runs the action provided in the constructor ()
- public void Dispose( )
- {
- var disposeOp = Interlocked.Exchange(ref OnDispose, null);
- disposeOp!();
- }
-
- /// Creates an implementation of that does nothing for the "Null Object" pattern
- /// The that does nothing on
- ///
- /// The instance returned is allocated from the managed heap to ensure that is
- /// called only once (any additional call results in an ).
- ///
- public static IDisposable CreateNOP()
- {
- return new DisposableAction(()=> { });
- }
-
- private Action? OnDispose;
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/FluentValidation/ExceptionValidationExtensions.cs b/src/Ubiquity.NET.Extensions/FluentValidation/ExceptionValidationExtensions.cs
deleted file mode 100644
index ec3908330..000000000
--- a/src/Ubiquity.NET.Extensions/FluentValidation/ExceptionValidationExtensions.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.FluentValidation
-{
- // This does NOT use the new C# 14 extension syntax due to several reasons
- // 1) Code lens does not work https://github.com/dotnet/roslyn/issues/79006 [Sadly, marked as "not planned" - e.g., dead-end]
- // 2) MANY analyzers get things wrong and need to be supressed (CA1000, CA1034, and many others [SAxxxx])
- // 3) Many external tools don't support the new syntax yet and it isn't clear if they will in the future.
- // 4) No clear support for Caller* attributes ([CallerArgumentExpression(...)]).
- //
- // Bottom line it's a good idea with an incomplete implementation lacking support
- // in the overall ecosystem. Don't use it unless you absolutely have to until all
- // of that is sorted out.
-
- /// Extension class to provide Fluent validation of arguments
- ///
- /// These are similar to many of the built-in support checks except that
- /// they use a `Fluent' style to allow validation of parameters used as inputs
- /// to other functions that ultimately produce parameters for a base constructor.
- /// They also serve to provide validation when using body expressions for property
- /// method implementations etc... Though the C# 14 field keyword makes that
- /// use mostly a moot point.
- ///
- /// In .NET Standard 2.0 builds this can create ambiguities with the static extensions
- /// in `PolyFillExceptionValidators`. This is becuase they are "Poly Filled"
- /// in downstream versions and the resolution rules for extensions in the C# language.
- /// Instance methods are resolved before the static extensions and therefore the extensions
- /// here are resolved even if there is a direct static extensions. This seems broken, but
- /// is how the language is resolving things. Therefore carefull use of namespace usings
- /// and global usings as well as explicit use of this type is needed to resolve this. It
- /// is NOT recommended to use explict references to the static method in `PolyFillExceptionValidators`
- /// as the methods don't exist if the BCL type contains the method already in a given
- /// runtime. Thus, in compilation units, needing both namespaces only this one is
- /// explicitly referenced.
- ///
- ///
- public static class ExceptionValidationExtensions
- {
- /// Throws an exception if is
- /// Type of reference parameter to test for
- /// Instance to test
- /// Name or expression of the value in [Default: provided by compiler]
- ///
- /// is
- [DebuggerStepThrough]
- public static T ThrowIfNull( [NotNull] this T? self, [CallerArgumentExpression( nameof( self ) )] string? exp = null )
- {
- return self is null
- ? throw new ArgumentNullException(exp)
- : self;
- }
-
- /// Throws an exception if an argument is outside of a given (Inclusive) range
- /// Type of value to test
- /// Value to test
- /// Minimum value allowed for
- /// Maximum value allowed for
- /// Name or expression of the value in [Default: provided by compiler]
- ///
- [DebuggerStepThrough]
- [SuppressMessage( "Style", "IDE0046:Convert to conditional expression", Justification = "Not simpler, more readable this way" )]
- public static T ThrowIfOutOfRange( this T self, T min, T max, [CallerArgumentExpression( nameof( self ) )] string? exp = null )
- where T : struct, IComparable
- {
- ArgumentOutOfRangeException.ThrowIfLessThan(self, min, exp);
- ArgumentOutOfRangeException.ThrowIfGreaterThan(self, max, exp);
- return self;
- }
-
- /// Tests if an enum is defined or not
- /// Type of value to test
- /// Value to test
- /// Name or expression of the value in [Default: provided by compiler]
- ///
- /// The enumerated value is not defined
- ///
- /// This is useful to prevent callers from playing tricks with casts, etc... to land with a value
- /// that is otherwise undefined. Note: This is mostly useless on an enumeration marked with
- /// as a legit value that is a combination of flags does not have
- /// a defined value (Only single bit values do)
- ///
- [DebuggerStepThrough]
- public static T ThrowIfNotDefined( this T self, [CallerArgumentExpression( nameof( self ) )] string? exp = null )
- where T : struct, Enum
- {
- exp ??= string.Empty;
-
- if(Enum.IsDefined( typeof(T), self ))
- {
- return self;
- }
-
- try
- {
- int underlyingValue = (int)Convert.ChangeType(self, typeof(int), CultureInfo.InvariantCulture);
- throw new InvalidEnumArgumentException( exp, underlyingValue, typeof( T ) );
- }
- catch(Exception ex) when (ex is InvalidCastException or FormatException or OverflowException)
- {
- // InvalidEnumArgumentException constructors ONLY provide paramater name value set for values
- // that are representable as an int. Thus, anything else requires a custom message that at
- // least includes the original value in question. (Normally an enum does fit an int, but for
- // interop might not) the resulting exception will have "ParamName" as the default of "null"!
- //
- // This matches the overloaded constructor version but allows for reporting enums with non-int underlying type.
- throw new InvalidEnumArgumentException( SR.Format( nameof( Resources.InvalidEnumArgument_NonInt ), exp, self, typeof( T ) ) );
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/FluentValidation/ReadMe.md b/src/Ubiquity.NET.Extensions/FluentValidation/ReadMe.md
deleted file mode 100644
index da2006705..000000000
--- a/src/Ubiquity.NET.Extensions/FluentValidation/ReadMe.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# About
-This folder contains fluent validation extensions. It is a distinct namespace to aid in
-diasambiguation when using downlevel polyfills for static validation extensions. When both
-instance extensions and static extensions are available with the same name there is an
-ambiguity and the compiler resolves to the instance extension. Thus,
-`.` is resolved as
-`.` when both are available. Thus, when supporting
-downlevel runtimes (like for a Roslyn Source generator/analyzer/fixer or VSIX extension)
-then both namespaces are not implicitly "used". Instead only one is. If both namespaces are
-needed in a compilation unit, then the poly fill is "used" and the fluent form is explicitly
-referenced. Thus, there is no implicit ambiguity/confusion.
diff --git a/src/Ubiquity.NET.Extensions/GlobalNamespaceImports.cs b/src/Ubiquity.NET.Extensions/GlobalNamespaceImports.cs
deleted file mode 100644
index 8137e3280..000000000
--- a/src/Ubiquity.NET.Extensions/GlobalNamespaceImports.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.
-
-/*
-NOTE:
-While the MsBuild `ImplicitUsings` property is banned from this repo, the C# language feature of global usings is NOT.
-The build property will auto include an invisible and undiscoverable (without looking up obscure documentation)
-set of namespaces that is NOT consistent or controlled by the developer. THAT is what is BAD/BROKEN about that feature.
-By banning it's use and then providing a `GlobalNamespaceImports.cs` source file with ONLY global using statements ALL of
-that is eliminated. Such use of the language feature restores FULL control and visibility of the namespaces to the developer,
-where it belongs. For a good explanation of this problem see: https://rehansaeed.com/the-problem-with-csharp-10-implicit-usings/.
-For an explanation of the benefits of the language feature see: https://www.hanselman.com/blog/implicit-usings-in-net-6
-*/
-
-// BUG: False positive from IDE0005 - Using directive is unnecessary
-// Attempts to remove/sort are at least able to figure it out and do the right thing.
-// Bug seems to be related to multi-targetting.
-#pragma warning disable IDE0005
-
-global using System;
-global using System.Collections;
-global using System.Collections.Generic;
-global using System.Collections.Immutable;
-global using System.ComponentModel;
-global using System.Diagnostics;
-global using System.Diagnostics.CodeAnalysis;
-global using System.Globalization;
-global using System.IO;
-global using System.Linq;
-global using System.Reflection;
-global using System.Runtime.CompilerServices;
-global using System.Text;
-global using System.Threading;
-
-global using Ubiquity.NET.Extensions.Properties;
diff --git a/src/Ubiquity.NET.Extensions/KvpArrayBuilder.cs b/src/Ubiquity.NET.Extensions/KvpArrayBuilder.cs
deleted file mode 100644
index b533adb04..000000000
--- a/src/Ubiquity.NET.Extensions/KvpArrayBuilder.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions
-{
- /// Simple type to support dictionary style creation of an immutable array of KeyValue pairs via
- /// Type of the key
- /// Type of the value
- ///
- ///
- /// This allows creation of an array of pairs without incurring the overhead of allocating and initializing
- /// the hash codes for the keys, if they are not used. (As may be the case if the list is provided to
- /// native interop). The normal behavior of building an would
- /// at a minimum incur the cost of allocation and computation of the hash code for each key.
- /// MUCH better performance is achieved by building the array via a builder then converting it into the
- /// final immutable form.
- ///
- /// This implementation is based on a post on StackOverflow by Ian Griffiths (updated for latest language
- /// and runtime version functionality and to produce an ). It provides collection
- /// initialization support for a sequence of .
- ///
- ///
- [SuppressMessage( "Design", "CA1010:Generic interface should also be implemented", Justification = "IEnumerable is unused but must exist to support collection initializers" )]
- [SuppressMessage( "Naming", "CA1710:Identifiers should have correct suffix", Justification = "It is the correct suffix; This is NOT a collection it's a builder" )]
- [SuppressMessage( "Performance", "CA1815:Override equals and operator equals on value types", Justification = "Equality not relevant for a builder" )]
- public readonly struct KvpArrayBuilder( )
- : IEnumerable
- where TKey : notnull
- {
- /// Add a key+value pair into the dictionary
- /// Key for the entry
- /// Value for the entry
- public void Add( TKey key, TValue value )
- {
- Builder.Add( new( key, value ) );
- }
-
- /// Indexer to set the value of an entry
- /// Key value to set
- /// Value to set for the
- /// Value type [Ignored for set only support]
- ///
- ///
- /// Since this builder does NOT store or compute hash codes the indexer is a syntactical convenience
- /// wrapper around the method. It does NOT prevent duplicate entries. If you use
- /// the same with a different value, then you get TWO entries with that key.
- /// (In some scenarios this may be desirable, but in most it is not.) The important point on this is
- /// that it is ***NOT*** checked here.
- ///
- ///
- [SuppressMessage( "Design", "CA1044:Properties should not be write only", Justification = "This type is ONLY for building immutable arrays" )]
- public TValue this[ TKey key ]
- {
- set => Add( key, value );
- }
-
- ///
- [MustUseReturnValue]
- public ImmutableArray> ToImmutable( )
- {
- return Builder.ToImmutable();
- }
-
- ///
- /// Always; Do not use this method. It exists only to allow compile time initializer syntax.
- [DoesNotReturn]
- public IEnumerator GetEnumerator( )
- {
- // Only implementing IEnumerable because collection initializer
- // syntax is unavailable if you don't.
- throw new NotImplementedException();
- }
-
- private readonly ImmutableArray>.Builder Builder = ImmutableArray.CreateBuilder>();
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/MustUseReturnValueAttribute.cs b/src/Ubiquity.NET.Extensions/MustUseReturnValueAttribute.cs
deleted file mode 100644
index 43447d89f..000000000
--- a/src/Ubiquity.NET.Extensions/MustUseReturnValueAttribute.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions
-{
- /// `MustUseRetVal` analyzer compatible attribute
- ///
- ///
- [AttributeUsage( AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Struct )]
- public sealed class MustUseReturnValueAttribute
- : Attribute
- {
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/ProcessInfo.cs b/src/Ubiquity.NET.Extensions/ProcessInfo.cs
deleted file mode 100644
index 8e51ea05d..000000000
--- a/src/Ubiquity.NET.Extensions/ProcessInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions
-{
- /// Process related extensions/support
- public static class ProcessInfo
- {
- /// Gets the active assembly as of the first use of this property
- ///
- /// The active assembly is the entry assembly which may be null if called from native
- /// code as no such assembly exists for that scenario.
- ///
- public static Assembly? ActiveAssembly => field ??= Assembly.GetEntryAssembly();
-
- /// Gets the executable path for this instance of an application
- /// This is a short hand for [ 0 ]
- public static string ExecutablePath => Environment.GetCommandLineArgs()[ 0 ];
-
- /// Gets the name of the executable for this instance of an application
- ///
- /// This is a short hand for using
- /// as the path.
- ///
- public static string ExecutableName => Path.GetFileNameWithoutExtension( ExecutablePath );
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/Properties/ResourceNotFoundException.cs b/src/Ubiquity.NET.Extensions/Properties/ResourceNotFoundException.cs
deleted file mode 100644
index 2fe41e37d..000000000
--- a/src/Ubiquity.NET.Extensions/Properties/ResourceNotFoundException.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.Properties
-{
- /// Exception thornw if a resource is missing
- ///
- /// This is ALWAYS a bug in the application and should not be caught or suppressed in any way.
- /// It indicates that a named resource does not exist, either add the resource or correct the
- /// spelling of the name - NEVER dismiss this.
- ///
- [Serializable]
- public class ResourceNotFoundException
- : Exception
- {
- /// Initializes a new instance of the class.
- public ResourceNotFoundException( )
- {
- }
-
- ///
- public ResourceNotFoundException( string resourceName )
- : base( string.Format( Resources.Culture, Resources.Missing_Resource_Exception_Message_fmt, resourceName ) )
- {
- ResourceName = resourceName;
- }
-
- ///
- public ResourceNotFoundException( string message, Exception inner )
- : base( message, inner )
- {
- }
-
- /// Gets the name of the resource missing
- public string ResourceName { get; } = string.Empty;
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/Properties/Resources.Designer.cs b/src/Ubiquity.NET.Extensions/Properties/Resources.Designer.cs
deleted file mode 100644
index 71cb072c4..000000000
--- a/src/Ubiquity.NET.Extensions/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,171 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace Ubiquity.NET.Extensions.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ubiquity.NET.Extensions.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to The value cannot be an empty string or composed entirely of whitespace..
- ///
- internal static string Argument_EmptyOrWhiteSpaceString {
- get {
- return ResourceManager.GetString("Argument_EmptyOrWhiteSpaceString", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be equal to '{2}'..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeEqual {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeEqual", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be greater than '{2}'..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeGreater {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeGreater", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be greater than or equal to '{2}'..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeGreaterOrEqual {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeGreaterOrEqual", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be less than '{2}'..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeLess {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeLess", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be less than or equal to '{2}'..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeLessOrEqual {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeLessOrEqual", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be a non-negative value..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeNonNegative {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeNonNegative", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be a non-negative and non-zero value..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeNonNegativeNonZero {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeNonNegativeNonZero", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must be a non-zero value..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeNonZero {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeNonZero", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ('{1}') must not be equal to '{2}'..
- ///
- internal static string ArgumentOutOfRange_Generic_MustBeNotEqual {
- get {
- return ResourceManager.GetString("ArgumentOutOfRange_Generic_MustBeNotEqual", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to The value of argument '{0}' ({1}) is invalid for Enum of type '{2}'.
- ///
- internal static string InvalidEnumArgument_NonInt {
- get {
- return ResourceManager.GetString("InvalidEnumArgument_NonInt", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Missing resource. Name='{0}'.
- ///
- internal static string Missing_Resource_Exception_Message_fmt {
- get {
- return ResourceManager.GetString("Missing_Resource_Exception_Message_fmt", resourceCulture);
- }
- }
- }
-}
diff --git a/src/Ubiquity.NET.Extensions/Properties/Resources.resx b/src/Ubiquity.NET.Extensions/Properties/Resources.resx
deleted file mode 100644
index 62c8ccfc7..000000000
--- a/src/Ubiquity.NET.Extensions/Properties/Resources.resx
+++ /dev/null
@@ -1,157 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- {0} ('{1}') must be a non-zero value.
-
-
- {0} ('{1}') must be a non-negative value.
-
-
- {0} ('{1}') must be a non-negative and non-zero value.
-
-
- {0} ('{1}') must be less than or equal to '{2}'.
-
-
- {0} ('{1}') must be less than '{2}'.
-
-
- {0} ('{1}') must be greater than or equal to '{2}'.
-
-
- {0} ('{1}') must be greater than '{2}'.
-
-
- {0} ('{1}') must be equal to '{2}'.
-
-
- {0} ('{1}') must not be equal to '{2}'.
-
-
- The value cannot be an empty string or composed entirely of whitespace.
-
-
- The value of argument '{0}' ({1}) is invalid for Enum of type '{2}'
- Message used for enums with an underlying type that is not able to fit into an int. {0} - expression that generated the exception; {1} value of the expression that is invalid; {2} is the type of the enumeration.
-
-
- Missing resource. Name='{0}'
-
-
\ No newline at end of file
diff --git a/src/Ubiquity.NET.Extensions/Properties/SR.cs b/src/Ubiquity.NET.Extensions/Properties/SR.cs
deleted file mode 100644
index d59355747..000000000
--- a/src/Ubiquity.NET.Extensions/Properties/SR.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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.
-
-namespace Ubiquity.NET.Extensions.Properties
-{
- // RESX file generator does not use `partial` and VS2022 doesn't correctly support
- // C# 14 `extension` so derivation is the only option at present...
- // CONSIDER: Generator to create this from an attribute that includes the type of the Resources
- // generator/Analyzer should validate that the type has a ResourceManager member.
- // (Effectively a C++ concept since the type is generated by a SingleFileGenerator
- // it doesn't have an interface or base type to use as a constraint)
- internal static class SR
- {
- internal static string Format( [NotNull] string resourceName, TArg0 arg0 )
- {
- ArgumentNullException.ThrowIfNull(resourceName);
-
- string? fmt = Resources.ResourceManager.GetString(resourceName, Resources.Culture) ?? throw new ResourceNotFoundException(resourceName);
- return string.Format(Resources.Culture, fmt, arg0);
- }
-
- internal static string Format( [NotNull] string resourceName, TArg0 arg0, TArg1 arg1 )
- {
- ArgumentNullException.ThrowIfNull(resourceName);
-
- string? fmt = Resources.ResourceManager.GetString(resourceName, Resources.Culture) ?? throw new ResourceNotFoundException(resourceName);
- return string.Format(Resources.Culture, fmt, arg0, arg1);
- }
-
- internal static string Format( [NotNull] string resourceName, TArg0 arg0, TArg1 arg1, TArg2 arg2 )
- {
- ArgumentNullException.ThrowIfNull(resourceName);
-
- string? fmt = Resources.ResourceManager.GetString(resourceName, Resources.Culture) ?? throw new ResourceNotFoundException(resourceName);
- return string.Format(Resources.Culture, fmt, arg0, arg1, arg2);
- }
-
- internal static string Format( [NotNull] string resourceName, params IEnumerable