| File: MSBuild\ProjectFile\CommandLineArgumentReader.cs | Web Access |
| Project: src\roslyn\src\Workspaces\MSBuild\BuildHost\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj (Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using Roslyn.Utilities; using MSB = Microsoft.Build; namespace Microsoft.CodeAnalysis.MSBuild; internal abstract class CommandLineArgumentReader { protected readonly MSB.Execution.ProjectInstance Project; private readonly List<string> _builder; protected CommandLineArgumentReader(MSB.Execution.ProjectInstance project) { Project = project; _builder = new List<string>(); } protected abstract void ReadCore(); private static void ValidateName(string name) { if (string.IsNullOrEmpty(name) || name.Any(char.IsWhiteSpace)) { throw new ArgumentException(WorkspaceMSBuildBuildHostResources.Parameter_cannot_be_null_empty_or_contain_whitespace, nameof(name)); } } protected void Add(string name) { ValidateName(name); _builder.Add($"/{name}"); } protected void Add(string name, string? value, bool addQuoteIfValueContainsWhitespace = true) { ValidateName(name); if (string.IsNullOrEmpty(value) || (addQuoteIfValueContainsWhitespace && value.Any(char.IsWhiteSpace))) { _builder.Add($"/{name}:\"{value}\""); } else { _builder.Add($"/{name}:{value}"); } } protected void Add(string name, int value) { Add(name, value.ToString()); } protected void AddIfNotNullOrWhiteSpace(string name, string? value, bool addQuoteIfValueContainsWhitespace = true) { if (!RoslynString.IsNullOrWhiteSpace(value)) { Add(name, value, addQuoteIfValueContainsWhitespace); } } protected void AddIfTrue(string name, bool condition) { if (condition) { Add(name); } } protected void AddIfTrue(string name, string value, bool condition) { if (condition) { Add(name, value); } } protected void AddIfFalse(string name, bool condition) { if (!condition) { Add(name); } } protected void AddWithPlus(string name) { Add($"{name}+"); } protected void AddWithMinus(string name) { Add($"{name}-"); } protected void AddWithPlusOrMinus(string name, bool condition) { if (condition) { AddWithPlus(name); } else { AddWithMinus(name); } } protected void ReadAdditionalFiles() { var additionalFiles = Project.GetAdditionalFiles(); if (additionalFiles != null) { foreach (var additionalFile in additionalFiles) { Add("additionalfile", Project.GetAbsolutePath(additionalFile.ItemSpec)); } } } protected void ReadAnalyzers() { var analyzers = Project.GetAnalyzers(); if (analyzers != null) { foreach (var analyzer in analyzers) { Add("analyzer", Project.GetAbsolutePath(analyzer.ItemSpec)); } } } protected void ReadCodePage() { var codePage = Project.ReadCodePage(); AddIfTrue("codepage", codePage.ToString(), codePage != 0); } private static readonly Dictionary<string, string> s_debugTypeValues = new(StringComparer.OrdinalIgnoreCase) { { "none", "none" }, { "pdbonly", "pdbonly" }, { "full", "full" }, { "portable", "portable" }, { "embedded", "embedded" } }; protected void ReadDebugInfo() { var emitDebugInfo = Project.ReadPropertyBool(PropertyNames.DebugSymbols); if (emitDebugInfo) { var debugType = Project.ReadPropertyString(PropertyNames.DebugType); if (debugType != null && s_debugTypeValues.TryGetValue(debugType, out var value)) { Add("debug", value); } } } protected void ReadDelaySign() { var delaySign = Project.ReadPropertyString(PropertyNames.DelaySign); if (!RoslynString.IsNullOrWhiteSpace(delaySign)) { AddWithPlusOrMinus("delaysign", Conversions.ToBool(delaySign)); } } protected void ReadErrorReport() { var errorReport = Project.ReadPropertyString(PropertyNames.ErrorReport); if (!RoslynString.IsNullOrWhiteSpace(errorReport)) { Add("errorreport", errorReport.ToLower()); } } protected void ReadFeatures() { var features = Project.ReadPropertyString(PropertyNames.Features); if (!RoslynString.IsNullOrWhiteSpace(features)) { foreach (var feature in CompilerOptionParseUtilities.ParseFeatureFromMSBuild(features)) { Add("features", feature); } } } protected void ReadImports() { var imports = Project.GetTaskItems(ItemNames.Import); if (imports == null) return; // In case of import alias clause in the form of `aliasname = namespace`, // we want to add quotes to that single clause only instead of the entire imports. AddIfNotNullOrWhiteSpace("imports", string.Join(",", imports.Select(ReadImportItem)), addQuoteIfValueContainsWhitespace: false); static string ReadImportItem(MSB.Framework.ITaskItem item) { var trimmed = item.ItemSpec.Trim(); return trimmed.Contains(' ') ? $"\"{trimmed}\"" : trimmed; } } protected void ReadPlatform() { var platform = Project.ReadPropertyString(PropertyNames.PlatformTarget); var prefer32bit = Project.ReadPropertyBool(PropertyNames.Prefer32Bit); if (prefer32bit && (RoslynString.IsNullOrWhiteSpace(platform) || string.Equals("anycpu", platform, StringComparison.OrdinalIgnoreCase))) { platform = "anycpu32bitpreferred"; } AddIfNotNullOrWhiteSpace("platform", platform); } protected void ReadReferences() { foreach (var (filePath, aliases) in Project.GetMetadataReferences()) { if (aliases.Length == 0) { Add("reference", filePath); } else { foreach (var alias in aliases) { if (string.Equals(alias, "global", StringComparison.OrdinalIgnoreCase)) { Add("reference", filePath); } else { Add("reference", $"{alias}=\"{filePath}\""); } } } } } protected void ReadSigning() { var signAssembly = Project.ReadPropertyBool(PropertyNames.SignAssembly); if (signAssembly) { var keyFile = Project.ReadPropertyString(PropertyNames.KeyOriginatorFile); if (!RoslynString.IsNullOrWhiteSpace(keyFile)) { Add("keyFile", keyFile); } var keyContainer = Project.ReadPropertyString(PropertyNames.KeyContainerName); if (!RoslynString.IsNullOrWhiteSpace(keyContainer)) { Add("keycontainer", keyContainer); } } } protected string[] Read() { ReadCore(); return _builder.ToArray(); } }