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)); } }
protected void AddIfNotNullOrWhiteSpace(string name, string?value) { if (!RoslynString.IsNullOrWhiteSpace(value)) { Add(name, value); } }
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 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); } } } }
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); }
public static void AppendToAliasNameSet( this string?alias, ImmutableHashSet <string> .Builder builder ) { if (RoslynString.IsNullOrWhiteSpace(alias)) { return; } builder.Add(alias); var caseSensitive = builder.KeyComparer == StringComparer.Ordinal; Debug.Assert( builder.KeyComparer == StringComparer.Ordinal || builder.KeyComparer == StringComparer.OrdinalIgnoreCase ); if (alias.TryGetWithoutAttributeSuffix(caseSensitive, out var aliasWithoutAttribute)) { builder.Add(aliasWithoutAttribute); return; } builder.Add(alias.GetWithSingleAttributeSuffix(caseSensitive)); }
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 } }
protected void AddIfNotNullOrWhiteSpace(string name, string?value, bool addQuoteIfValueContainsWhitespace = true) { if (!RoslynString.IsNullOrWhiteSpace(value)) { Add(name, value, addQuoteIfValueContainsWhitespace); } }
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)); } }
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 }
private ProjectFileInfo CreateProjectFileInfo(MSB.Execution.ProjectInstance project) { var commandLineArgs = GetCommandLineArgs(project); var outputFilePath = project.ReadPropertyString(PropertyNames.TargetPath); if (!RoslynString.IsNullOrWhiteSpace(outputFilePath)) { outputFilePath = GetAbsolutePathRelativeToProject(outputFilePath); } var outputRefFilePath = project.ReadPropertyString(PropertyNames.TargetRefPath); if (!RoslynString.IsNullOrWhiteSpace(outputRefFilePath)) { outputRefFilePath = GetAbsolutePathRelativeToProject(outputRefFilePath); } // Right now VB doesn't have the concept of "default namespace". But we conjure one in workspace // by assigning the value of the project's root namespace to it. So various feature can choose to // use it for their own purpose. // In the future, we might consider officially exposing "default namespace" for VB project // (e.g. through a <defaultnamespace> msbuild property) var defaultNamespace = project.ReadPropertyString(PropertyNames.RootNamespace) ?? string.Empty; var targetFramework = project.ReadPropertyString(PropertyNames.TargetFramework); if (RoslynString.IsNullOrWhiteSpace(targetFramework)) { targetFramework = null; } var docs = project.GetDocuments() .Where(IsNotTemporaryGeneratedFile) .Select(MakeDocumentFileInfo) .ToImmutableArray(); var additionalDocs = project.GetAdditionalFiles() .Select(MakeNonSourceFileDocumentFileInfo) .ToImmutableArray(); var analyzerConfigDocs = project.GetEditorConfigFiles() .Select(MakeNonSourceFileDocumentFileInfo) .ToImmutableArray(); return(ProjectFileInfo.Create( Language, project.FullPath, outputFilePath, outputRefFilePath, defaultNamespace, targetFramework, commandLineArgs, docs, additionalDocs, analyzerConfigDocs, project.GetProjectReferences().ToImmutableArray(), Log)); }
protected void ReadErrorReport() { var errorReport = Project.ReadPropertyString(PropertyNames.ErrorReport); if (!RoslynString.IsNullOrWhiteSpace(errorReport)) { Add("errorreport", errorReport.ToLower()); } }
protected void ReadDelaySign() { var delaySign = Project.ReadPropertyString(PropertyNames.DelaySign); if (!RoslynString.IsNullOrWhiteSpace(delaySign)) { AddWithPlusOrMinus("delaysign", Conversions.ToBool(delaySign)); } }
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)); } }
private static string GetMSBuildFailedMessage(string projectFilePath, string message) => RoslynString.IsNullOrWhiteSpace(message) ? string.Format( WorkspaceMSBuildResources.Msbuild_failed_when_processing_the_file_0, projectFilePath ) : string.Format( WorkspaceMSBuildResources.Msbuild_failed_when_processing_the_file_0_with_message_1, projectFilePath, message );
protected void ReadFeatures() { var features = Project.ReadPropertyString(PropertyNames.Features); if (!RoslynString.IsNullOrWhiteSpace(features)) { foreach (var feature in CompilerOptionParseUtilities.ParseFeatureFromMSBuild(features)) { Add("features", feature); } } }
/// <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 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 Add(string name, string?value) { ValidateName(name); if (RoslynString.IsNullOrEmpty(value) || value.Contains(char.IsWhiteSpace)) { _builder.Add($"/{name}:\"{value}\""); } else { _builder.Add($"/{name}:{value}"); } }
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 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 void DiffRules( string oldRulesJsonPath, string newRulesJsonPath, string outputPath, string?latestRulesJsonPath = null) { RuleFileContent oldContent = ReadRuleFileContent(oldRulesJsonPath); RuleFileContent newContent = ReadRuleFileContent(newRulesJsonPath); // If we have the latest rules, we can backfill missing help link URLs. if (!RoslynString.IsNullOrWhiteSpace(latestRulesJsonPath)) { RuleFileContent latestContent = ReadRuleFileContent(latestRulesJsonPath); Dictionary <string, RuleInfo> latestRulesById = latestContent.Rules.ToDictionary(r => r.Id); foreach (RuleInfo rule in oldContent.Rules.Concat(newContent.Rules)) { if (RoslynString.IsNullOrWhiteSpace(rule.HelpLink) && latestRulesById.TryGetValue(rule.Id, out RuleInfo latestRule)) { rule.HelpLink = latestRule.HelpLink; } } } Dictionary <string, RuleInfo> oldRulesById = oldContent.Rules.ToDictionary(r => r.Id); Dictionary <string, RuleInfo> newRulesById = newContent.Rules.ToDictionary(r => r.Id); IEnumerable <RuleInfo> addedRules = newContent.Rules .Where(r => !oldRulesById.ContainsKey(r.Id)); IEnumerable <RuleInfo> removedRules = oldContent.Rules .Where(r => !newRulesById.ContainsKey(r.Id)); IEnumerable <RuleInfo> changedRules = newContent.Rules .Where(r => oldRulesById.TryGetValue(r.Id, out RuleInfo oldRule) && r.IsEnabledByDefault != oldRule.IsEnabledByDefault); StringBuilder sb = new StringBuilder(); GenerateAddRemovedRulesDiffMarkdown(sb, "### Added", addedRules); GenerateAddRemovedRulesDiffMarkdown(sb, "### Removed", removedRules); GenerateChangedRulesDiffMarkdown(sb, "### Changed", changedRules); File.WriteAllText(outputPath, sb.ToString()); }
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 }
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); } } }
private void ReadDoc() { var documentationFile = Project.ReadPropertyString(PropertyNames.DocFileItem); var generateDocumentation = Project.ReadPropertyBool(PropertyNames.GenerateDocumentation); var hasDocumentationFile = !RoslynString.IsNullOrWhiteSpace(documentationFile); if (hasDocumentationFile || generateDocumentation) { if (!RoslynString.IsNullOrWhiteSpace(documentationFile)) { Add("doc", documentationFile); } else { Add("doc"); } } }
/// <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)); }