From 52d4784fcd28397524eeb1f7d863493778e2e349 Mon Sep 17 00:00:00 2001 From: nil4 Date: Tue, 7 Jan 2020 20:04:26 +0100 Subject: [PATCH] Enable C# 8, NRT annotations and RollForward=Major (#38) Enable C# 8 and add nullable reference types (NRT) annotations. Enable [`RollForward=Major`](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#major-version-roll-forward) to allow running the tool on .NET Core 3.x and later (fixes #42). Build with .NET Core 3.1 SDK and SourceLink enabled. Retarget tests to .NET Core 3.1 and .NET 4.8. Upgrade NuGet packages used for tests. --- README.md | 4 +- appveyor.yml | 12 +-- azure-pipelines.yml | 9 +- dotnet-xdt.tests/TestTransformationLogger.cs | 10 +-- dotnet-xdt.tests/dotnet-xdt.tests.csproj | 8 +- dotnet-xdt/IXmlOriginalDocumentService.cs | 2 +- dotnet-xdt/IXmlTransformationLogger.cs | 10 +-- dotnet-xdt/NamedTypeFactory.cs | 8 +- dotnet-xdt/Program.cs | 18 ++-- dotnet-xdt/XmlArgumentUtility.cs | 2 +- dotnet-xdt/XmlAttributePreservationDict.cs | 16 ++-- .../XmlAttributePreservationProvider.cs | 2 +- dotnet-xdt/XmlAttributePreservingWriter.cs | 18 ++-- dotnet-xdt/XmlAttributeTransform.cs | 8 +- dotnet-xdt/XmlElementContext.cs | 83 ++++++++++--------- dotnet-xdt/XmlFileInfoDocument.cs | 49 +++++------ dotnet-xdt/XmlFormatter.cs | 56 ++++++------- dotnet-xdt/XmlLocator.cs | 38 ++++----- dotnet-xdt/XmlLocators.cs | 12 +-- dotnet-xdt/XmlNodeException.cs | 6 +- dotnet-xdt/XmlTransform.cs | 48 +++++------ dotnet-xdt/XmlTransformableDocument.cs | 4 +- dotnet-xdt/XmlTransformation.cs | 50 +++++------ dotnet-xdt/XmlTransformationLogger.cs | 14 ++-- dotnet-xdt/XmlTransforms.cs | 72 ++++++++-------- dotnet-xdt/dotnet-xdt.csproj | 11 ++- global.json | 2 +- 27 files changed, 290 insertions(+), 282 deletions(-) diff --git a/README.md b/README.md index 4c11696..ae77f93 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ is that you can use the same command, for both installation and usage, across al Install `dotnet-xdt` as a global tool (only once): ```cmd -dotnet tool install --global dotnet-xdt --version 2.1.1 +dotnet tool install --global dotnet-xdt --version 2.2.0 ``` And then you can apply XDT transforms, from the command-line, anywhere on your PC, e.g.: @@ -58,7 +58,7 @@ Download the latest build of `dotnet-xdt.exe` from the [releases page](https://g For complete flexibility, reference the cross-platform `DotNet.Xdt` NuGet package in your application: ```cmd -dotnet add package DotNet.Xdt --version 2.1.1 +dotnet add package DotNet.Xdt --version 2.2.0 ``` You can apply XDT transforms to any XML file, or other XML sources that can be read from diff --git a/appveyor.yml b/appveyor.yml index eb45563..3a910a2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ # https://www.appveyor.com/docs/appveyor-yml/ -image: Visual Studio 2017 +image: Visual Studio 2019 Preview version: 2.1.{build} @@ -11,7 +11,7 @@ clone_depth: 1 environment: DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 - DOTNET_SDK_URL: 'https://dotnetcli.azureedge.net/dotnet/Sdk/2.2.204/dotnet-sdk-2.2.204-win-x64.zip' + DOTNET_SDK_URL: 'https://dotnetcli.azureedge.net/dotnet/Sdk/3.1.100/dotnet-sdk-3.1.100-win-x64.zip' cache: - '%LocalAppData%\NuGet\v3-cache' # NuGet v3 @@ -40,9 +40,9 @@ artifacts: - path: dotnet-xdt/bin/$(configuration)/*.nupkg - path: dotnet-xdt/bin/$(configuration)/net461/dotnet-xdt.exe name: dotnet-xdt.exe -- path: dotnet-xdt.tests/bin/$(configuration)/net461/test-results.xml - name: test-results/net461.xml -- path: dotnet-xdt.tests/bin/$(configuration)/netcoreapp2.1/test-results.xml - name: test-results/netcoreapp21.xml +- path: dotnet-xdt.tests/bin/$(configuration)/net48/test-results.xml + name: test-results/net48.xml +- path: dotnet-xdt.tests/bin/$(configuration)/netcoreapp3.1/test-results.xml + name: test-results/netcoreapp31.xml deploy: off \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c803d9b..4ea370b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,9 +4,14 @@ pool: steps: - task: UseDotNet@2 - displayName: 'Install SDK 2.2.204' + displayName: 'Install SDK 2.1.607' inputs: - version: 2.2.204 + version: 2.1.607 + +- task: UseDotNet@2 + displayName: 'Install SDK 3.1.100' + inputs: + version: 3.1.100 - task: BatchScript@1 displayName: 'Run build.cmd' diff --git a/dotnet-xdt.tests/TestTransformationLogger.cs b/dotnet-xdt.tests/TestTransformationLogger.cs index 7269015..b786a1a 100644 --- a/dotnet-xdt.tests/TestTransformationLogger.cs +++ b/dotnet-xdt.tests/TestTransformationLogger.cs @@ -23,30 +23,30 @@ public void LogMessage(MessageType type, string message, params object[] message public void LogWarning(string message, params object[] messageArgs) => LogWarning("", message, messageArgs); - public void LogWarning(string file, string message, params object[] messageArgs) + public void LogWarning(string? file, string message, params object[] messageArgs) => LogWarning(file, 0, 0, message, messageArgs); // we will format like: transform.xml (30, 10) warning: Argument 'snap' did not match any attributes const string WarningFormat = "{0} ({1}, {2}) warning: {3}"; - public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) + public void LogWarning(string? file, int lineNumber, int linePosition, string message, params object[] messageArgs) => _log.AppendLine(string.Format(WarningFormat, Path.GetFileName(file), lineNumber, linePosition, string.Format(message,messageArgs))); public void LogError(string message, params object[] messageArgs) => LogError("", message, messageArgs); - public void LogError(string file, string message, params object[] messageArgs) + public void LogError(string? file, string message, params object[] messageArgs) => LogError(file, 0, 0, message, messageArgs); //transform.xml(33, 10) error: Could not resolve 'ThrowException' as a type of Transform const string ErrorFormat = "{0} ({1}, {2}) error: {3}"; - public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) + public void LogError(string? file, int lineNumber, int linePosition, string message, params object[] messageArgs) => _log.AppendLine(string.Format(ErrorFormat, Path.GetFileName(file), lineNumber, linePosition, string.Format(message,messageArgs))); public void LogErrorFromException(Exception ex) {} public void LogErrorFromException(Exception ex, string file) {} - public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition) + public void LogErrorFromException(Exception ex, string? file, int lineNumber, int linePosition) { string message = ex.Message; LogError(file, lineNumber, linePosition, message); diff --git a/dotnet-xdt.tests/dotnet-xdt.tests.csproj b/dotnet-xdt.tests/dotnet-xdt.tests.csproj index 54c86ef..ed8a9fa 100644 --- a/dotnet-xdt.tests/dotnet-xdt.tests.csproj +++ b/dotnet-xdt.tests/dotnet-xdt.tests.csproj @@ -1,9 +1,11 @@  - netcoreapp2.1;net461 + netcoreapp3.1;net48 false false - latest + preview + enable + $(Nullable) strict true @@ -16,7 +18,7 @@ - + diff --git a/dotnet-xdt/IXmlOriginalDocumentService.cs b/dotnet-xdt/IXmlOriginalDocumentService.cs index 92b69a4..9181818 100644 --- a/dotnet-xdt/IXmlOriginalDocumentService.cs +++ b/dotnet-xdt/IXmlOriginalDocumentService.cs @@ -4,6 +4,6 @@ namespace DotNet.Xdt { interface IXmlOriginalDocumentService { - XmlNodeList SelectNodes(string path, XmlNamespaceManager nsmgr); + XmlNodeList? SelectNodes(string path, XmlNamespaceManager nsmgr); } } diff --git a/dotnet-xdt/IXmlTransformationLogger.cs b/dotnet-xdt/IXmlTransformationLogger.cs index 5bc0ea6..b8cdc4a 100644 --- a/dotnet-xdt/IXmlTransformationLogger.cs +++ b/dotnet-xdt/IXmlTransformationLogger.cs @@ -13,14 +13,14 @@ public interface IXmlTransformationLogger void LogMessage(string message, params object[] messageArgs); void LogMessage(MessageType type, string message, params object[] messageArgs); void LogWarning(string message, params object[] messageArgs); - void LogWarning(string file, string message, params object[] messageArgs); - void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs); + void LogWarning(string? file, string message, params object[] messageArgs); + void LogWarning(string? file, int lineNumber, int linePosition, string message, params object[] messageArgs); void LogError(string message, params object[] messageArgs); - void LogError(string file, string message, params object[] messageArgs); - void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs); + void LogError(string? file, string message, params object[] messageArgs); + void LogError(string? file, int lineNumber, int linePosition, string message, params object[] messageArgs); void LogErrorFromException(Exception ex); void LogErrorFromException(Exception ex, string file); - void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition); + void LogErrorFromException(Exception ex, string? file, int lineNumber, int linePosition); void StartSection(string message, params object[] messageArgs); void StartSection(MessageType type, string message, params object[] messageArgs); void EndSection(string message, params object[] messageArgs); diff --git a/dotnet-xdt/NamedTypeFactory.cs b/dotnet-xdt/NamedTypeFactory.cs index b6ee793..b309c81 100644 --- a/dotnet-xdt/NamedTypeFactory.cs +++ b/dotnet-xdt/NamedTypeFactory.cs @@ -37,11 +37,11 @@ internal void AddPathRegistration(string path, string nameSpace) _registrations.Add(new PathRegistration(path, nameSpace)); } - internal TObjectType Construct(string typeName) where TObjectType : class + internal TObjectType? Construct(string typeName) where TObjectType : class { if (string.IsNullOrEmpty(typeName)) return null; - Type type = GetType(typeName); + Type? type = GetType(typeName); if (type == null) throw new XmlTransformationException(string.Format(System.Globalization.CultureInfo.CurrentCulture, SR.XMLTRANSFORMATION_UnknownTypeName, typeName, typeof(TObjectType).Name)); @@ -56,9 +56,9 @@ internal TObjectType Construct(string typeName) where TObjectType : return constructor.Invoke(Array.Empty()) as TObjectType; } - Type GetType(string typeName) + Type? GetType(string typeName) { - Type foundType = null; + Type? foundType = null; foreach (Registration registration in _registrations) { if (!registration.IsValid) continue; diff --git a/dotnet-xdt/Program.cs b/dotnet-xdt/Program.cs index 07df32d..ab6ab77 100644 --- a/dotnet-xdt/Program.cs +++ b/dotnet-xdt/Program.cs @@ -18,7 +18,7 @@ static class Program static int Main(string[] args) { - string sourceFilePath = null, outputFilePath = null, transformFilePath = null; + string? sourceFilePath = null, outputFilePath = null, transformFilePath = null; bool verbose = false, printUsage = false; if (!ParseArguments(args, ref sourceFilePath, ref outputFilePath, ref transformFilePath, ref verbose, ref printUsage)) @@ -105,8 +105,8 @@ static void PrintUsage(TextWriter writer) writer.WriteLine($"Example: {ToolName} --source original.xml --transform delta.xml --output final.xml --verbose"); } - static bool ParseArguments(IReadOnlyList args, ref string sourceFilePath, ref string outputFilePath, - ref string transformFilePath, ref bool verbose, ref bool showHelp) + static bool ParseArguments(IReadOnlyList args, ref string? sourceFilePath, ref string? outputFilePath, + ref string? transformFilePath, ref bool verbose, ref bool showHelp) { for (var i = 0; i < args.Count; i++) { @@ -150,7 +150,7 @@ static bool ParseArguments(IReadOnlyList args, ref string sourceFilePath && !string.IsNullOrWhiteSpace(outputFilePath) && !string.IsNullOrWhiteSpace(transformFilePath); - bool TryRead(ref int index, ref string value) + bool TryRead(ref int index, ref string? value) { ++index; if (index >= args.Count || value != null) return false; @@ -180,19 +180,19 @@ public void LogMessage(MessageType type, string message, params object[] message public void LogWarning(string message, params object[] messageArgs) => Console.WriteLine($"{Prefix}WARN: {message}", messageArgs); - public void LogWarning(string file, string message, params object[] messageArgs) + public void LogWarning(string? file, string message, params object[] messageArgs) => Console.WriteLine($"{Prefix}WARN '{file}': {message}", messageArgs); - public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) + public void LogWarning(string? file, int lineNumber, int linePosition, string message, params object[] messageArgs) => Console.WriteLine($"{Prefix}WARN '{file}':{lineNumber}:{linePosition}: {message}", messageArgs); public void LogError(string message, params object[] messageArgs) => Console.Error.WriteLine($"{Prefix}ERROR: {message}", messageArgs); - public void LogError(string file, string message, params object[] messageArgs) + public void LogError(string? file, string message, params object[] messageArgs) => Console.Error.WriteLine($"{Prefix}ERROR '{file}': {message}", messageArgs); - public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) + public void LogError(string? file, int lineNumber, int linePosition, string message, params object[] messageArgs) => Console.Error.WriteLine($"{Prefix}ERROR '{file}':{lineNumber}:{linePosition}: {message}", messageArgs); public void LogErrorFromException(Exception ex) @@ -201,7 +201,7 @@ public void LogErrorFromException(Exception ex) public void LogErrorFromException(Exception ex, string file) => Console.Error.WriteLine($"{Prefix}ERROR '{file}': {ex}"); - public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition) + public void LogErrorFromException(Exception ex, string? file, int lineNumber, int linePosition) => Console.Error.WriteLine($"{Prefix}ERROR '{file}':{lineNumber}:{linePosition}: {ex}"); public void StartSection(string message, params object[] messageArgs) diff --git a/dotnet-xdt/XmlArgumentUtility.cs b/dotnet-xdt/XmlArgumentUtility.cs index dfef9d4..0209ee1 100644 --- a/dotnet-xdt/XmlArgumentUtility.cs +++ b/dotnet-xdt/XmlArgumentUtility.cs @@ -27,7 +27,7 @@ internal static IList SplitArguments(string argumentString) static IList RecombineArguments(IList arguments, char separator) { var combinedArguments = new List(); - string combinedArgument = null; + string? combinedArgument = null; var parenCount = 0; foreach (string argument in arguments) diff --git a/dotnet-xdt/XmlAttributePreservationDict.cs b/dotnet-xdt/XmlAttributePreservationDict.cs index 51f7546..7f20ac4 100644 --- a/dotnet-xdt/XmlAttributePreservationDict.cs +++ b/dotnet-xdt/XmlAttributePreservationDict.cs @@ -11,7 +11,7 @@ class XmlAttributePreservationDict readonly List _orderedAttributes = new List(); readonly Dictionary _leadingSpaces = new Dictionary(); - string _attributeNewLineString; + string? _attributeNewLineString; bool? _oneAttributePerLine; bool OneAttributePerLine => _oneAttributePerLine @@ -66,7 +66,7 @@ static int EnumerateAttributes(string elementStartTag, Action internal void WritePreservedAttributes(XmlAttributePreservingWriter writer, XmlAttributeCollection attributes) { - string oldNewLineString = null; + string? oldNewLineString = null; if (_attributeNewLineString != null) oldNewLineString = writer.SetAttributeNewLineString(_attributeNewLineString); @@ -119,7 +119,7 @@ internal void UpdatePreservationInfo(XmlAttributeCollection updatedAttributes, X } var firstAttribute = true; - string keepLeadingWhitespace = null; + string? keepLeadingWhitespace = null; foreach (string key in _orderedAttributes) { bool exists = attributeExists[key]; @@ -173,7 +173,7 @@ internal void UpdatePreservationInfo(XmlAttributeCollection updatedAttributes, X _leadingSpaces[key] = " "; else if (OneAttributePerLine) // Add the indent space between each attribute - _leadingSpaces[key] = GetAttributeNewLineString(formatter); + _leadingSpaces[key] = GetAttributeNewLineString(formatter)!; else // Don't add any hard-coded spaces. All new attributes // should be at the end, so they'll be formatted while @@ -220,13 +220,13 @@ bool ComputeOneAttributePerLine() static bool ContainsNewLine(string space) => space.IndexOf("\n", StringComparison.Ordinal) >= 0; - public string GetAttributeNewLineString(XmlFormatter formatter) - => _attributeNewLineString ?? (_attributeNewLineString = ComputeAttributeNewLineString(formatter)); + public string? GetAttributeNewLineString(XmlFormatter? formatter) + => _attributeNewLineString ??= ComputeAttributeNewLineString(formatter); - string ComputeAttributeNewLineString(XmlFormatter formatter) + string? ComputeAttributeNewLineString(XmlFormatter? formatter) => LookAheadForNewLineString() ?? formatter?.CurrentAttributeIndent; - string LookAheadForNewLineString() + string? LookAheadForNewLineString() { foreach (string space in _leadingSpaces.Values) if (ContainsNewLine(space)) return space; diff --git a/dotnet-xdt/XmlAttributePreservationProvider.cs b/dotnet-xdt/XmlAttributePreservationProvider.cs index 79bb03a..2180523 100644 --- a/dotnet-xdt/XmlAttributePreservationProvider.cs +++ b/dotnet-xdt/XmlAttributePreservationProvider.cs @@ -16,7 +16,7 @@ public XmlAttributePreservationProvider(string fileName) _reader = new PositionTrackingTextReader(_streamReader); } - public XmlAttributePreservationDict GetDictAtPosition(int lineNumber, int linePosition) + public XmlAttributePreservationDict? GetDictAtPosition(int lineNumber, int linePosition) { if (_reader.ReadToPosition(lineNumber, linePosition)) { diff --git a/dotnet-xdt/XmlAttributePreservingWriter.cs b/dotnet-xdt/XmlAttributePreservingWriter.cs index 2ba8843..e534a29 100644 --- a/dotnet-xdt/XmlAttributePreservingWriter.cs +++ b/dotnet-xdt/XmlAttributePreservingWriter.cs @@ -12,11 +12,11 @@ class XmlAttributePreservingWriter : XmlWriter readonly XmlTextWriter _xmlWriter; readonly AttributeTextWriter _textWriter; - public XmlAttributePreservingWriter(string fileName, Encoding encoding) + public XmlAttributePreservingWriter(string fileName, Encoding? encoding) : this(encoding == null ? new StreamWriter(fileName) : new StreamWriter(fileName, false, encoding)) { } - public XmlAttributePreservingWriter(Stream w, Encoding encoding) + public XmlAttributePreservingWriter(Stream w, Encoding? encoding) : this(encoding == null ? new StreamWriter(w) : new StreamWriter(w, encoding)) { } @@ -86,7 +86,7 @@ enum State } State _state = State.Writing; - StringBuilder _writeBuffer; + StringBuilder? _writeBuffer; readonly TextWriter _baseWriter; @@ -97,7 +97,7 @@ public AttributeTextWriter(TextWriter baseWriter) : base(CultureInfo.InvariantCulture) => _baseWriter = baseWriter; - public string AttributeLeadingWhitespace { get; set; } + public string? AttributeLeadingWhitespace { get; set; } public string AttributeNewLineString { get; set; } = "\r\n"; @@ -136,7 +136,7 @@ public override void Write(char value) break; case State.ReadingAttribute: case State.Buffering: - _writeBuffer.Append(value); + _writeBuffer?.Append(value); break; } } @@ -156,12 +156,12 @@ void UpdateState(char value) case '>': if (_state == State.Buffering) { - string currentBuffer = _writeBuffer.ToString(); + string currentBuffer = _writeBuffer?.ToString() ?? ""; if (currentBuffer.EndsWith(" /", StringComparison.Ordinal)) { // We've identified the string " />" at the // end of the buffer, so remove the space - _writeBuffer.Remove(currentBuffer.LastIndexOf(' '), 1); + _writeBuffer?.Remove(currentBuffer.LastIndexOf(' '), 1); } ChangeState(State.Writing); } @@ -234,12 +234,12 @@ void WriteQueuedAttribute() // Write leading whitespace if (AttributeLeadingWhitespace != null) { - _writeBuffer.Insert(0, AttributeLeadingWhitespace); + _writeBuffer?.Insert(0, AttributeLeadingWhitespace); AttributeLeadingWhitespace = null; } else { - int lineLength = _linePosition + _writeBuffer.Length + 1; + int lineLength = _linePosition + _writeBuffer!.Length + 1; if (lineLength > MaxLineLength) _writeBuffer.Insert(0, AttributeNewLineString); else diff --git a/dotnet-xdt/XmlAttributeTransform.cs b/dotnet-xdt/XmlAttributeTransform.cs index 47814b3..0790b66 100644 --- a/dotnet-xdt/XmlAttributeTransform.cs +++ b/dotnet-xdt/XmlAttributeTransform.cs @@ -6,10 +6,10 @@ namespace DotNet.Xdt { abstract class AttributeTransform : Transform { - XmlNode _transformAttributeSource; - XmlNodeList _transformAttributes; - XmlNode _targetAttributeSource; - XmlNodeList _targetAttributes; + XmlNode? _transformAttributeSource; + XmlNodeList? _transformAttributes; + XmlNode? _targetAttributeSource; + XmlNodeList? _targetAttributes; protected AttributeTransform() : base(TransformFlags.ApplyTransformToAllTargetNodes) diff --git a/dotnet-xdt/XmlElementContext.cs b/dotnet-xdt/XmlElementContext.cs index 999891d..4518e7d 100644 --- a/dotnet-xdt/XmlElementContext.cs +++ b/dotnet-xdt/XmlElementContext.cs @@ -9,22 +9,22 @@ namespace DotNet.Xdt { class XmlElementContext : XmlNodeContext { - readonly XmlElementContext _parentContext; - string _xpath; - string _parentXPath; + readonly XmlElementContext? _parentContext; + string? _xpath; + string? _parentXPath; readonly IServiceProvider _serviceProvider; - XmlNode _transformNodes; - XmlNodeList _targetNodes; - XmlNodeList _targetParents; + XmlNode? _transformNodes; + XmlNodeList? _targetNodes; + XmlNodeList? _targetParents; - XmlAttribute _transformAttribute; - XmlAttribute _locatorAttribute; + XmlAttribute? _transformAttribute; + XmlAttribute? _locatorAttribute; - XmlNamespaceManager _namespaceManager; + XmlNamespaceManager? _namespaceManager; - public XmlElementContext(XmlElementContext parent, XmlElement element, XmlDocument xmlTargetDoc, IServiceProvider serviceProvider) + public XmlElementContext(XmlElementContext? parent, XmlElement element, XmlDocument xmlTargetDoc, IServiceProvider serviceProvider) : base(element) { _parentContext = parent; @@ -32,7 +32,7 @@ public XmlElementContext(XmlElementContext parent, XmlElement element, XmlDocume _serviceProvider = serviceProvider; } - public T GetService() where T : class + public T? GetService() where T : class { if (_serviceProvider != null) { @@ -44,13 +44,13 @@ public T GetService() where T : class return null; } - public XmlElement Element => Node as XmlElement; + public XmlElement? Element => Node as XmlElement; - public string XPath => _xpath ?? (_xpath = ConstructXPath()); + public string XPath => _xpath ??= ConstructXPath(); - public string ParentXPath => _parentXPath ?? (_parentXPath = ConstructParentXPath()); + public string ParentXPath => _parentXPath ??= ConstructParentXPath(); - public Transform ConstructTransform(out string argumentString) + public Transform? ConstructTransform(out string? argumentString) { try { @@ -66,9 +66,9 @@ public Transform ConstructTransform(out string argumentString) public int TransformLinePosition => (_transformAttribute as IXmlLineInfo)?.LinePosition ?? LinePosition; - public XmlAttribute TransformAttribute => _transformAttribute; + public XmlAttribute? TransformAttribute => _transformAttribute; - public XmlAttribute LocatorAttribute => _locatorAttribute; + public XmlAttribute? LocatorAttribute => _locatorAttribute; string ConstructXPath() { @@ -76,7 +76,7 @@ string ConstructXPath() { string parentPath = _parentContext == null ? string.Empty : _parentContext.XPath; - Locator locator = CreateLocator(out string argumentString); + Locator locator = CreateLocator(out string? argumentString); return locator.ConstructPath(parentPath, this, argumentString); } @@ -92,7 +92,7 @@ string ConstructParentXPath() { string parentPath = _parentContext == null ? string.Empty : _parentContext.XPath; - Locator locator = CreateLocator(out string argumentString); + Locator locator = CreateLocator(out string? argumentString); return locator.ConstructParentPath(parentPath, this, argumentString); } @@ -102,7 +102,7 @@ string ConstructParentXPath() } } - Locator CreateLocator(out string argumentString) + Locator CreateLocator(out string? argumentString) { var locator = CreateObjectFromAttribute(out argumentString, out _locatorAttribute); if (locator == null) @@ -114,9 +114,9 @@ Locator CreateLocator(out string argumentString) return locator; } - internal XmlNode TransformNode => _transformNodes ?? (_transformNodes = CreateCloneInTargetDocument(Element)); + internal XmlNode TransformNode => _transformNodes ??= CreateCloneInTargetDocument(Element); - internal XmlNodeList TargetNodes => _targetNodes ?? (_targetNodes = GetTargetNodes(XPath)); + internal XmlNodeList TargetNodes => _targetNodes ??= GetTargetNodes(XPath); internal XmlNodeList TargetParents { @@ -124,13 +124,13 @@ internal XmlNodeList TargetParents { if (_targetParents == null && _parentContext != null) _targetParents = GetTargetNodes(ParentXPath); - return _targetParents; + return _targetParents!; } } XmlDocument TargetDocument { get; } - XmlNode CreateCloneInTargetDocument(XmlNode sourceNode) + XmlNode CreateCloneInTargetDocument(XmlNode? sourceNode) { var infoDocument = TargetDocument as XmlFileInfoDocument; XmlNode clonedNode; @@ -139,7 +139,7 @@ XmlNode CreateCloneInTargetDocument(XmlNode sourceNode) clonedNode = infoDocument.CloneNodeFromOtherDocument(sourceNode); else { - var reader = new XmlTextReader(new StringReader(sourceNode.OuterXml)); + var reader = new XmlTextReader(new StringReader(sourceNode?.OuterXml)); clonedNode = TargetDocument.ReadNode(reader); } @@ -158,7 +158,7 @@ static void ScrubTransformAttributesAndNamespaces(XmlNode node) { if (attribute.NamespaceURI == XmlTransformation.TransformNamespace) attributesToRemove.Add(attribute); - else if (attribute.Prefix.Equals("xmlns") || attribute.Name.Equals("xmlns")) + else if (attribute.Prefix!.Equals("xmlns") || attribute.Name.Equals("xmlns")) attributesToRemove.Add(attribute); else attribute.Prefix = null; @@ -175,15 +175,15 @@ static void ScrubTransformAttributesAndNamespaces(XmlNode node) XmlNodeList GetTargetNodes(string xpath) => TargetDocument.SelectNodes(xpath, GetNamespaceManager()); - Exception WrapException(Exception ex) => XmlNodeException.Wrap(ex, Element); + Exception WrapException(Exception ex) => XmlNodeException.Wrap(ex, Element!); - static Exception WrapException(Exception ex, XmlNode node) => XmlNodeException.Wrap(ex, node); + static Exception WrapException(Exception ex, XmlNode? node) => XmlNodeException.Wrap(ex, node!); XmlNamespaceManager GetNamespaceManager() { if (_namespaceManager == null) { - XmlNodeList localNamespaces = Element.SelectNodes("namespace::*"); + XmlNodeList localNamespaces = Element!.SelectNodes("namespace::*"); if (localNamespaces.Count > 0) { @@ -205,13 +205,13 @@ XmlNamespaceManager GetNamespaceManager() return _namespaceManager; } - XmlNameTable GetParentNameTable() - => _parentContext == null ? Element.OwnerDocument.NameTable : _parentContext.GetNamespaceManager().NameTable; + XmlNameTable? GetParentNameTable() + => _parentContext == null ? Element?.OwnerDocument?.NameTable : _parentContext.GetNamespaceManager().NameTable; - static Regex _nameAndArgumentsRegex; - static Regex NameAndArgumentsRegex => _nameAndArgumentsRegex ?? (_nameAndArgumentsRegex = new Regex(@"\A\s*(?\w+)(\s*\((?.*)\))?\s*\Z", RegexOptions.Compiled | RegexOptions.Singleline)); + static Regex? _nameAndArgumentsRegex; + static Regex NameAndArgumentsRegex => _nameAndArgumentsRegex ??= new Regex(@"\A\s*(?\w+)(\s*\((?.*)\))?\s*\Z", RegexOptions.Compiled | RegexOptions.Singleline); - static string ParseNameAndArguments(string name, out string arguments) + static string ParseNameAndArguments(string name, out string? arguments) { arguments = null; @@ -230,16 +230,17 @@ static string ParseNameAndArguments(string name, out string arguments) throw new XmlTransformationException(SR.XMLTRANSFORMATION_BadAttributeValue); } - TObjectType CreateObjectFromAttribute(out string argumentString, out XmlAttribute objectAttribute) where TObjectType : class + TObjectType? CreateObjectFromAttribute(out string? argumentString, out XmlAttribute? objectAttribute) + where TObjectType : class { - objectAttribute = Element.Attributes.GetNamedItem(typeof(TObjectType).Name, XmlTransformation.TransformNamespace) as XmlAttribute; + objectAttribute = Element?.Attributes.GetNamedItem(typeof(TObjectType).Name, XmlTransformation.TransformNamespace) as XmlAttribute; try { if (objectAttribute != null) { string typeName = ParseNameAndArguments(objectAttribute.Value, out argumentString); if (!string.IsNullOrEmpty(typeName)) - return GetService().Construct(typeName); + return GetService()!.Construct(typeName); } } catch (Exception ex) @@ -251,7 +252,7 @@ TObjectType CreateObjectFromAttribute(out string argumentString, ou return null; } - internal bool HasTargetNode(out XmlElementContext failedContext, out bool existedInOriginal) + internal bool HasTargetNode(out XmlElementContext? failedContext, out bool existedInOriginal) { failedContext = null; existedInOriginal = false; @@ -271,13 +272,13 @@ internal bool HasTargetNode(out XmlElementContext failedContext, out bool existe internal bool HasTargetParent(out XmlElementContext failedContext, out bool existedInOriginal) { - failedContext = null; + failedContext = null!; existedInOriginal = false; if (TargetParents.Count == 0) { failedContext = this; - while (!string.IsNullOrEmpty(failedContext._parentContext?.ParentXPath) && failedContext._parentContext.TargetParents.Count == 0) + while (!string.IsNullOrEmpty(failedContext._parentContext?.ParentXPath) && failedContext._parentContext?.TargetParents.Count == 0) failedContext = failedContext._parentContext; existedInOriginal = ExistedInOriginal(failedContext.XPath); @@ -290,7 +291,7 @@ internal bool HasTargetParent(out XmlElementContext failedContext, out bool exis bool ExistedInOriginal(string xpath) { var service = GetService(); - XmlNodeList nodeList = service?.SelectNodes(xpath, GetNamespaceManager()); + XmlNodeList? nodeList = service?.SelectNodes(xpath, GetNamespaceManager()); return nodeList != null && nodeList.Count > 0; } } diff --git a/dotnet-xdt/XmlFileInfoDocument.cs b/dotnet-xdt/XmlFileInfoDocument.cs index a9e3eac..37c9c77 100644 --- a/dotnet-xdt/XmlFileInfoDocument.cs +++ b/dotnet-xdt/XmlFileInfoDocument.cs @@ -8,8 +8,8 @@ namespace DotNet.Xdt { public class XmlFileInfoDocument : XmlDocument, IDisposable { - Encoding _textEncoding; - XmlTextReader _reader; + Encoding? _textEncoding; + XmlTextReader? _reader; int _lineNumberOffset; int _linePositionOffset; @@ -26,9 +26,7 @@ public override void Load(string filename) public override void Load(XmlReader reader) { - if (reader == null) throw new ArgumentNullException(nameof(reader)); - - _reader = reader as XmlTextReader; + _reader = reader as XmlTextReader ?? throw new ArgumentNullException(nameof(reader)); if (_reader != null) FileName = _reader.BaseURI; @@ -44,7 +42,7 @@ void LoadFromFileName(string filename) { FileName = filename; - StreamReader reader = null; + StreamReader? reader = null; try { if (PreserveWhitespace) @@ -82,9 +80,9 @@ void LoadFromTextReader(TextReader textReader) _textEncoding = _reader.Encoding; } - static Encoding GetEncodingFromStream(Stream stream) + static Encoding? GetEncodingFromStream(Stream stream) { - Encoding encoding = null; + Encoding? encoding = null; if (stream.CanSeek) { var buffer = new byte[3]; @@ -106,10 +104,10 @@ static Encoding GetEncodingFromStream(Stream stream) return encoding; } - internal XmlNode CloneNodeFromOtherDocument(XmlNode element) + internal XmlNode CloneNodeFromOtherDocument(XmlNode? element) { - XmlTextReader oldReader = _reader; - string oldFileName = FileName; + XmlTextReader? oldReader = _reader; + string? oldFileName = FileName; XmlNode clone; try @@ -129,7 +127,7 @@ internal XmlNode CloneNodeFromOtherDocument(XmlNode element) FileName = null; _reader = null; - clone = ReadNode(new XmlTextReader(new StringReader(element.OuterXml))); + clone = ReadNode(new XmlTextReader(new StringReader(element!.OuterXml))); } } finally @@ -146,7 +144,7 @@ internal XmlNode CloneNodeFromOtherDocument(XmlNode element) internal bool HasErrorInfo => _reader != null; - internal string FileName { get; private set; } + internal string? FileName { get; private set; } int CurrentLineNumber => _reader?.LineNumber + _lineNumberOffset ?? 0; @@ -154,9 +152,9 @@ internal XmlNode CloneNodeFromOtherDocument(XmlNode element) bool FirstLoad { get; set; } = true; - XmlAttributePreservationProvider PreservationProvider { get; set; } + XmlAttributePreservationProvider? PreservationProvider { get; set; } - Encoding TextEncoding + Encoding? TextEncoding { get { @@ -167,7 +165,7 @@ Encoding TextEncoding if (HasChildNodes) { var declaration = FirstChild as XmlDeclaration; - string value = declaration?.Encoding; + string? value = declaration?.Encoding; if (value?.Length > 0) return Encoding.GetEncoding(value); } @@ -180,7 +178,7 @@ public override void Save(string filename) if (string.IsNullOrWhiteSpace(filename)) throw new ArgumentException("File name cannot be empty", nameof(filename)); - XmlWriter xmlWriter = null; + XmlWriter? xmlWriter = null; try { if (PreserveWhitespace) @@ -210,7 +208,7 @@ public override void Save(Stream stream) { if (stream == null) throw new ArgumentNullException(nameof(stream)); - XmlWriter xmlWriter = null; + XmlWriter? xmlWriter = null; try { if (PreserveWhitespace) @@ -246,7 +244,7 @@ internal bool IsNewNode(XmlNode node) return FindContainingElement(node) is XmlFileInfoElement element && !element.IsOriginal; } - static XmlElement FindContainingElement(XmlNode node) + static XmlElement? FindContainingElement(XmlNode node) { while (node != null && !(node is XmlElement)) node = node.ParentNode; @@ -255,7 +253,7 @@ static XmlElement FindContainingElement(XmlNode node) class XmlFileInfoElement : XmlElement, IXmlLineInfo, IXmlFormattableAttributes { - readonly XmlAttributePreservationDict _preservationDict; + readonly XmlAttributePreservationDict? _preservationDict; internal XmlFileInfoElement(string prefix, string localName, string namespaceUri, XmlFileInfoDocument document) : base(prefix, localName, namespaceUri, document) @@ -280,8 +278,7 @@ public override void WriteTo(XmlWriter w) if (HasAttributes) { - var preservingWriter = w as XmlAttributePreservingWriter; - if (preservingWriter == null || _preservationDict == null) + if (!(w is XmlAttributePreservingWriter preservingWriter) || _preservationDict == null) WriteAttributesTo(w); else WritePreservedAttributesTo(preservingWriter); @@ -304,7 +301,7 @@ void WriteAttributesTo(XmlWriter w) } void WritePreservedAttributesTo(XmlAttributePreservingWriter preservingWriter) - => _preservationDict.WritePreservedAttributes(preservingWriter, Attributes); + => _preservationDict!.WritePreservedAttributes(preservingWriter, Attributes); public bool HasLineInfo() => true; @@ -315,10 +312,10 @@ void WritePreservedAttributesTo(XmlAttributePreservingWriter preservingWriter) public bool IsOriginal { get; } void IXmlFormattableAttributes.FormatAttributes(XmlFormatter formatter) - => _preservationDict.UpdatePreservationInfo(Attributes, formatter); + => _preservationDict!.UpdatePreservationInfo(Attributes, formatter); - string IXmlFormattableAttributes.AttributeIndent - => _preservationDict.GetAttributeNewLineString(null); + string? IXmlFormattableAttributes.AttributeIndent + => _preservationDict!.GetAttributeNewLineString(null); } class XmlFileInfoAttribute : XmlAttribute, IXmlLineInfo diff --git a/dotnet-xdt/XmlFormatter.cs b/dotnet-xdt/XmlFormatter.cs index 43f4848..17ef090 100644 --- a/dotnet-xdt/XmlFormatter.cs +++ b/dotnet-xdt/XmlFormatter.cs @@ -10,7 +10,7 @@ interface IXmlFormattableAttributes { void FormatAttributes(XmlFormatter formatter); - string AttributeIndent { get; } + string? AttributeIndent { get; } } class XmlFormatter @@ -19,10 +19,10 @@ class XmlFormatter readonly LinkedList _indents = new LinkedList(); readonly LinkedList _attributeIndents = new LinkedList(); - string _currentIndent = string.Empty; - string _currentAttributeIndent; - string _oneTab; - XmlNode _currentNode; + string? _currentIndent = string.Empty; + string? _currentAttributeIndent; + string? _oneTab; + XmlNode? _currentNode; public static void Format(XmlDocument document) @@ -37,7 +37,7 @@ public static void Format(XmlDocument document) XmlFormatter(XmlFileInfoDocument document) => _document = document; - XmlNode CurrentNode + XmlNode? CurrentNode { get => _currentNode; set @@ -47,7 +47,7 @@ XmlNode CurrentNode } } - XmlNode PreviousNode { get; set; } + XmlNode? PreviousNode { get; set; } string PreviousIndent { @@ -58,11 +58,11 @@ string PreviousIndent } } - string CurrentIndent => _currentIndent ?? (_currentIndent = ComputeCurrentIndent()); + string CurrentIndent => _currentIndent ??= ComputeCurrentIndent(); - public string CurrentAttributeIndent => _currentAttributeIndent ?? (_currentAttributeIndent = ComputeCurrentAttributeIndent()); + public string? CurrentAttributeIndent => _currentAttributeIndent ??= ComputeCurrentAttributeIndent(); - string OneTab => _oneTab ?? (_oneTab = ComputeOneTab()); + string OneTab => _oneTab ??= ComputeOneTab(); const string DefaultTab = "\t"; @@ -139,7 +139,7 @@ void ReorderNewItemsAtEnd(XmlNode node) // The loop continues until we find something that isn't // a new Element. If it's whitespace, then that will be // the whitespace we need to move. - XmlNode whitespace = null; + XmlNode? whitespace = null; while (iter != null) { switch (iter.NodeType) @@ -209,15 +209,15 @@ int HandleWhiteSpace(XmlNode node) { // Prefer to keep 'node', but if 'PreviousNode' has a newline // and 'node' doesn't, keep the whitespace with the newline - XmlNode removeNode = PreviousNode; - if (FindLastNewLine(node.OuterXml) < 0 && FindLastNewLine(PreviousNode.OuterXml) >= 0) + XmlNode? removeNode = PreviousNode; + if (FindLastNewLine(node.OuterXml) < 0 && FindLastNewLine(PreviousNode!.OuterXml) >= 0) removeNode = node; - removeNode.ParentNode.RemoveChild(removeNode); + removeNode?.ParentNode?.RemoveChild(removeNode); indexChange = -1; } - string indent = GetIndentFromWhiteSpace(node); + string? indent = GetIndentFromWhiteSpace(node); if (indent != null) SetIndent(indent); @@ -242,7 +242,7 @@ int EnsureNodeIndent(XmlNode node, bool indentBeforeEnd) return indexChange; } - string GetIndentFromWhiteSpace(XmlNode node) + string? GetIndentFromWhiteSpace(XmlNode node) { string whitespace = node.OuterXml; int index = FindLastNewLine(whitespace); @@ -300,7 +300,7 @@ void PushIndent() // indent. These aren't always needed, so we don't compute // them until necessary. Also, we don't walk through this // stack like we do the indents stack. - _attributeIndents.AddLast(new LinkedListNode(_currentAttributeIndent)); + _attributeIndents.AddLast(new LinkedListNode(_currentAttributeIndent!)); _currentAttributeIndent = null; } @@ -318,18 +318,18 @@ void PopIndent() throw new InvalidOperationException("Popped too many indents"); } - bool NeedsIndent(XmlNode node, XmlNode previousNode) + bool NeedsIndent(XmlNode node, XmlNode? previousNode) { return !IsWhiteSpace(previousNode) && !IsText(previousNode) && (IsNewNode(node) || IsNewNode(previousNode)); } - static bool IsWhiteSpace(XmlNode node) => node != null && node.NodeType == XmlNodeType.Whitespace; + static bool IsWhiteSpace(XmlNode? node) => node != null && node.NodeType == XmlNodeType.Whitespace; - public bool IsText(XmlNode node) => node != null && node.NodeType == XmlNodeType.Text; + public bool IsText(XmlNode? node) => node != null && node.NodeType == XmlNodeType.Text; - bool IsNewNode(XmlNode node) => node != null && _document.IsNewNode(node); + bool IsNewNode(XmlNode? node) => node != null && _document.IsNewNode(node); void InsertIndentBefore(XmlNode node) => node.ParentNode.InsertBefore(_document.CreateWhitespace(CurrentIndent), node); @@ -337,9 +337,9 @@ bool NeedsIndent(XmlNode node, XmlNode previousNode) string ComputeCurrentIndent() => LookAheadForIndent() ?? PreviousIndent + OneTab; - string LookAheadForIndent() + string? LookAheadForIndent() { - if (_currentNode.ParentNode == null) + if (_currentNode?.ParentNode == null) return null; foreach (XmlNode siblingNode in _currentNode.ParentNode.ChildNodes) @@ -398,20 +398,20 @@ static string ConvertIndentToTab(string indent) return DefaultTab; } - string ComputeCurrentAttributeIndent() + string? ComputeCurrentAttributeIndent() { - string siblingIndent = LookForSiblingIndent(CurrentNode); + string? siblingIndent = LookForSiblingIndent(CurrentNode); if (siblingIndent != null) return siblingIndent; return CurrentIndent + OneTab; } - static string LookForSiblingIndent(XmlNode currentNode) + static string? LookForSiblingIndent(XmlNode? currentNode) { var beforeCurrentNode = true; - string foundIndent = null; + string? foundIndent = null; - foreach (XmlNode node in currentNode.ParentNode.ChildNodes) + foreach (XmlNode node in currentNode?.ParentNode?.ChildNodes!) { if (node == currentNode) beforeCurrentNode = false; diff --git a/dotnet-xdt/XmlLocator.cs b/dotnet-xdt/XmlLocator.cs index 8457fa2..0cca9ff 100644 --- a/dotnet-xdt/XmlLocator.cs +++ b/dotnet-xdt/XmlLocator.cs @@ -22,25 +22,25 @@ enum XPathAxis abstract class Locator { - IList _arguments; - string _parentPath; - XmlElementContext _context; - XmlTransformationLogger _logger; + IList? _arguments; + string? _parentPath; + XmlElementContext? _context; + XmlTransformationLogger? _logger; - protected virtual string ParentPath => _parentPath; + protected virtual string ParentPath => _parentPath!; - protected XmlNode CurrentElement => _context.Element; + protected XmlNode? CurrentElement => _context?.Element; protected virtual string NextStepNodeTest - => !string.IsNullOrEmpty(CurrentElement.NamespaceURI) && string.IsNullOrEmpty(CurrentElement.Prefix) - ? string.Concat("_defaultNamespace:", CurrentElement.LocalName) - : CurrentElement.Name; + => !string.IsNullOrEmpty(CurrentElement?.NamespaceURI) && string.IsNullOrEmpty(CurrentElement?.Prefix) + ? string.Concat("_defaultNamespace:", CurrentElement!.LocalName) + : CurrentElement!.Name; protected virtual XPathAxis NextStepAxis => XPathAxis.Child; protected virtual string ConstructPath() - => AppendStep(ParentPath, NextStepAxis, NextStepNodeTest, ConstructPredicate()); + => AppendStep(ParentPath!, NextStepAxis, NextStepNodeTest, ConstructPredicate()); protected string AppendStep(string basePath, string stepNodeTest) => AppendStep(basePath, XPathAxis.Child, stepNodeTest, string.Empty); @@ -62,23 +62,23 @@ protected string AppendStep(string basePath, XPathAxis stepAxis, string stepNode protected virtual string ConstructPredicate() => string.Empty; - protected XmlTransformationLogger Log + protected XmlTransformationLogger? Log { get { if (_logger == null) { - _logger = _context.GetService(); + _logger = _context?.GetService(); if (_logger != null) - _logger.CurrentReferenceNode = _context.LocatorAttribute; + _logger.CurrentReferenceNode = _context!.LocatorAttribute; } return _logger; } } - protected string ArgumentString { get; private set; } + protected string? ArgumentString { get; private set; } - protected IList Arguments + protected IList? Arguments { get { @@ -107,11 +107,11 @@ protected void EnsureArguments(int min, int max) EnsureArguments(min); - if (Arguments.Count > max) + if (Arguments?.Count > max) throw new XmlTransformationException(string.Format(System.Globalization.CultureInfo.CurrentCulture, SR.XMLTRANSFORMATION_TooManyArguments, GetType().Name)); } - internal string ConstructPath(string parentPath, XmlElementContext context, string argumentString) + internal string ConstructPath(string parentPath, XmlElementContext context, string? argumentString) { Debug.Assert(_parentPath == null && _context == null && ArgumentString == null, "Do not call ConstructPath recursively"); @@ -142,7 +142,7 @@ internal string ConstructPath(string parentPath, XmlElementContext context, stri return resultPath; } - internal string ConstructParentPath(string parentPath, XmlElementContext context, string argumentString) + internal string ConstructParentPath(string parentPath, XmlElementContext context, string? argumentString) { Debug.Assert(_parentPath == null && _context == null && ArgumentString == null, "Do not call ConstructPath recursively"); @@ -157,7 +157,7 @@ internal string ConstructParentPath(string parentPath, XmlElementContext context _context = context; ArgumentString = argumentString; - resultPath = ParentPath; + resultPath = ParentPath!; } finally { diff --git a/dotnet-xdt/XmlLocators.cs b/dotnet-xdt/XmlLocators.cs index e7f61f5..f2b49fc 100644 --- a/dotnet-xdt/XmlLocators.cs +++ b/dotnet-xdt/XmlLocators.cs @@ -15,11 +15,11 @@ protected override string ConstructPredicate() { EnsureArguments(1); - string keyPredicate = null; + string? keyPredicate = null; - foreach (string key in Arguments) + foreach (string key in Arguments!) { - if (CurrentElement.Attributes.GetNamedItem(key) is XmlAttribute keyAttribute) + if (CurrentElement!.Attributes.GetNamedItem(key) is XmlAttribute keyAttribute) { string keySegment = string.Format(CultureInfo.InvariantCulture, "@{0}='{1}'", keyAttribute.Name, keyAttribute.Value); keyPredicate = keyPredicate == null ? keySegment : string.Concat(keyPredicate, " and ", keySegment); @@ -28,7 +28,7 @@ protected override string ConstructPredicate() throw new XmlTransformationException(string.Format(CultureInfo.CurrentCulture, SR.XMLTRANSFORMATION_MatchAttributeDoesNotExist, key)); } - return keyPredicate; + return keyPredicate!; } } @@ -37,7 +37,7 @@ sealed class Condition : Locator protected override string ConstructPredicate() { EnsureArguments(1, 1); - return Arguments[0]; + return Arguments![0]; } } @@ -49,7 +49,7 @@ protected override string ConstructPath() { EnsureArguments(1, 1); - string xpath = Arguments[0]; + string xpath = Arguments![0]; if (!xpath.StartsWith("/", StringComparison.Ordinal)) { // Relative XPath diff --git a/dotnet-xdt/XmlNodeException.cs b/dotnet-xdt/XmlNodeException.cs index 4cbd4f5..9b09777 100644 --- a/dotnet-xdt/XmlNodeException.cs +++ b/dotnet-xdt/XmlNodeException.cs @@ -7,8 +7,8 @@ namespace DotNet.Xdt [Serializable] public sealed class XmlNodeException : XmlTransformationException { - readonly XmlFileInfoDocument _document; - readonly IXmlLineInfo _lineInfo; + readonly XmlFileInfoDocument? _document; + readonly IXmlLineInfo? _lineInfo; // If this is already an XmlNodeException, then it probably // got its node closer to the error, making it more accurate @@ -31,7 +31,7 @@ public XmlNodeException(string message, XmlNode node) public bool HasErrorInfo => _lineInfo != null; - public string FileName => _document?.FileName; + public string? FileName => _document?.FileName; public int LineNumber => _lineInfo?.LineNumber ?? 0; diff --git a/dotnet-xdt/XmlTransform.cs b/dotnet-xdt/XmlTransform.cs index 4e86c67..e646711 100644 --- a/dotnet-xdt/XmlTransform.cs +++ b/dotnet-xdt/XmlTransform.cs @@ -24,12 +24,12 @@ enum TransformFlags abstract class Transform { - XmlTransformationLogger _logger; - XmlElementContext _context; - XmlNode _currentTransformNode; - XmlNode _currentTargetNode; + XmlTransformationLogger? _logger; + XmlElementContext? _context; + XmlNode? _currentTransformNode; + XmlNode? _currentTargetNode; - IList _arguments; + IList? _arguments; protected Transform() : this(TransformFlags.None) @@ -54,7 +54,7 @@ protected Transform(TransformFlags flags, MissingTargetMessage message) protected abstract void Apply(); - protected XmlNode TransformNode => _currentTransformNode ?? _context.TransformNode; + protected XmlNode TransformNode => _currentTransformNode ?? _context!.TransformNode; protected XmlNode TargetNode { @@ -64,13 +64,13 @@ protected XmlNode TargetNode foreach (XmlNode targetNode in TargetNodes) return targetNode; - return _currentTargetNode; + return _currentTargetNode!; } } - protected XmlNodeList TargetNodes => UseParentAsTargetNode ? _context.TargetParents : _context.TargetNodes; + protected XmlNodeList TargetNodes => UseParentAsTargetNode ? _context!.TargetParents : _context!.TargetNodes; - protected XmlNodeList TargetChildNodes => _context.TargetNodes; + protected XmlNodeList TargetChildNodes => _context!.TargetNodes; protected XmlTransformationLogger Log { @@ -78,17 +78,17 @@ protected XmlTransformationLogger Log { if (_logger == null) { - _logger = _context.GetService(); + _logger = _context!.GetService(); if (_logger != null) _logger.CurrentReferenceNode = _context.TransformAttribute; } - return _logger; + return _logger!; } } - protected T GetService() where T : class => _context.GetService(); + protected T? GetService() where T : class => _context!.GetService(); - protected string ArgumentString { get; private set; } + protected string? ArgumentString { get; private set; } protected IList Arguments { @@ -96,7 +96,7 @@ protected IList Arguments { if (_arguments == null && ArgumentString != null) _arguments = XmlArgumentUtility.SplitArguments(ArgumentString); - return _arguments; + return _arguments!; } } @@ -104,7 +104,7 @@ string TransformNameLong { get { - if (_context.HasLineInfo) + if (_context!.HasLineInfo) return string.Format(System.Globalization.CultureInfo.CurrentCulture, SR.XMLTRANSFORMATION_TransformNameFormatLong, TransformName, _context.TransformLineNumber, _context.TransformLinePosition); return TransformNameShort; } @@ -115,7 +115,7 @@ internal string TransformNameShort string TransformName => GetType().Name; - internal void Execute(XmlElementContext context, string argumentString) + internal void Execute(XmlElementContext context, string? argumentString) { Debug.Assert(_context == null && ArgumentString == null, "Don't call Execute recursively"); Debug.Assert(_logger == null, "Logger wasn't released from previous execution"); @@ -182,14 +182,14 @@ void ReleaseLogger() void ApplyOnAllTargetNodes() { - XmlNode originalTransformNode = TransformNode; + XmlNode? originalTransformNode = TransformNode; foreach (XmlNode node in TargetNodes) { try { _currentTargetNode = node; - _currentTransformNode = originalTransformNode.Clone(); + _currentTransformNode = originalTransformNode!.Clone(); ApplyOnce(); } @@ -208,12 +208,12 @@ void ApplyOnce() Apply(); } - void WriteApplyMessage(XmlNode targetNode) + void WriteApplyMessage(XmlNode? targetNode) { if (targetNode is IXmlLineInfo lineInfo) Log.LogMessage(MessageType.Verbose, SR.XMLTRANSFORMATION_TransformStatusApplyTarget, targetNode.Name, lineInfo.LineNumber, lineInfo.LinePosition); else - Log.LogMessage(MessageType.Verbose, SR.XMLTRANSFORMATION_TransformStatusApplyTargetNoLineInfo, targetNode.Name); + Log.LogMessage(MessageType.Verbose, SR.XMLTRANSFORMATION_TransformStatusApplyTargetNoLineInfo, targetNode!.Name); } bool ShouldExecuteTransform() => HasRequiredTarget(); @@ -221,8 +221,8 @@ void WriteApplyMessage(XmlNode targetNode) bool HasRequiredTarget() { bool hasRequiredTarget = UseParentAsTargetNode - ? _context.HasTargetParent(out XmlElementContext matchFailureContext, out bool existedInOriginal) - : _context.HasTargetNode(out matchFailureContext, out existedInOriginal); + ? _context!.HasTargetParent(out XmlElementContext? matchFailureContext, out bool existedInOriginal) + : _context!.HasTargetNode(out matchFailureContext, out existedInOriginal); if (hasRequiredTarget) return true; @@ -230,13 +230,13 @@ bool HasRequiredTarget() return false; } - void HandleMissingTarget(XmlElementContext matchFailureContext, bool existedInOriginal) + void HandleMissingTarget(XmlElementContext? matchFailureContext, bool existedInOriginal) { string messageFormat = existedInOriginal ? SR.XMLTRANSFORMATION_TransformSourceMatchWasRemoved : SR.XMLTRANSFORMATION_TransformNoMatchingTargetNodes; - string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, messageFormat, matchFailureContext.XPath); + string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, messageFormat, matchFailureContext!.XPath); switch (MissingTargetMessage) { case MissingTargetMessage.None: diff --git a/dotnet-xdt/XmlTransformableDocument.cs b/dotnet-xdt/XmlTransformableDocument.cs index 8eadb39..e97b64a 100644 --- a/dotnet-xdt/XmlTransformableDocument.cs +++ b/dotnet-xdt/XmlTransformableDocument.cs @@ -4,7 +4,7 @@ namespace DotNet.Xdt { public class XmlTransformableDocument : XmlFileInfoDocument, IXmlOriginalDocumentService { - XmlDocument _xmlOriginal; + XmlDocument? _xmlOriginal; public bool IsChanged => _xmlOriginal != null && !IsXmlEqual(_xmlOriginal, this); @@ -24,7 +24,7 @@ internal void OnAfterChange() // assume there's a difference. static bool IsXmlEqual(XmlDocument xmlOriginal, XmlDocument xmlTransformed) => false; - XmlNodeList IXmlOriginalDocumentService.SelectNodes(string xpath, XmlNamespaceManager nsmgr) + XmlNodeList? IXmlOriginalDocumentService.SelectNodes(string xpath, XmlNamespaceManager nsmgr) => _xmlOriginal?.SelectNodes(xpath, nsmgr); } } diff --git a/dotnet-xdt/XmlTransformation.cs b/dotnet-xdt/XmlTransformation.cs index 8f39ea9..0e384ef 100644 --- a/dotnet-xdt/XmlTransformation.cs +++ b/dotnet-xdt/XmlTransformation.cs @@ -14,27 +14,27 @@ public class XmlTransformation : IServiceProvider, IDisposable readonly string _transformFile; XmlDocument _xmlTransformation; - XmlDocument _xmlTarget; - XmlTransformableDocument _xmlTransformable; + XmlDocument? _xmlTarget; + XmlTransformableDocument? _xmlTransformable; readonly XmlTransformationLogger _logger; - NamedTypeFactory _namedTypeFactory; + NamedTypeFactory? _namedTypeFactory; ServiceContainer _transformationServiceContainer = new ServiceContainer(); - ServiceContainer _documentServiceContainer; + ServiceContainer? _documentServiceContainer; public XmlTransformation(string transformFile) : this(transformFile, true, null) { } - public XmlTransformation(string transform, IXmlTransformationLogger logger) + public XmlTransformation(string transform, IXmlTransformationLogger? logger) : this(transform, true, logger) { } - public XmlTransformation(string transform, bool isTransformAFile, IXmlTransformationLogger logger) + public XmlTransformation(string transform, bool isTransformAFile, IXmlTransformationLogger? logger) { _transformFile = transform ?? throw new ArgumentNullException(nameof(transform)); - _logger = new XmlTransformationLogger(logger); + _logger = new XmlTransformationLogger(logger!); _xmlTransformation = new XmlFileInfoDocument(); if (isTransformAFile) @@ -95,7 +95,7 @@ void ReleaseDocumentServices() void PreprocessTransformDocument() { HasTransformNamespace = false; - foreach (XmlAttribute attribute in _xmlTransformation.SelectNodes("//namespace::*")) + foreach (XmlAttribute attribute in _xmlTransformation!.SelectNodes("//namespace::*")) { if (attribute.Value.Equals(TransformNamespace, StringComparison.Ordinal)) { @@ -120,7 +120,7 @@ void PreprocessTransformDocument() continue; } - XmlElementContext context = null; + XmlElementContext? context = null; try { switch (element.LocalName) @@ -147,10 +147,10 @@ void PreprocessTransformDocument() } public void AddTransformationService(Type serviceType, object serviceInstance) - => _transformationServiceContainer.AddService(serviceType, serviceInstance); + => _transformationServiceContainer!.AddService(serviceType, serviceInstance); public void RemoveTransformationService(Type serviceType) - => _transformationServiceContainer.RemoveService(serviceType); + => _transformationServiceContainer!.RemoveService(serviceType); public bool Apply(XmlDocument xmlTarget) { @@ -214,8 +214,8 @@ void TransformLoop(XmlNodeContext parentContext) } } - XmlElementContext CreateElementContext(XmlElementContext parentContext, XmlElement element) - => new XmlElementContext(parentContext, element, _xmlTarget, this); + XmlElementContext CreateElementContext(XmlElementContext? parentContext, XmlElement element) + => new XmlElementContext(parentContext, element, _xmlTarget!, this); void HandleException(Exception ex) => _logger.LogErrorFromException(ex); @@ -228,13 +228,13 @@ static Exception WrapException(Exception ex, XmlNodeContext context) void HandleElement(XmlElementContext context) { - Transform transform = context.ConstructTransform(out string argumentString); + Transform? transform = context.ConstructTransform(out string? argumentString); if (transform != null) { bool fOriginalSupressWarning = _logger.SupressWarnings; - if (context.Element.Attributes.GetNamedItem(SupressWarnings, TransformNamespace) is XmlAttribute supressWarningsAttribute) + if (context.Element!.Attributes.GetNamedItem(SupressWarnings, TransformNamespace) is XmlAttribute supressWarningsAttribute) { bool fSupressWarning = Convert.ToBoolean(supressWarningsAttribute.Value, System.Globalization.CultureInfo.InvariantCulture); _logger.SupressWarnings = fSupressWarning; @@ -269,11 +269,11 @@ void HandleElement(XmlElementContext context) void PreprocessImportElement(XmlElementContext context) { - string assemblyName = null; - string nameSpace = null; - string path = null; + string? assemblyName = null; + string? nameSpace = null; + string? path = null; - foreach (XmlAttribute attribute in context.Element.Attributes) + foreach (XmlAttribute attribute in context.Element!.Attributes) { if (attribute.NamespaceURI.Length == 0) { @@ -304,14 +304,14 @@ void PreprocessImportElement(XmlElementContext context) throw new XmlNodeException(string.Format(System.Globalization.CultureInfo.CurrentCulture, SR.XMLTRANSFORMATION_ImportMissingNamespace), context.Element); if (assemblyName != null) - _namedTypeFactory.AddAssemblyRegistration(assemblyName, nameSpace); + _namedTypeFactory!.AddAssemblyRegistration(assemblyName, nameSpace); else - _namedTypeFactory.AddPathRegistration(path, nameSpace); + _namedTypeFactory!.AddPathRegistration(path!, nameSpace); } - public object GetService(Type serviceType) + public object? GetService(Type serviceType) { - object service = null; + object? service = null; if (_documentServiceContainer != null) service = _documentServiceContainer.GetService(serviceType); @@ -323,7 +323,7 @@ protected virtual void Dispose(bool disposing) if (_transformationServiceContainer != null) { _transformationServiceContainer.Dispose(); - _transformationServiceContainer = null; + _transformationServiceContainer = null!; } if (_documentServiceContainer != null) @@ -341,7 +341,7 @@ protected virtual void Dispose(bool disposing) if (_xmlTransformation is XmlFileInfoDocument xmlFileInfoDocument) { xmlFileInfoDocument.Dispose(); - _xmlTransformation = null; + _xmlTransformation = null!; } } diff --git a/dotnet-xdt/XmlTransformationLogger.cs b/dotnet-xdt/XmlTransformationLogger.cs index 16a706e..a6c27d8 100644 --- a/dotnet-xdt/XmlTransformationLogger.cs +++ b/dotnet-xdt/XmlTransformationLogger.cs @@ -8,7 +8,7 @@ namespace DotNet.Xdt public class XmlTransformationLogger { readonly IXmlTransformationLogger _externalLogger; - XmlNode _currentReferenceNode; + XmlNode? _currentReferenceNode; internal XmlTransformationLogger(IXmlTransformationLogger logger) => _externalLogger = logger; @@ -36,7 +36,7 @@ internal void LogErrorFromException(Exception ex) internal bool HasLoggedErrors { get; set; } - internal XmlNode CurrentReferenceNode + internal XmlNode? CurrentReferenceNode { get => _currentReferenceNode; set @@ -80,7 +80,7 @@ public void LogWarning(XmlNode referenceNode, string message, params object[] me { if (_externalLogger != null) { - string fileName = ConvertUriToFileName(referenceNode.OwnerDocument); + string? fileName = ConvertUriToFileName(referenceNode.OwnerDocument); if (referenceNode is IXmlLineInfo lineInfo) { @@ -120,7 +120,7 @@ public void LogError(XmlNode referenceNode, string message, params object[] mess if (_externalLogger != null) { - string fileName = ConvertUriToFileName(referenceNode.OwnerDocument); + string? fileName = ConvertUriToFileName(referenceNode.OwnerDocument); if (referenceNode is IXmlLineInfo lineInfo) { @@ -155,13 +155,13 @@ public void EndSection(string message, params object[] messageArgs) public void EndSection(MessageType type, string message, params object[] messageArgs) => _externalLogger?.EndSection(type, message, messageArgs); - static string ConvertUriToFileName(XmlDocument xmlDocument) + static string? ConvertUriToFileName(XmlDocument? xmlDocument) { - string uri = xmlDocument is XmlFileInfoDocument errorInfoDocument ? errorInfoDocument.FileName : xmlDocument.BaseURI; + string? uri = xmlDocument is XmlFileInfoDocument errorInfoDocument ? errorInfoDocument.FileName : xmlDocument!.BaseURI; return ConvertUriToFileName(uri); } - static string ConvertUriToFileName(string fileName) + static string? ConvertUriToFileName(string? fileName) { try { diff --git a/dotnet-xdt/XmlTransforms.cs b/dotnet-xdt/XmlTransforms.cs index e45d1a7..a4896d0 100644 --- a/dotnet-xdt/XmlTransforms.cs +++ b/dotnet-xdt/XmlTransforms.cs @@ -9,7 +9,7 @@ namespace DotNet.Xdt { static class CommonErrors { - internal static void ExpectNoArguments(XmlTransformationLogger log, string transformName, string argumentString) + internal static void ExpectNoArguments(XmlTransformationLogger log, string transformName, string? argumentString) { if (!string.IsNullOrEmpty(argumentString)) log.LogWarning(SR.XMLTRANSFORMATION_TransformDoesNotExpectArguments, transformName); @@ -100,7 +100,7 @@ internal InsertBase() : base(TransformFlags.UseParentAsTargetNode, MissingTargetMessage.Error) { } - XmlElement _siblingElement; + XmlElement? _siblingElement; protected XmlElement SiblingElement { @@ -194,7 +194,7 @@ public SetTokenizedAttributeStorage(int capacity) /// class SetTokenizedAttributes : AttributeTransform { - SetTokenizedAttributeStorage _storageDictionary; + SetTokenizedAttributeStorage? _storageDictionary; bool _fInitStorageDictionary; public static readonly string Token = "Token"; public static readonly string TokenNumber = "TokenNumber"; @@ -203,7 +203,7 @@ class SetTokenizedAttributes : AttributeTransform public static readonly string XpathLocator = "XpathLocator"; public static readonly string XPathWithLocator = "XPathWithLocator"; - XmlAttribute _tokenizeValueCurrentXmlAttribute; + XmlAttribute? _tokenizeValueCurrentXmlAttribute; protected SetTokenizedAttributeStorage TransformStorage @@ -215,7 +215,7 @@ protected SetTokenizedAttributeStorage TransformStorage _storageDictionary = GetService(); _fInitStorageDictionary = true; } - return _storageDictionary; + return _storageDictionary!; } } @@ -223,7 +223,7 @@ protected override void Apply() { var fTokenizeParameter = false; SetTokenizedAttributeStorage storage = TransformStorage; - List> parameters = null; + List>? parameters = null; if (storage != null) { @@ -234,7 +234,7 @@ protected override void Apply() foreach (XmlAttribute transformAttribute in TransformAttributes) { - var targetAttribute = TargetNode.Attributes.GetNamedItem(transformAttribute.Name) as XmlAttribute; + XmlAttribute? targetAttribute = TargetNode.Attributes.GetNamedItem(transformAttribute.Name) as XmlAttribute; string newValue = TokenizeValue(targetAttribute, transformAttribute, fTokenizeParameter, parameters); @@ -257,30 +257,30 @@ protected override void Apply() } - static RegularExpressions.Regex _sDirRegex; - static RegularExpressions.Regex _sParentAttribRegex; - static RegularExpressions.Regex _sTokenFormatRegex; + static RegularExpressions.Regex? _sDirRegex; + static RegularExpressions.Regex? _sParentAttribRegex; + static RegularExpressions.Regex? _sTokenFormatRegex; // Directory registrory - internal static RegularExpressions.Regex DirRegex => _sDirRegex - ?? (_sDirRegex = new RegularExpressions.Regex(@"\G\{%(\s*(?\w+(?=\W))(\s*(?=)\s*'(?[^']*)'|\s*(?=)\s*(?[^\s%>]*)|(?)(?\s*?)))*\s*?%\}")); + internal static RegularExpressions.Regex DirRegex + => _sDirRegex ??= new RegularExpressions.Regex(@"\G\{%(\s*(?\w+(?=\W))(\s*(?=)\s*'(?[^']*)'|\s*(?=)\s*(?[^\s%>]*)|(?)(?\s*?)))*\s*?%\}"); - internal static RegularExpressions.Regex ParentAttributeRegex => _sParentAttribRegex - ?? (_sParentAttribRegex = new RegularExpressions.Regex(@"\G\$\((?[\w:\.]+)\)")); + internal static RegularExpressions.Regex ParentAttributeRegex + => _sParentAttribRegex ??= new RegularExpressions.Regex(@"\G\$\((?[\w:\.]+)\)"); - internal static RegularExpressions.Regex TokenFormatRegex => _sTokenFormatRegex - ?? (_sTokenFormatRegex = new RegularExpressions.Regex(@"\G\#\((?[\w:\.]+)\)")); + internal static RegularExpressions.Regex TokenFormatRegex + => _sTokenFormatRegex ??= new RegularExpressions.Regex(@"\G\#\((?[\w:\.]+)\)"); - protected delegate string GetValueCallback(string key); + protected delegate string? GetValueCallback(string key); - protected string GetAttributeValue(string attributeName) + protected string? GetAttributeValue(string attributeName) { - string dataValue = null; + string? dataValue = null; var sourceAttribute = TargetNode.Attributes.GetNamedItem(attributeName) as XmlAttribute; if (sourceAttribute == null) { // if it is other attributename, we fall back to the current now - if (string.Compare(attributeName, _tokenizeValueCurrentXmlAttribute.Name, StringComparison.OrdinalIgnoreCase) != 0) + if (string.Compare(attributeName, _tokenizeValueCurrentXmlAttribute!.Name, StringComparison.OrdinalIgnoreCase) != 0) sourceAttribute = TransformNode.Attributes.GetNamedItem(attributeName) as XmlAttribute; } if (sourceAttribute != null) @@ -292,7 +292,7 @@ protected string GetAttributeValue(string attributeName) protected string EscapeDirRegexSpecialCharacter(string value, bool escape) => escape ? value.Replace("'", "'") : value.Replace("'", "'"); - protected static string SubstituteKownValue(string transformValue, RegularExpressions.Regex patternRegex, string patternPrefix, GetValueCallback getValueDelegate) + protected static string SubstituteKnownValue(string transformValue, RegularExpressions.Regex patternRegex, string patternPrefix, GetValueCallback getValueDelegate) { var position = 0; var matchsExpr = new List(); @@ -324,7 +324,7 @@ protected static string SubstituteKownValue(string transformValue, RegularExpres RegularExpressions.Capture captureTagName = match.Groups["tagname"]; string attributeName = captureTagName.Value; - string newValue = getValueDelegate(attributeName); + string? newValue = getValueDelegate(attributeName); // null indicate that the attribute is not exist strbuilder.Append(newValue ?? match.Value); @@ -338,15 +338,15 @@ protected static string SubstituteKownValue(string transformValue, RegularExpres return transformValue; } - string GetXPathToAttribute(XmlAttribute xmlAttribute) + string GetXPathToAttribute(XmlAttribute? xmlAttribute) => GetXPathToAttribute(xmlAttribute, null); - string GetXPathToAttribute(XmlAttribute xmlAttribute, IList locators) + string GetXPathToAttribute(XmlAttribute? xmlAttribute, IList? locators) { string path = string.Empty; if (xmlAttribute != null) { - string pathToNode = GetXPathToNode(xmlAttribute.OwnerElement); + string? pathToNode = GetXPathToNode(xmlAttribute.OwnerElement); if (!string.IsNullOrEmpty(pathToNode)) { var identifier = new StringBuilder(256); @@ -354,7 +354,7 @@ string GetXPathToAttribute(XmlAttribute xmlAttribute, IList locators) { foreach (string match in locators) { - string val = GetAttributeValue(match); + string? val = GetAttributeValue(match); if (!string.IsNullOrEmpty(val)) { if (identifier.Length != 0) @@ -385,18 +385,18 @@ string GetXPathToAttribute(XmlAttribute xmlAttribute, IList locators) return path; } - static string GetXPathToNode(XmlNode xmlNode) + static string? GetXPathToNode(XmlNode xmlNode) { if (xmlNode == null || xmlNode.NodeType == XmlNodeType.Document) return null; - string parentPath = GetXPathToNode(xmlNode.ParentNode); + string? parentPath = GetXPathToNode(xmlNode.ParentNode); return string.Concat(parentPath, "/", xmlNode.Name); } - string TokenizeValue(XmlAttribute targetAttribute, + string TokenizeValue(XmlAttribute? targetAttribute, XmlAttribute transformAttribute, bool fTokenizeParameter, - List> parameters) + List>? parameters) { Debug.Assert(!fTokenizeParameter || parameters != null); @@ -405,7 +405,7 @@ string TokenizeValue(XmlAttribute targetAttribute, string xpath = GetXPathToAttribute(targetAttribute); //subsitute the know value first in the transformAttribute - transformValue = SubstituteKownValue(transformValue, ParentAttributeRegex, "$(", key => EscapeDirRegexSpecialCharacter(GetAttributeValue(key), true)); + transformValue = SubstituteKnownValue(transformValue, ParentAttributeRegex, "$(", key => EscapeDirRegexSpecialCharacter(GetAttributeValue(key)!, true)); // then use the directive to parse the value. --- if TokenizeParameterize is enable if (fTokenizeParameter && parameters != null) @@ -454,15 +454,15 @@ string TokenizeValue(XmlAttribute targetAttribute, for (var i = 0; i < attrnames.Count; i++) { string name = attrnames[i].Value; - string val = null; + string? val = null; if (attrvalues != null && i < attrvalues.Count) val = EscapeDirRegexSpecialCharacter(attrvalues[i].Value, false); - paramDictionary[name] = val; + paramDictionary[name] = val!; } //Identify the Token format - if (!paramDictionary.TryGetValue(Token, out string strTokenFormat)) - strTokenFormat = _storageDictionary.TokenFormat; + if (!paramDictionary.TryGetValue(Token, out string? strTokenFormat)) + strTokenFormat = _storageDictionary!.TokenFormat; if (!string.IsNullOrEmpty(strTokenFormat)) paramDictionary[Token] = strTokenFormat; @@ -480,7 +480,7 @@ string TokenizeValue(XmlAttribute targetAttribute, // parameterDictionary["TokenNumber"] string keyindex = keys[i]; string val = paramDictionary[keyindex]; - string newVal = SubstituteKownValue(val, TokenFormatRegex, "#(", + string newVal = SubstituteKnownValue(val, TokenFormatRegex, "#(", key => paramDictionary.ContainsKey(key) ? paramDictionary[key] : null); paramDictionary[keyindex] = newVal; diff --git a/dotnet-xdt/dotnet-xdt.csproj b/dotnet-xdt/dotnet-xdt.csproj index e49375f..13c4b91 100644 --- a/dotnet-xdt/dotnet-xdt.csproj +++ b/dotnet-xdt/dotnet-xdt.csproj @@ -10,7 +10,9 @@ $(_ToolTFM) true - latest + preview + enable + $(Nullable) strict embedded true @@ -19,10 +21,10 @@ DotNet.Xdt dotnet-xdt - 2.1.1 + 2.2.0 $(FileVersion) - <_ReleaseNotes>Enable [SourceLink](https://github.com/dotnet/sourcelink#readme) for access to original source code while debugging. + <_ReleaseNotes>Enable [RollForward=Major](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#major-version-roll-forward) to allow running `dotnet-xdt` on .NET Core 3.x and later versions. @@ -33,6 +35,7 @@ + Major true XDT (XML Document Transform) tool for .NET Core. <_PackageTags>netcoreapp21;global-tool @@ -59,7 +62,7 @@ - + diff --git a/global.json b/global.json index a08e14d..e9aac8c 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "2.2.204" + "version": "3.1.100" } }