| File: RuleSet\RuleSetInclude.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// 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.IO; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis { /// <summary> /// Represents a Include tag in a RuleSet file. /// </summary> public class RuleSetInclude { private readonly string _includePath; /// <summary> /// The path of the included file. /// </summary> public string IncludePath { get { return _includePath; } } private readonly ReportDiagnostic _action; /// <summary> /// The effective action to apply on this included ruleset. /// </summary> public ReportDiagnostic Action { get { return _action; } } /// <summary> /// Create a RuleSetInclude given the include path and the effective action. /// </summary> public RuleSetInclude(string includePath, ReportDiagnostic action) { _includePath = includePath; _action = action; } /// <summary> /// Gets the RuleSet associated with this ruleset include /// </summary> /// <param name="parent">The parent of this ruleset include</param> public RuleSet? LoadRuleSet(RuleSet parent) { // Try to load the rule set RuleSet? ruleSet = null; string? path = _includePath; try { path = GetIncludePath(parent); if (path == null) { return null; } ruleSet = RuleSetProcessor.LoadFromFile(path); } catch (FileNotFoundException) { // The compiler uses the same rule set files as FxCop, but doesn't have all of // the same logic for resolving included files. For the moment, just ignore any // includes we can't resolve. } catch (Exception e) { throw new InvalidRuleSetException(string.Format(CodeAnalysisResources.InvalidRuleSetInclude, path, e.Message)); } return ruleSet; } /// <summary> /// Returns a full path to the include file. Relative paths are expanded relative to the current rule set file. /// </summary> /// <param name="parent">The parent of this rule set include</param> private string? GetIncludePath(RuleSet parent) { var resolvedIncludePath = resolveIncludePath(_includePath, parent?.FilePath); if (resolvedIncludePath == null) { return null; } // Return the canonical full path return Path.GetFullPath(resolvedIncludePath); static string? resolveIncludePath(string includePath, string? parentRulesetPath) { var resolvedIncludePath = resolveIncludePathCore(includePath, parentRulesetPath); if (resolvedIncludePath == null && PathUtilities.IsUnixLikePlatform) { // Attempt to resolve legacy ruleset includes after replacing Windows style directory separator char with current plaform's directory separator char. includePath = includePath.Replace('\\', Path.DirectorySeparatorChar); resolvedIncludePath = resolveIncludePathCore(includePath, parentRulesetPath); } return resolvedIncludePath; } static string? resolveIncludePathCore(string includePath, string? parentRulesetPath) { includePath = Environment.ExpandEnvironmentVariables(includePath); // If a full path is specified then use it if (Path.IsPathRooted(includePath)) { if (File.Exists(includePath)) { return includePath; } } else if (!string.IsNullOrEmpty(parentRulesetPath)) { // Otherwise, try to find the include file relative to the parent ruleset. includePath = PathUtilities.CombinePathsUnchecked(Path.GetDirectoryName(parentRulesetPath) ?? "", includePath); if (File.Exists(includePath)) { return includePath; } } return null; } } } }