private static ImmutableHashSet <string> GetAliasedNames( CompilationUnitSyntax?compilationUnit ) { var aliasedNames = s_emptyAliasedNames; if (compilationUnit is null) { return(aliasedNames); } foreach (var usingDirective in compilationUnit.Usings) { AddAliasedName(usingDirective); } foreach (var member in compilationUnit.Members) { if (member is NamespaceDeclarationSyntax namespaceDeclaration) { AddAliasedNames(namespaceDeclaration); } } return(aliasedNames); void AddAliasedName(UsingDirectiveSyntax usingDirective) { if (usingDirective.Alias is object) { if ( usingDirective.Name.GetRightmostName() is IdentifierNameSyntax identifierName ) { var identifierAlias = identifierName.Identifier.ValueText; if (!RoslynString.IsNullOrEmpty(identifierAlias)) { aliasedNames = aliasedNames.Add(identifierAlias); } } } } void AddAliasedNames(NamespaceDeclarationSyntax namespaceDeclaration) { foreach (var usingDirective in namespaceDeclaration.Usings) { AddAliasedName(usingDirective); } foreach (var member in namespaceDeclaration.Members) { if (member is NamespaceDeclarationSyntax memberNamespace) { AddAliasedNames(memberNamespace); } } } }
private static void ValidateName(string name) { if (RoslynString.IsNullOrEmpty(name) || name.Contains(char.IsWhiteSpace)) { throw new ArgumentException(WorkspaceMSBuildResources.Parameter_cannot_be_null_empty_or_contain_whitespace, nameof(name)); } }
internal static bool TryParseUInt16(string?value, out ushort result) { result = 0; if (RoslynString.IsNullOrEmpty(value)) { return(false); } int numBase = 10; if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { numBase = 16; } else if (value.StartsWith("0", StringComparison.OrdinalIgnoreCase)) { numBase = 8; } try { result = Convert.ToUInt16(value, numBase); } catch { return(false); } return(true); }
protected static string GetDocumentLogicalPath( MSB.Framework.ITaskItem documentItem, string projectDirectory ) { var link = documentItem.GetMetadata(MetadataNames.Link); if (!RoslynString.IsNullOrEmpty(link)) { // if a specific link is specified in the project file then use it to form the logical path. return(link); } else { var filePath = documentItem.ItemSpec; if (!PathUtilities.IsAbsolute(filePath)) { return(filePath); } var normalizedPath = FileUtilities.TryNormalizeAbsolutePath(filePath); if (normalizedPath == null) { return(filePath); } // If the document is within the current project directory (or subdirectory), then the logical path is the relative path // from the project's directory. if (normalizedPath.StartsWith(projectDirectory, StringComparison.OrdinalIgnoreCase)) { return(normalizedPath[projectDirectory.Length..]);
private void WriteRules() { if (_descriptors.Count > 0) { _writer.WriteObjectStart("rules"); foreach (var pair in _descriptors.ToSortedList()) { DiagnosticDescriptor descriptor = pair.Value; _writer.WriteObjectStart(pair.Key); // rule _writer.Write("id", descriptor.Id); string?shortDescription = descriptor.Title.ToString(_culture); if (!RoslynString.IsNullOrEmpty(shortDescription)) { _writer.Write("shortDescription", shortDescription); } string?fullDescription = descriptor.Description.ToString(_culture); if (!RoslynString.IsNullOrEmpty(fullDescription)) { _writer.Write("fullDescription", fullDescription); } _writer.Write("defaultLevel", GetLevel(descriptor.DefaultSeverity)); if (!string.IsNullOrEmpty(descriptor.HelpLinkUri)) { _writer.Write("helpUri", descriptor.HelpLinkUri); } _writer.WriteObjectStart("properties"); if (!string.IsNullOrEmpty(descriptor.Category)) { _writer.Write("category", descriptor.Category); } _writer.Write("isEnabledByDefault", descriptor.IsEnabledByDefault); if (descriptor.CustomTags.Any()) { _writer.WriteArrayStart("tags"); foreach (string tag in descriptor.CustomTags) { _writer.Write(tag); } _writer.WriteArrayEnd(); // tags } _writer.WriteObjectEnd(); // properties _writer.WriteObjectEnd(); // rule } _writer.WriteObjectEnd(); // rules } }
internal Task <ImmutableDictionary <string, string> > GetAnalyzerOptionsAsync(CancellationToken cancellationToken) { var projectFilePath = Project.FilePath; // We need to work out path to this document. Documents may not have a "real" file path if they're something created // as a part of a code action, but haven't been written to disk yet. string?effectiveFilePath = null; if (FilePath != null) { effectiveFilePath = FilePath; } else if (Name != null && projectFilePath != null) { var projectPath = PathUtilities.GetDirectoryName(projectFilePath); if (!RoslynString.IsNullOrEmpty(projectPath) && PathUtilities.GetDirectoryName(projectFilePath) is string directory) { effectiveFilePath = PathUtilities.CombinePathsUnchecked(directory, Name); } } if (effectiveFilePath != null) { return(Project.State.GetAnalyzerOptionsForPathAsync(effectiveFilePath, cancellationToken)); } else { // Really no idea where this is going, so bail return(Task.FromResult(DictionaryAnalyzerConfigOptions.EmptyDictionary)); } }
public override void LogDiagnostic(Diagnostic diagnostic, SuppressionInfo?suppressionInfo) { _writer.WriteObjectStart(); // result _writer.Write("ruleId", diagnostic.Id); string ruleKey = _descriptors.Add(diagnostic.Descriptor); if (ruleKey != diagnostic.Id) { _writer.Write("ruleKey", ruleKey); } _writer.Write("level", GetLevel(diagnostic.Severity)); string?message = diagnostic.GetMessage(_culture); if (!RoslynString.IsNullOrEmpty(message)) { _writer.Write("message", message); } if (diagnostic.IsSuppressed) { _writer.WriteArrayStart("suppressionStates"); _writer.Write("suppressedInSource"); _writer.WriteArrayEnd(); } WriteLocations(diagnostic.Location, diagnostic.AdditionalLocations); WriteResultProperties(diagnostic); _writer.WriteObjectEnd(); // result }
public static FixedLocalizableString Create(string?fixedResource) { if (RoslynString.IsNullOrEmpty(fixedResource)) { return(s_empty); } return(new FixedLocalizableString(fixedResource)); }
/// <returns> /// <list type="bullet"> /// <item><description><see langword="true"/> if <paramref name="applyFix"/> is specified and the fix is successfully applied</description></item> /// <item><description><see langword="false"/> if <paramref name="applyFix"/> is specified but the fix is not successfully applied</description></item> /// <item><description><see langword="null"/> if <paramref name="applyFix"/> is false, so there is no fix to apply</description></item> /// </list> /// </returns> public async Task <bool?> CodeActionsAsync( IEnumerable <string> expectedItems, string?applyFix = null, bool verifyNotShowing = false, bool ensureExpectedItemsAreOrdered = false, FixAllScope?fixAllScope = null, bool blockUntilComplete = true, CancellationToken cancellationToken = default) { await TestServices.Editor.ShowLightBulbAsync(cancellationToken); if (verifyNotShowing) { await CodeActionsNotShowingAsync(cancellationToken); return(null); } var actions = await TestServices.Editor.GetLightBulbActionsAsync(cancellationToken); if (expectedItems != null && expectedItems.Any()) { if (ensureExpectedItemsAreOrdered) { TestUtilities.ThrowIfExpectedItemNotFoundInOrder( actions, expectedItems); } else { TestUtilities.ThrowIfExpectedItemNotFound( actions, expectedItems); } } if (fixAllScope.HasValue) { Assumes.Present(applyFix); } if (!RoslynString.IsNullOrEmpty(applyFix)) { var result = await TestServices.Editor.ApplyLightBulbActionAsync(applyFix, fixAllScope, blockUntilComplete, cancellationToken); if (blockUntilComplete) { // wait for action to complete await TestServices.Workspace.WaitForAsyncOperationsAsync(FeatureAttribute.LightBulb, cancellationToken); } return(result); } return(null); }
/// <returns> /// <list type="bullet"> /// <item><description><see langword="true"/> if <paramref name="applyFix"/> is specified and the fix is successfully applied</description></item> /// <item><description><see langword="false"/> if <paramref name="applyFix"/> is specified but the fix is not successfully applied</description></item> /// <item><description><see langword="null"/> if <paramref name="applyFix"/> is false, so there is no fix to apply</description></item> /// </list> /// </returns> public bool?CodeActions( IEnumerable <string> expectedItems, string?applyFix = null, bool verifyNotShowing = false, bool ensureExpectedItemsAreOrdered = false, FixAllScope?fixAllScope = null, bool blockUntilComplete = true) { _textViewWindow.ShowLightBulb(); _textViewWindow.WaitForLightBulbSession(); if (verifyNotShowing) { CodeActionsNotShowing(); return(null); } var actions = _textViewWindow.GetLightBulbActions(); if (expectedItems != null && expectedItems.Any()) { if (ensureExpectedItemsAreOrdered) { TestUtilities.ThrowIfExpectedItemNotFoundInOrder( actions, expectedItems); } else { TestUtilities.ThrowIfExpectedItemNotFound( actions, expectedItems); } } if (fixAllScope.HasValue) { Contract.ThrowIfNull(applyFix); } if (!RoslynString.IsNullOrEmpty(applyFix)) { var result = _textViewWindow.ApplyLightBulbAction(applyFix, fixAllScope, blockUntilComplete); if (blockUntilComplete) { // wait for action to complete _instance.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.LightBulb); } return(result); } return(null); }
public async Task <ImmutableArray <ProjectFileInfo> > GetProjectFileInfosAsync(CancellationToken cancellationToken) { if (_loadedProject is null) { return(ImmutableArray.Create(ProjectFileInfo.CreateEmpty(Language, _loadedProject?.FullPath, Log))); } var targetFrameworkValue = _loadedProject.GetPropertyValue(PropertyNames.TargetFramework); var targetFrameworksValue = _loadedProject.GetPropertyValue(PropertyNames.TargetFrameworks); if (RoslynString.IsNullOrEmpty(targetFrameworkValue) && !RoslynString.IsNullOrEmpty(targetFrameworksValue)) { // This project has a <TargetFrameworks> property, but does not specify a <TargetFramework>. // In this case, we need to iterate through the <TargetFrameworks>, set <TargetFramework> with // each value, and build the project. var targetFrameworks = targetFrameworksValue.Split(';'); var results = ImmutableArray.CreateBuilder <ProjectFileInfo>(targetFrameworks.Length); if (!_loadedProject.GlobalProperties.TryGetValue(PropertyNames.TargetFramework, out var initialGlobalTargetFrameworkValue)) { initialGlobalTargetFrameworkValue = null; } foreach (var targetFramework in targetFrameworks) { _loadedProject.SetGlobalProperty(PropertyNames.TargetFramework, targetFramework); _loadedProject.ReevaluateIfNecessary(); var projectFileInfo = await BuildProjectFileInfoAsync(cancellationToken).ConfigureAwait(false); results.Add(projectFileInfo); } if (initialGlobalTargetFrameworkValue is null) { _loadedProject.RemoveGlobalProperty(PropertyNames.TargetFramework); } else { _loadedProject.SetGlobalProperty(PropertyNames.TargetFramework, initialGlobalTargetFrameworkValue); } _loadedProject.ReevaluateIfNecessary(); return(results.ToImmutable()); } else { var projectFileInfo = await BuildProjectFileInfoAsync(cancellationToken).ConfigureAwait(false); projectFileInfo ??= ProjectFileInfo.CreateEmpty(Language, _loadedProject?.FullPath, Log); return(ImmutableArray.Create(projectFileInfo)); } }
/// <summary> /// Adds a "/features:" switch to the command line for each provided feature. /// </summary> internal static void AddFeatures(CommandLineBuilderExtension commandLine, string?features) { if (RoslynString.IsNullOrEmpty(features)) { return; } foreach (var feature in CompilerOptionParseUtilities.ParseFeatureFromMSBuild(features)) { commandLine.AppendSwitchIfNotNull("/features:", feature.Trim()); } }
protected void Add(string name, string?value) { ValidateName(name); if (RoslynString.IsNullOrEmpty(value) || value.Contains(char.IsWhiteSpace)) { _builder.Add($"/{name}:\"{value}\""); } else { _builder.Add($"/{name}:{value}"); } }
public LocalConstantDefinition( string name, Location location, MetadataConstant compileTimeValue, ImmutableArray <bool> dynamicTransformFlags, ImmutableArray <string> tupleElementNames) { RoslynDebug.Assert(!RoslynString.IsNullOrEmpty(name)); RoslynDebug.Assert(compileTimeValue != null); Name = name; Location = location; CompileTimeValue = compileTimeValue; DynamicTransformFlags = dynamicTransformFlags.NullToEmpty(); TupleElementNames = tupleElementNames.NullToEmpty(); }
private static string?NormalizePath(string?path) { if (RoslynString.IsNullOrEmpty(path)) { return(path); } var c = path[path.Length - 1]; if (c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar) { path = path.Substring(0, path.Length - 1); } return(path); }
public override void LogDiagnostic(Diagnostic diagnostic, SuppressionInfo?suppressionInfo) { _writer.WriteObjectStart(); // result _writer.Write("ruleId", diagnostic.Id); int ruleIndex = _descriptors.Add(diagnostic.Descriptor); _writer.Write("ruleIndex", ruleIndex); _writer.Write("level", GetLevel(diagnostic.Severity)); string?message = diagnostic.GetMessage(_culture); if (!RoslynString.IsNullOrEmpty(message)) { _writer.WriteObjectStart("message"); _writer.Write("text", message); _writer.WriteObjectEnd(); } if (diagnostic.IsSuppressed) { _writer.WriteArrayStart("suppressions"); _writer.WriteObjectStart(); // suppression _writer.Write("kind", "inSource"); string?justification = suppressionInfo?.Attribute?.DecodeNamedArgument <string>( "Justification", SpecialType.System_String ); if (justification != null) { _writer.Write("justification", justification); } _writer.WriteObjectEnd(); // suppression _writer.WriteArrayEnd(); } WriteLocations(diagnostic.Location, diagnostic.AdditionalLocations); WriteResultProperties(diagnostic); _writer.WriteObjectEnd(); // result }
/// <summary> /// Gets a value indicating whether the project of the compilation is a Web SDK project based on project properties. /// </summary> internal static bool IsWebProject(this Compilation compilation, AnalyzerOptions options) { var propertyValue = options.GetMSBuildPropertyValue(MSBuildPropertyOptionNames.UsingMicrosoftNETSdkWeb, compilation); if (string.Equals(propertyValue?.Trim(), "true", StringComparison.OrdinalIgnoreCase)) { return(true); } propertyValue = options.GetMSBuildPropertyValue(MSBuildPropertyOptionNames.ProjectTypeGuids, compilation); if (!RoslynString.IsNullOrEmpty(propertyValue) && (propertyValue.Contains(WebAppProjectGuidString, StringComparison.OrdinalIgnoreCase) || propertyValue.Contains(WebSiteProjectGuidString, StringComparison.OrdinalIgnoreCase))) { var guids = propertyValue.Split(';').Select(g => g.Trim()).ToImmutableArray(); return(guids.Contains(WebAppProjectGuidString, StringComparer.OrdinalIgnoreCase) || guids.Contains(WebSiteProjectGuidString, StringComparer.OrdinalIgnoreCase)); } return(false); }
protected sealed override async ValueTask <IChecksummedPersistentStorage?> TryOpenDatabaseAsync( SolutionKey solutionKey, string workingFolderPath, string databaseFilePath, CancellationToken cancellationToken) { var solutionFolder = IOUtilities.PerformIO(() => Path.GetDirectoryName(solutionKey.FilePath)); if (RoslynString.IsNullOrEmpty(solutionFolder)) { return(null); } var cacheService = await this.CreateCacheServiceAsync(solutionFolder, cancellationToken).ConfigureAwait(false); var relativePathBase = await cacheService.GetRelativePathBaseAsync(cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(relativePathBase)) { return(null); } return(new CloudCachePersistentStorage(cacheService, solutionKey, workingFolderPath, relativePathBase, databaseFilePath)); }
internal static bool ContainsDroppedIdentifierCharacters(string?name) { if (RoslynString.IsNullOrEmpty(name)) { return(false); } if (name[0] == '@') { return(true); } int nameLength = name.Length; for (int i = 0; i < nameLength; i++) { if (UnicodeCharacterUtilities.IsFormattingChar(name[i])) { return(true); } } return(false); }
internal static async Task <SyntaxNode> GetTransformedSyntaxRootAsync(ISyntaxFacts syntaxFacts, AbstractFileHeaderHelper fileHeaderHelper, SyntaxTrivia newLineTrivia, Document document, string?fileHeaderTemplate, CancellationToken cancellationToken) { var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); // If we weren't given a header lets get the one from editorconfig if (fileHeaderTemplate is null && !document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(tree).TryGetEditorConfigOption(CodeStyleOptions2.FileHeaderTemplate, out fileHeaderTemplate)) { // No header supplied, no editorconfig setting, nothing to do return(root); } if (RoslynString.IsNullOrEmpty(fileHeaderTemplate)) { // Header template is empty, nothing to do. This shouldn't be possible if this method is called in // reaction to a diagnostic, but this method is also used when creating new documents so lets be defensive. return(root); } var expectedFileHeader = fileHeaderTemplate.Replace("{fileName}", Path.GetFileName(document.FilePath)); var fileHeader = fileHeaderHelper.ParseFileHeader(root); SyntaxNode newSyntaxRoot; if (fileHeader.IsMissing) { newSyntaxRoot = AddHeader(syntaxFacts, fileHeaderHelper, newLineTrivia, root, expectedFileHeader); } else { newSyntaxRoot = ReplaceHeader(syntaxFacts, fileHeaderHelper, newLineTrivia, root, expectedFileHeader); } return(newSyntaxRoot); }
internal ITextBuffer GetOrCreateBufferForPath(string?filePath, IContentType contentType, string languageName, string initialText) { // If we don't have a file path we'll just make something up for the purpose of this dictionary so all // buffers are still held onto. This isn't a file name used in the workspace itself so it's unobservable. if (RoslynString.IsNullOrEmpty(filePath)) { filePath = Guid.NewGuid().ToString(); } return(_createdTextBuffers.GetOrAdd(filePath, _ => { var textBuffer = EditorFactory.CreateBuffer(ExportProvider, contentType, initialText); // Ensure that the editor options on the text buffer matches that of the options that can be directly set in the workspace var editorOptions = ExportProvider.GetExportedValue <IEditorOptionsFactoryService>().GetOptions(textBuffer); var workspaceOptions = this.Options; editorOptions.SetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId, !workspaceOptions.GetOption(FormattingOptions.UseTabs, languageName)); editorOptions.SetOptionValue(DefaultOptions.TabSizeOptionId, workspaceOptions.GetOption(FormattingOptions.TabSize, languageName)); editorOptions.SetOptionValue(DefaultOptions.IndentSizeOptionId, workspaceOptions.GetOption(FormattingOptions.IndentationSize, languageName)); return textBuffer; })); }
public bool Execute(GeneratorExecutionContext context) { Lang language; switch (Language) { case LanguageNames.CSharp: language = Lang.CSharp; break; case LanguageNames.VisualBasic: language = Lang.VisualBasic; break; default: LogError(Lang.CSharp, $"GenerateResxSource doesn't support language: '{Language}'"); return(false); } var extension = language switch { Lang.CSharp => "cs", Lang.VisualBasic => "vb", _ => "cs", }; OutputTextHintName = ResourceName + $".Designer.{extension}"; if (string.IsNullOrEmpty(ResourceName)) { LogError(language, "ResourceName not specified"); return(false); } var resourceAccessName = RoslynString.IsNullOrEmpty(ResourceClassName) ? ResourceName : ResourceClassName; SplitName(resourceAccessName, out var namespaceName, out var className); var classIndent = namespaceName == null ? "" : " "; var memberIndent = classIndent + " "; var text = ResourceFile.GetText(context.CancellationToken); if (text is null) { LogError(language, "ResourceFile was null"); return(false); } var strings = new StringBuilder(); foreach (var node in XDocument.Parse(text.ToString()).Descendants("data")) { var name = node.Attribute("name")?.Value; if (name == null) { LogError(language, "Missing resource name"); return(false); } var value = node.Elements("value").FirstOrDefault()?.Value.Trim(); if (value == null) { LogError(language, $"Missing resource value: '{name}'"); return(false); } if (name.Length == 0) { LogError(language, $"Empty resource name"); return(false); } var docCommentString = value.Length > maxDocCommentLength?value.Substring(0, maxDocCommentLength) + " ..." : value; RenderDocComment(language, memberIndent, strings, docCommentString); var identifier = GetIdentifierFromResourceName(name); var defaultValue = IncludeDefaultValues ? ", " + CreateStringLiteral(value, language) : string.Empty; switch (language) { case Lang.CSharp: if (AsConstants) { strings.AppendLine($"{memberIndent}internal const string @{identifier} = \"{name}\";"); } else { strings.AppendLine($"{memberIndent}internal static {(IncludeDefaultValues || !Generator.SupportsNullable(context) ? "string" : "string?")} @{identifier} => GetResourceString(\"{name}\"{defaultValue});"); } if (EmitFormatMethods) { var resourceString = new ResourceString(name, value); if (resourceString.HasArguments) { RenderDocComment(language, memberIndent, strings, docCommentString); RenderFormatMethod(memberIndent, language, strings, resourceString); } } break; case Lang.VisualBasic: if (AsConstants) { strings.AppendLine($"{memberIndent}Friend Const [{identifier}] As String = \"{name}\""); } else { strings.AppendLine($"{memberIndent}Friend Shared ReadOnly Property [{identifier}] As String"); strings.AppendLine($"{memberIndent} Get"); strings.AppendLine($"{memberIndent} Return GetResourceString(\"{name}\"{defaultValue})"); strings.AppendLine($"{memberIndent} End Get"); strings.AppendLine($"{memberIndent}End Property"); } if (EmitFormatMethods) { throw new NotImplementedException(); } break; default: throw new InvalidOperationException(); } } INamedTypeSymbol?methodImplOptions = context.Compilation.GetOrCreateTypeByMetadataName(typeof(MethodImplOptions).FullName); var hasAggressiveInlining = methodImplOptions?.MemberNames.Contains(nameof(MethodImplOptions.AggressiveInlining)) ?? false; var hasNotNullIfNotNull = context.Compilation.GetOrCreateTypeByMetadataName("System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute") is object; string?getStringMethod; if (OmitGetResourceString) { getStringMethod = null; } else { switch (language) { case Lang.CSharp: var getResourceStringAttributes = new List <string>(); if (hasAggressiveInlining) { getResourceStringAttributes.Add("[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]"); } if (hasNotNullIfNotNull) { getResourceStringAttributes.Add("[return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull(\"defaultValue\")]"); } getStringMethod = $@"{memberIndent}internal static global::System.Globalization.CultureInfo{(Generator.SupportsNullable(context) ? "?" : "")} Culture {{ get; set; }} {string.Join(Environment.NewLine, getResourceStringAttributes.Select(attr => memberIndent + attr))} {memberIndent}internal static {(Generator.SupportsNullable(context) ? "string?" : "string")} GetResourceString(string resourceKey, {(Generator.SupportsNullable(context) ? "string?" : "string")} defaultValue = null) => ResourceManager.GetString(resourceKey, Culture) ?? defaultValue;"; if (EmitFormatMethods) { getStringMethod += $@" {memberIndent}private static string GetResourceString(string resourceKey, string[]? formatterNames) {memberIndent}{{ {memberIndent} var value = GetResourceString(resourceKey) ?? """"; {memberIndent} if (formatterNames != null) {memberIndent} {{ {memberIndent} for (var i = 0; i < formatterNames.Length; i++) {memberIndent} {{ {memberIndent} value = value.Replace(""{{"" + formatterNames[i] + ""}}"", ""{{"" + i + ""}}""); {memberIndent} }} {memberIndent} }} {memberIndent} return value; {memberIndent}}} "; } break; case Lang.VisualBasic: getStringMethod = $@"{memberIndent}Friend Shared Property Culture As Global.System.Globalization.CultureInfo {memberIndent}<Global.System.Runtime.CompilerServices.MethodImpl(Global.System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)> {memberIndent}Friend Shared Function GetResourceString(ByVal resourceKey As String, Optional ByVal defaultValue As String = Nothing) As String {memberIndent} Return ResourceManager.GetString(resourceKey, Culture) {memberIndent}End Function"; if (EmitFormatMethods) { throw new NotImplementedException(); } break; default: throw new InvalidOperationException(); } } string?namespaceStart, namespaceEnd; if (namespaceName == null) { namespaceStart = namespaceEnd = null; } else { switch (language) { case Lang.CSharp: namespaceStart = $@"namespace {namespaceName}{Environment.NewLine}{{"; namespaceEnd = "}"; break; case Lang.VisualBasic: namespaceStart = $"Namespace Global.{namespaceName}"; namespaceEnd = "End Namespace"; break; default: throw new InvalidOperationException(); } } string resourceTypeName; string?resourceTypeDefinition; if (string.IsNullOrEmpty(ResourceClassName) || ResourceName == ResourceClassName) { // resource name is same as accessor, no need for a second type. resourceTypeName = className; resourceTypeDefinition = null; } else { // resource name differs from the access class, need a type for specifying the resources // this empty type must remain as it is required by the .NETNative toolchain for locating resources // once assemblies have been merged into the application resourceTypeName = ResourceName; SplitName(resourceTypeName, out var resourceNamespaceName, out var resourceClassName); var resourceClassIndent = resourceNamespaceName == null ? "" : " "; switch (language) { case Lang.CSharp: resourceTypeDefinition = $"{resourceClassIndent}internal static class {resourceClassName} {{ }}"; if (resourceNamespaceName != null) { resourceTypeDefinition = $@"namespace {resourceNamespaceName} {{ {resourceTypeDefinition} }}"; } break; case Lang.VisualBasic: resourceTypeDefinition = $@"{resourceClassIndent}Friend Class {resourceClassName} {resourceClassIndent}End Class"; if (resourceNamespaceName != null) { resourceTypeDefinition = $@"Namespace {resourceNamespaceName} {resourceTypeDefinition} End Namespace"; } break; default: throw new InvalidOperationException(); } } // The ResourceManager property being initialized lazily is an important optimization that lets .NETNative // completely remove the ResourceManager class if the disk space saving optimization to strip resources // (/DisableExceptionMessages) is turned on in the compiler. string result; switch (language) { case Lang.CSharp: result = $@"// <auto-generated/> {(Generator.SupportsNullable(context) ? "#nullable enable" : "")} using System.Reflection; {resourceTypeDefinition} {namespaceStart} {classIndent}internal static partial class {className} {classIndent}{{ {memberIndent}private static global::System.Resources.ResourceManager{(Generator.SupportsNullable(context) ? "?" : "")} s_resourceManager; {memberIndent}internal static global::System.Resources.ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new global::System.Resources.ResourceManager(typeof({resourceTypeName}))); {getStringMethod} {strings} {classIndent}}} {namespaceEnd} "; break; case Lang.VisualBasic: result = $@"' <auto-generated/> Imports System.Reflection {resourceTypeDefinition} {namespaceStart} {classIndent}Friend Partial Class {className} {memberIndent}Private Sub New {memberIndent}End Sub {memberIndent} {memberIndent}Private Shared s_resourceManager As Global.System.Resources.ResourceManager {memberIndent}Friend Shared ReadOnly Property ResourceManager As Global.System.Resources.ResourceManager {memberIndent} Get {memberIndent} If s_resourceManager Is Nothing Then {memberIndent} s_resourceManager = New Global.System.Resources.ResourceManager(GetType({resourceTypeName})) {memberIndent} End If {memberIndent} Return s_resourceManager {memberIndent} End Get {memberIndent}End Property {getStringMethod} {strings} {classIndent}End Class {namespaceEnd} "; break; default: throw new InvalidOperationException(); } OutputText = SourceText.From(result, Encoding.UTF8, SourceHashAlgorithm.Sha256); return(true); }
private static bool IsDocumentLinked(MSB.Framework.ITaskItem documentItem) => !RoslynString.IsNullOrEmpty(documentItem.GetMetadata(MetadataNames.Link));
protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) { if (ProvideCommandLineArgs) { CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands) .Select(arg => new TaskItem(arg)).ToArray(); } if (SkipCompilerExecution) { return(0); } try { using var logger = new CompilerServerLogger(); string workingDir = CurrentDirectoryToUse(); string?tempDir = BuildServerConnection.GetTempPath(workingDir); if (!UseSharedCompilation || HasToolBeenOverridden || !BuildServerConnection.IsCompilerServerSupported) { LogCompilationMessage(logger, CompilationKind.Tool, $"using command line tool by design '{pathToTool}'"); return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } _sharedCompileCts = new CancellationTokenSource(); logger.Log($"CommandLine = '{commandLineCommands}'"); logger.Log($"BuildResponseFile = '{responseFileCommands}'"); var clientDir = Path.GetDirectoryName(PathToManagedTool); if (clientDir is null || tempDir is null) { LogCompilationMessage(logger, CompilationKind.Tool, $"using command line tool because we could not find client directory '{PathToManagedTool}'"); return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } var buildPaths = new BuildPathsAlt( clientDir: clientDir, workingDir: workingDir, // MSBuild doesn't need the .NET SDK directory sdkDir: null, tempDir: tempDir); // Note: using ToolArguments here (the property) since // commandLineCommands (the parameter) may have been mucked with // (to support using the dotnet cli) var responseTask = BuildServerConnection.RunServerCompilationAsync( Language, RoslynString.IsNullOrEmpty(SharedCompilationId) ? null : SharedCompilationId, GetArguments(ToolArguments, responseFileCommands).ToList(), buildPaths, keepAlive: null, libEnvVariable: LibDirectoryToUse(), logger: logger, cancellationToken: _sharedCompileCts.Token); responseTask.Wait(_sharedCompileCts.Token); ExitCode = HandleResponse(responseTask.Result, pathToTool, responseFileCommands, commandLineCommands, logger); } catch (OperationCanceledException) { ExitCode = 0; } catch (Exception e) { var util = new TaskLoggingHelper(this); util.LogErrorWithCodeFromResources("Compiler_UnexpectedException"); util.LogErrorFromException(e, showStackTrace: true, showDetail: true, file: null); ExitCode = -1; } finally { _sharedCompileCts?.Dispose(); _sharedCompileCts = null; } return(ExitCode); }
protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) { if (ProvideCommandLineArgs) { CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands) .Select(arg => new TaskItem(arg)).ToArray(); } if (SkipCompilerExecution) { return(0); } try { string workingDir = CurrentDirectoryToUse(); string?tempDir = BuildServerConnection.GetTempPath(workingDir); if (!UseSharedCompilation || HasToolBeenOverridden || !BuildServerConnection.IsCompilerServerSupported) { return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } using var logger = new CompilerServerLogger(); using (_sharedCompileCts = new CancellationTokenSource()) { logger.Log($"CommandLine = '{commandLineCommands}'"); logger.Log($"BuildResponseFile = '{responseFileCommands}'"); var clientDir = Path.GetDirectoryName(PathToManagedTool); if (clientDir is null || tempDir is null) { return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } // Note: we can't change the "tool path" printed to the console when we run // the Csc/Vbc task since MSBuild logs it for us before we get here. Instead, // we'll just print our own message that contains the real client location Log.LogMessage(ErrorString.UsingSharedCompilation, clientDir); var buildPaths = new BuildPathsAlt( clientDir: clientDir, workingDir: workingDir, // MSBuild doesn't need the .NET SDK directory sdkDir: null, tempDir: tempDir); // Note: using ToolArguments here (the property) since // commandLineCommands (the parameter) may have been mucked with // (to support using the dotnet cli) var responseTask = BuildServerConnection.RunServerCompilationAsync( Language, RoslynString.IsNullOrEmpty(SharedCompilationId) ? null : SharedCompilationId, GetArguments(ToolArguments, responseFileCommands).ToList(), buildPaths, keepAlive: null, libEnvVariable: LibDirectoryToUse(), logger: logger, cancellationToken: _sharedCompileCts.Token); responseTask.Wait(_sharedCompileCts.Token); var response = responseTask.Result; if (response != null) { ExitCode = HandleResponse(response, pathToTool, responseFileCommands, commandLineCommands, logger); } else { logger.LogError($"Server compilation failed, falling back to {pathToTool}"); Log.LogMessage(ErrorString.SharedCompilationFallback, pathToTool); ExitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); } } } catch (OperationCanceledException) { ExitCode = 0; } catch (Exception e) { var util = new TaskLoggingHelper(this); util.LogErrorWithCodeFromResources("Compiler_UnexpectedException"); util.LogErrorFromException(e, showStackTrace: true, showDetail: true, file: null); ExitCode = -1; } return(ExitCode); }