From 4e5a3acaaa993e9ce25408c2cf5c393a77d9cfe3 Mon Sep 17 00:00:00 2001 From: MaceWindu Date: Sun, 9 Oct 2022 17:21:54 +0200 Subject: [PATCH 01/38] - initial project refactoring - migration to scaffold framework --- .editorconfig | 5 +- .gitignore | 1 - Build/BuildNuspecs.ps1 | 2 +- Build/README.md | 11 +- Build/linq2db.LINQPad.nuspec | 24 +- Directory.Packages.props | 40 +- .../NotifyPropertyChanged.ttinclude | 6 +- LinqToDB.Templates/README.md | 1 + README.md | 25 +- Source/AppJsonConfig.cs | 72 +- Source/CSharpTools.cs | 166 --- Source/CX.cs | 40 +- Source/Compat/IsExternalInit.cs | 19 + Source/Compat/NullableAttributes.cs | 149 ++ Source/Compat/SkipLocalsInitAttribute.cs | 34 + .../{ => Configuration}/ConnectionDialog.xaml | 412 +++--- .../ConnectionDialog.xaml.cs | 586 ++++---- .../Configuration/StringToIntegerConverter.cs | 23 + Source/ConnectionViewModel.cs | 34 +- Source/ConnectionViewModel.generated.cs | 8 +- Source/ConnectionViewModel.tt | 3 + Source/DataModel/DataModelAugmentor.cs | 77 + Source/DataModel/ModelProviderInterceptor.cs | 566 ++++++++ Source/DriverHelper.cs | 407 +++--- Source/Extensions.cs | 71 +- Source/LINQPadDataConnection.cs | 63 +- Source/LinqToDBDriver.cs | 374 ++--- Source/LinqToDBLinqPadException.cs | 9 +- Source/LinqToDBStaticDriver.cs | 159 ++- Source/NullableAttributes.cs | 150 -- Source/Pluralization.cs | 79 +- Source/Properties/AssemblyInfo.cs | 5 +- Source/ProviderHelper.cs | 385 +++-- Source/SchemaAndCodeGenerator.PostgreSQL.cs | 124 -- Source/SchemaAndCodeGenerator.cs | 1025 ++------------ Source/SchemaGenerator.cs | 331 +++-- Source/StringToIntegerConverter.cs | 25 - Source/XmlFormatter.cs | 1243 +++++++++-------- Source/linq2db.LINQPad.csproj | 57 +- linq2db.LINQPad.sln | 29 +- nuget.config | 7 + release-notes.md | 32 + 42 files changed, 3312 insertions(+), 3567 deletions(-) create mode 100644 LinqToDB.Templates/README.md delete mode 100644 Source/CSharpTools.cs create mode 100644 Source/Compat/IsExternalInit.cs create mode 100644 Source/Compat/NullableAttributes.cs create mode 100644 Source/Compat/SkipLocalsInitAttribute.cs rename Source/{ => Configuration}/ConnectionDialog.xaml (96%) rename Source/{ => Configuration}/ConnectionDialog.xaml.cs (93%) create mode 100644 Source/Configuration/StringToIntegerConverter.cs create mode 100644 Source/DataModel/DataModelAugmentor.cs create mode 100644 Source/DataModel/ModelProviderInterceptor.cs delete mode 100644 Source/NullableAttributes.cs delete mode 100644 Source/SchemaAndCodeGenerator.PostgreSQL.cs delete mode 100644 Source/StringToIntegerConverter.cs create mode 100644 nuget.config diff --git a/.editorconfig b/.editorconfig index c0eadd3..50b1333 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,3 @@ -; What is EditorConfig? http://editorconfig.org/ - root = true ; use tabs identation for all files @@ -227,6 +225,9 @@ dotnet_diagnostic.IDE0079.severity = none # IDE0079: Remove unnecessary suppress dotnet_diagnostic.IDE0080.severity = none # IDE0080: Remove unnecessary suppression operator dotnet_diagnostic.IDE0081.severity = none # IDE0081: Remove ByVal dotnet_diagnostic.IDE0083.severity = none # IDE0083: Use pattern matching (not operator) +dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure +dotnet_diagnostic.IDE0160.severity = none # IDE0160: Use block-scoped namespace +dotnet_diagnostic.IDE0161.severity = error # IDE0161: Use file-scoped namespace dotnet_diagnostic.IDE1006.severity = none # IDE1006: Naming rule violation dotnet_diagnostic.CS1998.severity = error # CS1998: Async method lacks 'await' operators and will run synchronously diff --git a/.gitignore b/.gitignore index 5fcb5d8..6147e34 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -#Ignore files build by Visual Studio .vs/ bin/ obj/ diff --git a/Build/BuildNuspecs.ps1 b/Build/BuildNuspecs.ps1 index 9c1e861..5e6850f 100644 --- a/Build/BuildNuspecs.ps1 +++ b/Build/BuildNuspecs.ps1 @@ -37,7 +37,7 @@ if ($version) { $xml.package.metadata.AppendChild($child) $child = $xml.CreateElement('copyright', $nsUri) - $child.InnerText = 'Copyright © 2016-2020 ' + $authors + $child.InnerText = 'Copyright © 2016-2022 ' + $authors $xml.package.metadata.AppendChild($child) $child = $xml.CreateElement('authors', $nsUri) diff --git a/Build/README.md b/Build/README.md index ecc2898..8c83668 100644 --- a/Build/README.md +++ b/Build/README.md @@ -1,23 +1,25 @@ -## LINQ to DB LINQPad 6 and 7 Driver +# LINQ to DB LINQPad 6 and 7 Driver This nuget package is a driver for [LINQPad 6 and 7](http://www.linqpad.net). Following databases supported: +- **ClickHouse** (Binary, HTTP and MySQL interfaces) - **DB2** (LUW, z/OS) (only 64-bit version) - **Firebird** - **Informix** (only 64-bit version) - **Microsoft Access** *(supports both OleDb and ODBC)* - **Microsoft Sql Server** 2005+ *(including **Microsoft Sql Azure**)* - **Microsoft Sql Server Compact (SqlCe)** -- **MySql/MariaDB** +- **MariaDB** +- **MySql** - **Oracle** - **PostgreSQL** -- **SQLite** - **SAP HANA** *(client software must be installed, supports both Native and ODBC providers)* - **SAP/Sybase ASE** +- **SQLite** -### Installation +## Installation - Click "Add connection" in LINQPad. - In the "Choose Data Context" dialog, press the "View more drivers..." button. @@ -26,4 +28,3 @@ Following databases supported: - In the "Choose Data Context" dialog, select the "LINQ to DB" driver and click the "Next" button. - In the "LINQ to DB connection" dialog, supply your connection information. - You're done. - diff --git a/Build/linq2db.LINQPad.nuspec b/Build/linq2db.LINQPad.nuspec index 1b0c4a2..fddd40b 100644 --- a/Build/linq2db.LINQPad.nuspec +++ b/Build/linq2db.LINQPad.nuspec @@ -11,26 +11,32 @@ README.md + + + - - - - - + + + + + - - - - + + + + + + + diff --git a/Directory.Packages.props b/Directory.Packages.props index 2165f19..d5ed1a0 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,9 +1,11 @@  - + + + @@ -11,32 +13,26 @@ - + + + + + + - - - + + - - - - - - + + + + + - - - - - - - - - - - + + diff --git a/LinqToDB.Templates/NotifyPropertyChanged.ttinclude b/LinqToDB.Templates/NotifyPropertyChanged.ttinclude index 32cad1c..6aa522a 100644 --- a/LinqToDB.Templates/NotifyPropertyChanged.ttinclude +++ b/LinqToDB.Templates/NotifyPropertyChanged.ttinclude @@ -219,16 +219,16 @@ void NotifyPropertyChangedImpl() { new Event("PropertyChangedEventHandler", "PropertyChanged", true) { - IsVirtual = true, + IsVirtual = false, Attributes = { new Attribute("field : NonSerialized") } }, new Method(() => "void", "OnPropertyChanged", new Func[] { () => "string propertyName" }, () => OnPropertyChangedBody) { - AccessModifier = AccessModifier.Protected + AccessModifier = AccessModifier.Private }, new Method(() => "void", "OnPropertyChanged", new Func[] { () => "PropertyChangedEventArgs arg" }, () => OnPropertyChangedArgBody) { - AccessModifier = AccessModifier.Protected + AccessModifier = AccessModifier.Private }, } }); diff --git a/LinqToDB.Templates/README.md b/LinqToDB.Templates/README.md new file mode 100644 index 0000000..9a42a50 --- /dev/null +++ b/LinqToDB.Templates/README.md @@ -0,0 +1 @@ +Folder contains helper templates for WPF view generation. \ No newline at end of file diff --git a/README.md b/README.md index 860e4b4..9f8226d 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,38 @@ -## LINQ to DB LINQPad Driver +# LINQ to DB LINQPad Driver [![NuGet Version and Downloads count](https://buildstats.info/nuget/linq2db.LINQPad?includePreReleases=true)](https://www.nuget.org/packages/linq2db.LINQPad) [![License](https://img.shields.io/github/license/linq2db/linq2db.LINQPad)](MIT-LICENSE.txt) [![Master branch build](https://img.shields.io/azure-devops/build/linq2db/linq2db/8/master?label=build%20(master))](https://dev.azure.com/linq2db/linq2db/_build?definitionId=8&_a=summary) [![Latest build](https://img.shields.io/azure-devops/build/linq2db/linq2db/8?label=build%20(latest))](https://dev.azure.com/linq2db/linq2db/_build?definitionId=8&_a=summary) -linq2db.LINQPad is a driver for [LINQPad 5 (.NET Framework)](http://www.linqpad.net) and [LINQPad 6-7 (.NET Core)](http://www.linqpad.net). +linq2db.LINQPad is a driver for [LINQPad 5 (.NET Framework)](http://www.linqpad.net) and [LINQPad 6-7 (.NET/Core)](http://www.linqpad.net). Following databases supported (by all LINQPad versions if other not noted): +- **ClickHouse**: Binary (LINQPad 6+), HTTP and MySQL interfaces - **DB2** (LUW, z/OS) (LINQPad 6+ supports only 64-bit version) - **DB2 iSeries** (using [3rd-party provider](https://github.com/LinqToDB4iSeries/Linq2DB4iSeries)) *(iAccess 7.1+ software must be installed)*. **IMPORTANT:** currently available only for LINQPad 5 using linq2db.LINQPad version 2.9.3 or earlier - **Firebird** - **Informix** (LINQPad 6+ supports only 64-bit version) - **Microsoft Access** *(supports both OleDb and ODBC)* -- **Microsoft Sql Server** 2000+ *(including **Microsoft Sql Azure**. LINQPad 6+ [doesn't support](https://stackoverflow.com/a/45418196) **Sql Server 2000**)* +- **Microsoft Sql Server** 2005+ *(including **Microsoft Sql Azure**)* - **Microsoft Sql Server Compact (SqlCe)** -- **MySql/MariaDB** +- **MariaDB** +- **MySql** - **Oracle** - **PostgreSQL** -- **SQLite** - **SAP HANA** *(client software must be installed, supports both Native and ODBC providers)* - **SAP/Sybase ASE** +- **SQLite** -### Download +## Download Releases are hosted on [Github](https://github.com/linq2db/linq2db.LINQPad/releases) and on [Nuget](https://www.nuget.org/packages/linq2db.LINQPad) for LINQPad 6+ driver. Latest build is hosted on [Azure Artifacts](https://dev.azure.com/linq2db/linq2db/_packaging?_a=package&feed=linq2db%40Local&package=linq2db.LINQPad&protocolType=NuGet). Feed [URL](https://pkgs.dev.azure.com/linq2db/linq2db/_packaging/linq2db/nuget/v3/index.json) ([how to use](https://docs.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio#package-sources)). +## Installation -### Installation - -#### LINQPad 6+ (NuGet) +### LINQPad 6+ (NuGet) - Click "Add connection" in LINQPad. - In the "Choose Data Context" dialog, press the "View more drivers..." button. @@ -41,7 +42,7 @@ Latest build is hosted on [Azure Artifacts](https://dev.azure.com/linq2db/linq2d - In the "LINQ to DB connection" dialog, supply your connection information. - You're done. -#### LINQPad 6+ (Manual) +### LINQPad 6+ (Manual) - Download latest **.lpx6** file from the link provided above. - Click "Add connection" in LINQPad. @@ -52,7 +53,7 @@ Latest build is hosted on [Azure Artifacts](https://dev.azure.com/linq2db/linq2d - In the "LINQ to DB connection" dialog, supply your connection information. - You're done. -#### LINQPad 5 (Choose a driver) +### LINQPad 5 (Choose a driver) - Click "Add connection" in LINQPad. - In the "Choose Data Context" dialog, press the "View more drivers..." button. @@ -62,7 +63,7 @@ Latest build is hosted on [Azure Artifacts](https://dev.azure.com/linq2db/linq2d - In the "LINQ to DB connection" dialog, supply your connection information. - You're done. -#### LINQPad 5 (Manual) +### LINQPad 5 (Manual) - Download latest **.lpx** file from the link provided above. - Click "Add connection" in LINQPad. diff --git a/Source/AppJsonConfig.cs b/Source/AppJsonConfig.cs index fd17baa..7fc220d 100644 --- a/Source/AppJsonConfig.cs +++ b/Source/AppJsonConfig.cs @@ -1,56 +1,52 @@ #if NETCORE -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text.Json; using LinqToDB.Configuration; -namespace LinqToDB.LINQPad +namespace LinqToDB.LINQPad; + +internal sealed class AppJsonConfig : ILinqToDBSettings { - internal class AppJsonConfig : ILinqToDBSettings + public static ILinqToDBSettings Load(string configPath) { - public static ILinqToDBSettings Load(string configPath) - { - var config = JsonSerializer.Deserialize(File.ReadAllText(configPath)); + var config = JsonSerializer.Deserialize(File.ReadAllText(configPath)); - return new AppJsonConfig(config?.ConnectionStrings?.Select(entry => (IConnectionStringSettings)new ConnectionStringSettings(entry.Key, entry.Value)).ToArray() - ?? Array.Empty()); - } + return new AppJsonConfig(config?.ConnectionStrings?.Select(entry => (IConnectionStringSettings)new ConnectionStringSettings(entry.Key, entry.Value)).ToArray() + ?? Array.Empty()); + } - private readonly IConnectionStringSettings[] _connectionStrings; + private readonly IConnectionStringSettings[] _connectionStrings; - public AppJsonConfig(IConnectionStringSettings[] connectionStrings) - { - _connectionStrings = connectionStrings; - } + public AppJsonConfig(IConnectionStringSettings[] connectionStrings) + { + _connectionStrings = connectionStrings; + } - IEnumerable ILinqToDBSettings.DataProviders => Array.Empty(); - string? ILinqToDBSettings.DefaultConfiguration => null; - string? ILinqToDBSettings.DefaultDataProvider => null; - IEnumerable ILinqToDBSettings.ConnectionStrings => _connectionStrings; + IEnumerable ILinqToDBSettings.DataProviders => Array.Empty(); + string? ILinqToDBSettings.DefaultConfiguration => null; + string? ILinqToDBSettings.DefaultDataProvider => null; + IEnumerable ILinqToDBSettings.ConnectionStrings => _connectionStrings; - private class JsonConfig - { - public IDictionary? ConnectionStrings { get; set; } - } + private sealed class JsonConfig + { + public IDictionary? ConnectionStrings { get; set; } + } - private class ConnectionStringSettings : IConnectionStringSettings + private sealed class ConnectionStringSettings : IConnectionStringSettings + { + private readonly string _name; + private readonly string _connectionString; + + public ConnectionStringSettings(string name, string connectionString) { - private readonly string _name; - private readonly string _connectionString; - - public ConnectionStringSettings(string name, string connectionString) - { - _name = name; - _connectionString = connectionString; - } - - string IConnectionStringSettings.ConnectionString => _connectionString; - string IConnectionStringSettings.Name => _name; - string? IConnectionStringSettings.ProviderName => null; - bool IConnectionStringSettings.IsGlobal => false; + _name = name; + _connectionString = connectionString; } + + string IConnectionStringSettings.ConnectionString => _connectionString; + string IConnectionStringSettings.Name => _name; + string? IConnectionStringSettings.ProviderName => null; + bool IConnectionStringSettings.IsGlobal => false; } } #endif diff --git a/Source/CSharpTools.cs b/Source/CSharpTools.cs deleted file mode 100644 index 5b36319..0000000 --- a/Source/CSharpTools.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System.Collections.Generic; -using System.Globalization; -using System.Text; - -namespace LinqToDB.LINQPad -{ - // added temporary from https://github.com/linq2db/linq2db/pull/1393 - internal static class CSharpTools - { - /// - /// Reserved words (keywords) taken from - /// . - /// List actual for C# 8.0. - /// - private static readonly ISet _reservedWords - = new HashSet() - { - "abstract", "as", "base", "bool", "break", "byte", "case", "catch", - "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", - "do", "double", "else", "enum", "event", "explicit", "extern", "false", - "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", - "in", "int", "interface", "internal", "is", "lock", "long", "namespace", - "new", "null", "object", "operator", "out", "override", "params", "private", - "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", - "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", - "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", - "using", "virtual", "void", "volatile", "while" - }; - - /// - /// Contextual words taken from - /// . - /// List actual for C# 7.3. - /// - private static readonly ISet _contextualWords - = new HashSet() - { - "add", "alias", "ascending", "async", "await", "by", "descending", "dynamic", - "equals", "from", "get", "global", "group", "into", "join", "let", - "nameof", "on", "orderby", "partial", "remove", "select", "set", "unmanaged", - "value", "var", "when", "where", "yield" - }; - - private static readonly ISet _otherCharsCategories; - - private static readonly ISet _startCharCategories; - - static CSharpTools() - { - _startCharCategories = new HashSet() - { - // Lu letter - UnicodeCategory.UppercaseLetter, - // Ll letter - UnicodeCategory.LowercaseLetter, - // Lt letter - UnicodeCategory.TitlecaseLetter, - // Lm letter - UnicodeCategory.ModifierLetter, - // Lo letter - UnicodeCategory.OtherLetter, - // Nl letter - UnicodeCategory.LetterNumber - }; - - _otherCharsCategories = new HashSet(_startCharCategories) - { - // Mn - UnicodeCategory.NonSpacingMark, - // Mc - UnicodeCategory.SpacingCombiningMark, - // Nd - UnicodeCategory.DecimalDigitNumber, - // Pc - UnicodeCategory.ConnectorPunctuation, - // Cf - UnicodeCategory.Format - }; - } - - /// - /// Converts to valid C# identifier. - /// - public static string ToValidIdentifier(string? name) - { - if (name == null || name == string.Empty || name == "@") - { - return "_"; - } - - if (_reservedWords.Contains(name) || _contextualWords.Contains(name)) - { - return "@" + name; - } - - if (name.StartsWith("@")) - { - if (_reservedWords.Contains(name.Substring(1)) || _contextualWords.Contains(name.Substring(1))) - { - return name; - } - else - { - name = name.Substring(1); - } - } - - var sb = new StringBuilder(); - - foreach (var chr in name) - { - var cat = CharUnicodeInfo.GetUnicodeCategory(chr); - if (sb.Length == 0 && !_startCharCategories.Contains(cat) && chr != '_') - { - sb.Append('_'); - } - - if (sb.Length != 0 && !_otherCharsCategories.Contains(cat)) - { - sb.Append('_'); - } - else - { - sb.Append(chr); - } - } - - if (sb.Length >= 2 && sb[0] == '_' && sb[1] == '_' && (sb.Length == 2 || sb[2] != '_')) - { - sb.Insert(0, '_'); - } - - return sb.ToString(); - } - - public static string ToStringLiteral(string? value) - { - if (value == null) - return "null"; - - var sb = new StringBuilder("\""); - - foreach (var chr in value) - { - switch (chr) - { - case '\t': sb.Append("\\t"); break; - case '\n': sb.Append("\\n"); break; - case '\r': sb.Append("\\r"); break; - case '\\': sb.Append("\\\\"); break; - case '"': sb.Append("\\\""); break; - case '\0': sb.Append("\\0"); break; - case '\u0085': - case '\u2028': - case '\u2029': - sb.Append($"\\u{(ushort)chr:X4}"); break; - default: sb.Append(chr); break; - } - } - - sb.Append('"'); - - return sb.ToString(); - } - } -} diff --git a/Source/CX.cs b/Source/CX.cs index 8c09dea..76f5a5b 100644 --- a/Source/CX.cs +++ b/Source/CX.cs @@ -1,22 +1,22 @@ -namespace LinqToDB.LINQPad +namespace LinqToDB.LINQPad; + +// context properties names +static class CX { - // context properties names - static class CX - { - public const string ProviderName = "providerName"; - public const string ProviderPath = "providerPath"; - public const string ConnectionString = "connectionString"; - public const string ExcludeRoutines = "excludeRoutines"; - public const string ExcludeFKs = "excludeFKs"; - public const string IncludeSchemas = "includeSchemas"; - public const string ExcludeSchemas = "excludeSchemas"; - public const string IncludeCatalogs = "includeCatalogs"; - public const string ExcludeCatalogs = "excludeCatalogs"; - public const string OptimizeJoins = "optimizeJoins"; - public const string UseProviderSpecificTypes = "useProviderSpecificTypes"; - public const string UseCustomFormatter = "useCustomFormatter"; - public const string CommandTimeout = "commandTimeout"; - public const string NormalizeNames = "normalizeNames"; - public const string CustomConfiguration = "customConfiguration"; - } + public const string ProviderName = "providerName"; + public const string ProviderPath = "providerPath"; + public const string ConnectionString = "connectionString"; + public const string ExcludeRoutines = "excludeRoutines"; + public const string ExcludeFKs = "excludeFKs"; + public const string IncludeSchemas = "includeSchemas"; + public const string ExcludeSchemas = "excludeSchemas"; + public const string IncludeCatalogs = "includeCatalogs"; + public const string ExcludeCatalogs = "excludeCatalogs"; + public const string OptimizeJoins = "optimizeJoins"; + public const string UseProviderSpecificTypes = "useProviderSpecificTypes"; + public const string UseCustomFormatter = "useCustomFormatter"; + public const string CommandTimeout = "commandTimeout"; + // TODO: not used, remove + public const string NormalizeNames = "normalizeNames"; + public const string CustomConfiguration = "customConfiguration"; } diff --git a/Source/Compat/IsExternalInit.cs b/Source/Compat/IsExternalInit.cs new file mode 100644 index 0000000..f29b843 --- /dev/null +++ b/Source/Compat/IsExternalInit.cs @@ -0,0 +1,19 @@ +#if !NET5_0_OR_GREATER +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Rationale: required for init-only properties and record types +// Source: https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/System/Runtime/CompilerServices/IsExternalInit.cs +using System.ComponentModel; + +namespace System.Runtime.CompilerServices; + +/// +/// Reserved to be used by the compiler for tracking metadata. +/// This class should not be used by developers in source code. +/// +[EditorBrowsable(EditorBrowsableState.Never)] +internal static class IsExternalInit +{ +} +#endif diff --git a/Source/Compat/NullableAttributes.cs b/Source/Compat/NullableAttributes.cs new file mode 100644 index 0000000..07703a1 --- /dev/null +++ b/Source/Compat/NullableAttributes.cs @@ -0,0 +1,149 @@ +// 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. + +// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs +// https://raw.githubusercontent.com/dotnet/runtime/master/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs +namespace System.Diagnostics.CodeAnalysis; + +#if !NETCORE +/// Specifies that null is allowed as an input even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +sealed class AllowNullAttribute : Attribute +{ } + +/// Specifies that null is disallowed as an input even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +sealed class DisallowNullAttribute : Attribute +{ } + +/// Specifies that an output may be null even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +sealed class MaybeNullAttribute : Attribute +{ } + +/// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +sealed class NotNullAttribute : Attribute +{ } + +/// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +sealed class MaybeNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } +} + +/// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } +} + +/// Specifies that the output will be non-null if the named parameter is non-null. +[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] +sealed class NotNullIfNotNullAttribute : Attribute +{ + /// Initializes the attribute with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; + + /// Gets the associated parameter name. + public string ParameterName { get; } +} + +/// Applied to a method that will never return under any circumstance. +[AttributeUsage(AttributeTargets.Method, Inherited = false)] +sealed class DoesNotReturnAttribute : Attribute +{ } + +/// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +sealed class DoesNotReturnIfAttribute : Attribute +{ + /// Initializes the attribute with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + /// Gets the condition parameter value. + public bool ParameterValue { get; } +} + +/// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. +[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] +sealed class MemberNotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition and a field or property member. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullWhenAttribute(bool returnValue, string member) + { + ReturnValue = returnValue; + Members = new[] { member }; + } + + /// Initializes the attribute with the specified return value condition and list of field and property members. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullWhenAttribute(bool returnValue, params string[] members) + { + ReturnValue = returnValue; + Members = members; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } + + /// Gets field or property member names. + public string[] Members { get; } +} +#endif + +/// Specifies that the method or property will ensure that the listed field and property members have not-null values. +[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] +sealed class MemberNotNullAttribute : Attribute +{ + /// Initializes the attribute with a field or property member. + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullAttribute(string member) => Members = new[] { member }; + + /// Initializes the attribute with the list of field and property members. + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullAttribute(params string[] members) + => Members = members; + + /// Gets field or property member names. + public string[] Members { get; } +} diff --git a/Source/Compat/SkipLocalsInitAttribute.cs b/Source/Compat/SkipLocalsInitAttribute.cs new file mode 100644 index 0000000..f5092cf --- /dev/null +++ b/Source/Compat/SkipLocalsInitAttribute.cs @@ -0,0 +1,34 @@ +#if !NET5_0_OR_GREATER +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices; +/// +/// Used to indicate to the compiler that the .locals init +/// flag should not be set in method headers. +/// +/// +/// This attribute is unsafe because it may reveal uninitialized memory to +/// the application in certain instances (e.g., reading from uninitialized +/// stackalloc'd memory). If applied to a method directly, the attribute +/// applies to that method and all nested functions (lambdas, local +/// functions) below it. If applied to a type or module, it applies to all +/// methods nested inside. This attribute is intentionally not permitted on +/// assemblies. Use at the module level instead to apply to multiple type +/// declarations. +/// +[AttributeUsage(AttributeTargets.Module + | AttributeTargets.Class + | AttributeTargets.Struct + | AttributeTargets.Interface + | AttributeTargets.Constructor + | AttributeTargets.Method + | AttributeTargets.Property + | AttributeTargets.Event, Inherited = false)] +internal sealed class SkipLocalsInitAttribute : Attribute +{ + public SkipLocalsInitAttribute() + { + } +} +#endif diff --git a/Source/ConnectionDialog.xaml b/Source/Configuration/ConnectionDialog.xaml similarity index 96% rename from Source/ConnectionDialog.xaml rename to Source/Configuration/ConnectionDialog.xaml index ce2850b..5bb8e5a 100644 --- a/Source/ConnectionDialog.xaml +++ b/Source/Configuration/ConnectionDialog.xaml @@ -1,206 +1,206 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -