// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. namespace WixToolset.Netfx { using System; using System.Collections.Generic; using System.Xml.Linq; using WixToolset.Data; using WixToolset.Extensibility; using WixToolset.Extensibility.Data; using WixToolset.Netfx.Symbols; /// /// The compiler for the WiX Toolset .NET Framework Extension. /// public sealed class NetfxCompiler : BaseCompilerExtension { public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/netfx"; /// /// Processes an element for the Compiler. /// /// Parent element of element to process. /// Element to process. /// Extra information about the context in which this element is being parsed. public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary context) { switch (parentElement.Name.LocalName) { case "File": string fileId = context["FileId"]; switch (element.Name.LocalName) { case "NativeImage": this.ParseNativeImageElement(intermediate, section, element, fileId); break; default: this.ParseHelper.UnexpectedElement(parentElement, element); break; } break; case "Fragment": switch (element.Name.LocalName) { case "DotNetCoreSearch": this.ParseDotNetCoreSearchElement(intermediate, section, element); break; case "DotNetCoreSearchRef": this.ParseDotNetCoreSearchRefElement(intermediate, section, element); break; case "DotNetCoreSdkSearch": this.ParseDotNetCoreSdkSearchElement(intermediate, section, element); break; case "DotNetCoreSdkSearchRef": this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element); break; case "DotNetCoreSdkFeatureBandSearch": this.ParseDotNetCoreSdkFeatureBandSearchElement(intermediate, section, element); break; case "DotNetCoreSdkFeatureBandSearchRef": this.ParseDotNetCoreSdkFeatureBandSearchRefElement(intermediate, section, element); break; case "DotNetCompatibilityCheck": this.ParseDotNetCompatibilityCheckElement(intermediate, section, element); break; case "DotNetCompatibilityCheckRef": this.ParseDotNetCompatibilityCheckRefElement(intermediate, section, element); break; default: this.ParseHelper.UnexpectedElement(parentElement, element); break; } break; case "Bundle": switch (element.Name.LocalName) { case "DotNetCoreSearch": this.ParseDotNetCoreSearchElement(intermediate, section, element); break; case "DotNetCoreSearchRef": this.ParseDotNetCoreSearchRefElement(intermediate, section, element); break; case "DotNetCoreSdkSearch": this.ParseDotNetCoreSdkSearchElement(intermediate, section, element); break; case "DotNetCoreSdkSearchRef": this.ParseDotNetCoreSdkSearchRefElement(intermediate, section, element); break; case "DotNetCoreSdkFeatureBandSearch": this.ParseDotNetCoreSdkFeatureBandSearchElement(intermediate, section, element); break; case "DotNetCoreSdkFeatureBandSearchRef": this.ParseDotNetCoreSdkFeatureBandSearchRefElement(intermediate, section, element); break; default: this.ParseHelper.UnexpectedElement(parentElement, element); break; } break; case "Package": case "Module": switch (element.Name.LocalName) { case "DotNetCompatibilityCheck": this.ParseDotNetCompatibilityCheckElement(intermediate, section, element); break; case "DotNetCompatibilityCheckRef": this.ParseDotNetCompatibilityCheckRefElement(intermediate, section, element); break; default: this.ParseHelper.UnexpectedElement(parentElement, element); break; } break; default: this.ParseHelper.UnexpectedElement(parentElement, element); break; } } private void ParseDotNetCoreSearchElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string variable = null; string condition = null; string after = null; NetCoreSearchRuntimeType? runtimeType = null; NetCoreSearchPlatform? platform = null; var majorVersion = CompilerConstants.IntegerNotSet; foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "Variable": variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib); break; case "Condition": condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "After": after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "RuntimeType": var runtimeTypeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (runtimeTypeValue) { case "aspnet": runtimeType = NetCoreSearchRuntimeType.Aspnet; break; case "core": runtimeType = NetCoreSearchRuntimeType.Core; break; case "desktop": runtimeType = NetCoreSearchRuntimeType.Desktop; break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "RuntimeType", runtimeTypeValue, "aspnet", "core", "desktop")); break; } break; case "Platform": var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (platformValue) { case "arm64": platform = NetCoreSearchPlatform.Arm64; break; case "x64": platform = NetCoreSearchPlatform.X64; break; case "x86": platform = NetCoreSearchPlatform.X86; break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86")); break; } break; case "MajorVersion": // .NET Core had a different deployment strategy before .NET Core 3.0 which would require different detection logic. majorVersion = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 3, Int32.MaxValue); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } if (id == null) { id = this.ParseHelper.CreateIdentifier("dncs", variable, condition, after); } if (!runtimeType.HasValue) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "RuntimeType")); } if (!platform.HasValue) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform")); } if (majorVersion == CompilerConstants.IntegerNotSet) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "MajorVersion")); } else if (majorVersion == 4) { this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "MajorVersion", "4", "3", "5+")); } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); var bootstrapperExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBootstrapperExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64); if (bootstrapperExtensionId == null) { this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName)); } if (!this.Messaging.EncounteredError) { this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bootstrapperExtensionId); section.AddSymbol(new NetFxNetCoreSearchSymbol(sourceLineNumbers, id) { RuntimeType = runtimeType.Value, Platform = platform.Value, MajorVersion = majorVersion, }); } } private void ParseDotNetCoreSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSearch, refId); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); } private void ParseDotNetCoreSdkSearchElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string variable = null; string condition = null; string after = null; NetCoreSearchPlatform? platform = null; var majorVersion = CompilerConstants.IntegerNotSet; foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "Variable": variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib); break; case "Condition": condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "After": after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "Platform": var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (platformValue) { case "arm64": platform = NetCoreSearchPlatform.Arm64; break; case "x64": platform = NetCoreSearchPlatform.X64; break; case "x86": platform = NetCoreSearchPlatform.X86; break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86")); break; } break; case "MajorVersion": // .NET Core had a different deployment strategy before .NET Core 3.0 which would require different detection logic. majorVersion = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 3, Int32.MaxValue); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } if (id == null) { id = this.ParseHelper.CreateIdentifier("dncss", variable, condition, after); } if (!platform.HasValue) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform")); } if (majorVersion == CompilerConstants.IntegerNotSet) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "MajorVersion")); } else if (majorVersion == 4) { this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "MajorVersion", "4", "3", "5+")); } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); var bootstrapperExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBootstrapperExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64); if (bootstrapperExtensionId == null) { this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName)); } if (!this.Messaging.EncounteredError) { this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bootstrapperExtensionId); section.AddSymbol(new NetFxNetCoreSdkSearchSymbol(sourceLineNumbers, id) { Platform = platform.Value, MajorVersion = majorVersion, }); } } private void ParseDotNetCoreSdkSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSdkSearch, refId); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); } private void ParseDotNetCoreSdkFeatureBandSearchElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string variable = null; string condition = null; string after = null; NetCoreSearchPlatform? platform = null; string version = null; var majorVersion = 0; var minorVersion = 0; var patchVersion = 0; foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "Variable": variable = this.ParseHelper.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib); break; case "Condition": condition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "After": after = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "Platform": var platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (platformValue) { case "arm64": platform = NetCoreSearchPlatform.Arm64; break; case "x64": platform = NetCoreSearchPlatform.X64; break; case "x86": platform = NetCoreSearchPlatform.X86; break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Platform", platformValue, "arm64", "x64", "x86")); break; } break; case "Version": version = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } if (id == null) { id = this.ParseHelper.CreateIdentifier("dncsfbs", variable, condition, after); } if (!platform.HasValue) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform")); } if (String.IsNullOrEmpty(version)) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Version")); } else { if (!Version.TryParse(version, out var featureBandVersion)) { this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "x.x.x00")); } else { majorVersion = featureBandVersion.Major; minorVersion = featureBandVersion.Minor; patchVersion = featureBandVersion.Build; if ((patchVersion % 100) != 0 || featureBandVersion.Revision != -1) { this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "x.x.x00")); } if (majorVersion == 4) { this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Version", version, "3.*", "5+.*")); } } } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); var bootstrapperExtensionId = this.ParseHelper.CreateIdentifierValueFromPlatform("Wix4NetfxBootstrapperExtension", this.Context.Platform, BurnPlatforms.X86 | BurnPlatforms.X64 | BurnPlatforms.ARM64); if (bootstrapperExtensionId == null) { this.Messaging.Write(ErrorMessages.UnsupportedPlatformForElement(sourceLineNumbers, this.Context.Platform.ToString(), element.Name.LocalName)); } if (!this.Messaging.EncounteredError) { this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, bootstrapperExtensionId); section.AddSymbol(new NetFxNetCoreSdkFeatureBandSearchSymbol(sourceLineNumbers, id) { Platform = platform.Value, MajorVersion = majorVersion, MinorVersion = minorVersion, PatchVersion = patchVersion, }); } } private void ParseDotNetCoreSdkFeatureBandSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxNetCoreSdkFeatureBandSearch, refId); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); } /// /// Parses a NativeImage element. /// /// The element to parse. /// The file identifier of the parent element. private void ParseNativeImageElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string appBaseDirectory = null; string assemblyApplication = null; int attributes = 0x8; // 32bit is on by default int priority = 3; foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "AppBaseDirectory": appBaseDirectory = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); // See if a formatted value is specified. if (-1 == appBaseDirectory.IndexOf("[", StringComparison.Ordinal)) { this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, appBaseDirectory); } break; case "AssemblyApplication": assemblyApplication = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); // See if a formatted value is specified. if (-1 == assemblyApplication.IndexOf("[", StringComparison.Ordinal)) { this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, assemblyApplication); } break; case "Debug": if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= 0x1; } break; case "Dependencies": if (YesNoType.No == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= 0x2; } break; case "Platform": string platformValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); if (0 < platformValue.Length) { switch (platformValue) { case "32bit": // 0x8 is already on by default break; case "64bit": attributes &= ~0x8; attributes |= 0x10; break; case "all": attributes |= 0x10; break; } } break; case "Priority": priority = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 3); break; case "Profile": if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= 0x4; } break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } if (null == id) { id = this.ParseHelper.CreateIdentifier("nni", fileId); } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4NetFxScheduleNativeImage", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86); if (!this.Messaging.EncounteredError) { section.AddSymbol(new NetFxNativeImageSymbol(sourceLineNumbers, id) { FileRef = fileId, Priority = priority, Attributes = attributes, ApplicationFileRef = assemblyApplication, ApplicationBaseDirectoryRef = appBaseDirectory, }); } } /// /// Parses a DotNetCompatibilityCheck element. /// /// The element to parse. private void ParseDotNetCompatibilityCheckElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string property = null; string runtimeType = null; string platform = null; string version = null; string rollForward = "Minor"; foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "Property": property = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "RuntimeType": runtimeType = this.ParseRuntimeType(element, sourceLineNumbers, attrib); break; case "Platform": platform = this.ParsePlatform(element, sourceLineNumbers, attrib); break; case "Version": version = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib); break; case "RollForward": rollForward = this.ParseRollForward(element, sourceLineNumbers, attrib); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } if (null == id) { id = this.ParseHelper.CreateIdentifier("ndncc", property, runtimeType, platform, version); } if (String.IsNullOrEmpty(property)) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Property")); } if (String.IsNullOrEmpty(runtimeType)) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "RuntimeType")); } if (String.IsNullOrEmpty(platform)) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Platform")); } if (String.IsNullOrEmpty(version)) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Version")); } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4NetFxDotNetCompatibilityCheck", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86); if (!this.Messaging.EncounteredError) { section.AddSymbol(new NetFxDotNetCompatibilityCheckSymbol(sourceLineNumbers, id) { RuntimeType = runtimeType, Platform = platform, Version = version, RollForward = rollForward, Property = property, }); } } private string ParseRollForward(XElement element, SourceLineNumber sourceLineNumbers, XAttribute attrib) { string rollForward; rollForward = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (rollForward.ToLowerInvariant()) { case "latestmajor": rollForward = "LatestMajor"; break; case "major": rollForward = "Major"; break; case "latestminor": rollForward = "LatestMinor"; break; case "minor": rollForward = "Minor"; break; case "latestpatch": rollForward = "LatestPatch"; break; case "disable": rollForward = "Disable"; break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, rollForward, "latestmajor", "major", "latestminor", "minor", "latestpatch", "disable")); break; } return rollForward; } private string ParsePlatform(XElement element, SourceLineNumber sourceLineNumbers, XAttribute attrib) { string platform; platform = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (platform.ToLower()) { case "x86": case "x64": case "arm64": platform = platform.ToLower(); break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, platform, "x86", "x64", "arm64")); break; } return platform; } private string ParseRuntimeType(XElement element, SourceLineNumber sourceLineNumbers, XAttribute attrib) { var runtimeType = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (runtimeType.ToLower()) { case "aspnet": runtimeType = "Microsoft.AspNetCore.App"; break; case "desktop": runtimeType = "Microsoft.WindowsDesktop.App"; break; case "core": runtimeType = "Microsoft.NETCore.App"; break; default: this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, runtimeType, "aspnet", "desktop", "core")); break; } return runtimeType; } /// /// Parses a DotNetCompatibilityCheckRef element. /// /// The element to parse. private void ParseDotNetCompatibilityCheckRefElement(Intermediate intermediate, IntermediateSection section, XElement element) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, NetfxSymbolDefinitions.NetFxDotNetCompatibilityCheck, refId); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); break; } } else { this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); } } this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); } } }