提交 1d3d41d7 编写于 作者: M Matt Warren

better file path comparisons

上级 7f38544a
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace Roslyn.Utilities
{
......@@ -15,17 +17,24 @@ internal static class PathUtilities
// On Windows both / and \ are equally accepted.
internal static readonly char DirectorySeparatorChar = PlatformInformation.IsUnix ? '/' : '\\';
internal static readonly char AltDirectorySeparatorChar = '/';
internal static readonly string ParentRelativeDirectory = "..";
internal static readonly string ThisDirectory = ".";
internal static readonly string DirectorySeparatorStr = new string(DirectorySeparatorChar, 1);
internal const char VolumeSeparatorChar = ':';
internal static bool IsUnixLikePlatform => PlatformInformation.IsUnix;
internal static bool IsDirectorySeparator(char c)
/// <summary>
/// True if the character is a directory separator character.
/// </summary>
public static bool IsDirectorySeparator(char c)
{
return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar;
}
internal static string TrimTrailingSeparators(string s)
/// <summary>
/// Removes trailing directory separator characters
/// </summary>
public static string TrimTrailingSeparators(string s)
{
int lastSeparator = s.Length;
while (lastSeparator > 0 && IsDirectorySeparator(s[lastSeparator - 1]))
......@@ -41,22 +50,22 @@ internal static string TrimTrailingSeparators(string s)
return s;
}
internal static string GetExtension(string path)
public static string GetExtension(string path)
{
return FileNameUtilities.GetExtension(path);
}
internal static string ChangeExtension(string path, string extension)
public static string ChangeExtension(string path, string extension)
{
return FileNameUtilities.ChangeExtension(path, extension);
}
internal static string RemoveExtension(string path)
public static string RemoveExtension(string path)
{
return FileNameUtilities.ChangeExtension(path, extension: null);
}
internal static string GetFileName(string path, bool includeExtension = true)
public static string GetFileName(string path, bool includeExtension = true)
{
return FileNameUtilities.GetFileName(path, includeExtension);
}
......@@ -65,18 +74,15 @@ internal static string GetFileName(string path, bool includeExtension = true)
/// Get directory name from path.
/// </summary>
/// <remarks>
/// Unlike <see cref="System.IO.Path.GetDirectoryName"/> it
/// doesn't check for invalid path characters,
/// Unlike <see cref="System.IO.Path.GetDirectoryName"/> it doesn't check for invalid path characters
/// </remarks>
/// <returns>Prefix of path that represents a directory. </returns>
internal static string GetDirectoryName(string path)
/// <returns>Prefix of path that represents a directory</returns>
public static string GetDirectoryName(string path)
{
return GetDirectoryName(path, IsUnixLikePlatform);
}
/// <summary>
/// Exposed for testing purposes only.
/// </summary>
// Exposed for testing purposes only.
internal static string GetDirectoryName(string path, bool isUnixLike)
{
if (path != null)
......@@ -125,6 +131,9 @@ internal static bool IsSameDirectoryOrChildOf(string child, string parent)
return false;
}
/// <summary>
/// Gets the root part of the path.
/// </summary>
public static string GetPathRoot(string path)
{
return GetPathRoot(path, IsUnixLikePlatform);
......@@ -230,7 +239,10 @@ private static string GetUnixRoot(string path)
: "";
}
internal static PathKind GetPathKind(string path)
/// <summary>
/// Gets the specific kind of relative or absolute path.
/// </summary>
public static PathKind GetPathKind(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
......@@ -286,7 +298,10 @@ internal static PathKind GetPathKind(string path)
return PathKind.Relative;
}
internal static bool IsAbsolute(string path)
/// <summary>
/// True if the path is an absolute path (rooted to drive or network share)
/// </summary>
public static bool IsAbsolute(string path)
{
if (string.IsNullOrEmpty(path))
{
......@@ -333,7 +348,7 @@ private static bool IsDriveRootedAbsolutePath(string path)
/// or relative to a drive directory (e.g. "C:abc\def").
/// </returns>
/// <seealso cref="CombinePossiblyRelativeAndRelativePaths"/>
internal static string CombineAbsoluteAndRelativePaths(string root, string relativePath)
public static string CombineAbsoluteAndRelativePaths(string root, string relativePath)
{
Debug.Assert(IsAbsolute(root));
......@@ -347,7 +362,7 @@ internal static string CombineAbsoluteAndRelativePaths(string root, string relat
/// <param name="relativePath">Second path: relative and non-null.</param>
/// <returns>null, if <paramref name="rootOpt"/> is null; a combined path, otherwise.</returns>
/// <seealso cref="CombineAbsoluteAndRelativePaths"/>
internal static string CombinePossiblyRelativeAndRelativePaths(string rootOpt, string relativePath)
public static string CombinePossiblyRelativeAndRelativePaths(string rootOpt, string relativePath)
{
if (string.IsNullOrEmpty(rootOpt))
{
......@@ -368,7 +383,7 @@ internal static string CombinePossiblyRelativeAndRelativePaths(string rootOpt, s
return CombinePathsUnchecked(rootOpt, relativePath);
}
internal static string CombinePathsUnchecked(string root, string relativePath)
public static string CombinePathsUnchecked(string root, string relativePath)
{
Debug.Assert(!string.IsNullOrEmpty(root));
......@@ -381,7 +396,7 @@ internal static string CombinePathsUnchecked(string root, string relativePath)
return root + relativePath;
}
internal static string RemoveTrailingDirectorySeparator(string path)
private static string RemoveTrailingDirectorySeparator(string path)
{
if (path.Length > 0 && IsDirectorySeparator(path[path.Length - 1]))
{
......@@ -397,7 +412,7 @@ internal static string RemoveTrailingDirectorySeparator(string path)
/// Determines whether an assembly reference is considered an assembly file path or an assembly name.
/// used, for example, on values of /r and #r.
/// </summary>
internal static bool IsFilePath(string assemblyDisplayNameOrPath)
public static bool IsFilePath(string assemblyDisplayNameOrPath)
{
Debug.Assert(assemblyDisplayNameOrPath != null);
......@@ -419,7 +434,7 @@ internal static bool IsFilePath(string assemblyDisplayNameOrPath)
/// not have "foo" as a component. That's because here "foo" is the server name portion
/// of the UNC path, and not an actual directory or file name.
/// </summary>
internal static bool ContainsPathComponent(string path, string component, bool ignoreCase)
public static bool ContainsPathComponent(string path, string component, bool ignoreCase)
{
var comparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
if (path?.IndexOf(component, comparison) >= 0)
......@@ -443,5 +458,182 @@ internal static bool ContainsPathComponent(string path, string component, bool i
return false;
}
/// <summary>
/// Gets a path relative to a directory.
/// </summary>
public static string GetRelativePath(string directory, string fullPath)
{
string relativePath = string.Empty;
if (IsChildPath(directory, fullPath))
{
return GetRelativeChildPath(directory, fullPath);
}
var directoryPathParts = GetPathParts(directory);
var fullPathParts = GetPathParts(fullPath);
if (directoryPathParts.Length == 0 || fullPathParts.Length == 0)
{
return fullPath;
}
int index = 0;
// find index where full path diverges from base path
for (; index < directoryPathParts.Length; index++)
{
if (!PathsEqual(directoryPathParts[index], fullPathParts[index]))
{
break;
}
}
// if the first part doesn't match, they don't even have the same volume
// so there can be no relative path.
if (index == 0)
{
return fullPath;
}
// add backup notation for remaining base path levels beyond the index
var remainingParts = directoryPathParts.Length - index;
if (remainingParts > 0)
{
for (int i = 0; i < remainingParts; i++)
{
relativePath = relativePath + ParentRelativeDirectory + DirectorySeparatorStr;
}
}
// add the rest of the full path parts
for (int i = index; i < fullPathParts.Length; i++)
{
relativePath = CombinePathsUnchecked(relativePath, fullPathParts[i]);
}
return relativePath;
}
/// <summary>
/// True if the child path is a child of the parent path.
/// </summary>
public static bool IsChildPath(string parentPath, string childPath)
{
return parentPath.Length > 0
&& childPath.Length > parentPath.Length
&& PathsEqual(childPath, parentPath, parentPath.Length)
&& (IsDirectorySeparator(parentPath[parentPath.Length - 1]) || IsDirectorySeparator(childPath[parentPath.Length]));
}
private static string GetRelativeChildPath(string parentPath, string childPath)
{
var relativePath = childPath.Substring(parentPath.Length);
// trim any leading separators left over after removing leading directory
int start = ConsumeDirectorySeparators(relativePath, relativePath.Length, 0);
if (start > 0)
{
relativePath = relativePath.Substring(start);
}
return relativePath;
}
private static readonly char[] s_pathChars = new char[] { VolumeSeparatorChar, DirectorySeparatorChar, AltDirectorySeparatorChar };
private static string[] GetPathParts(string path)
{
var pathParts = path.Split(s_pathChars);
// remove references to self directories ('.')
if (pathParts.Contains(ThisDirectory))
{
pathParts = pathParts.Where(s => s != ThisDirectory).ToArray();
}
return pathParts;
}
/// <summary>
/// True if the two paths are the same.
/// </summary>
public static bool PathsEqual(string path1, string path2)
{
return PathsEqual(path1, path2, Math.Max(path1.Length, path2.Length));
}
/// <summary>
/// True if the two paths are the same. (but only up to the specified length)
/// </summary>
private static bool PathsEqual(string path1, string path2, int length)
{
if (path1.Length < length || path2.Length < length)
{
return false;
}
for (int i = 0; i < length; i++)
{
if (!PathCharEqual(path1[i], path2[i]))
{
return false;
}
}
return true;
}
private static bool PathCharEqual(char x, char y)
{
return x == y
|| (IsDirectorySeparator(x) && IsDirectorySeparator(y))
|| IsUnixLikePlatform
|| char.ToUpperInvariant(x) == char.ToUpperInvariant(y);
}
private static int PathHashCode(string path)
{
int hc = 0;
if (path != null)
{
foreach (var ch in path)
{
if (!IsDirectorySeparator(ch))
{
hc = Hash.Combine((int)char.ToUpperInvariant(ch), hc);
}
}
}
return hc;
}
public static readonly IEqualityComparer<string> Comparer = new PathComparer();
private class PathComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
if (x == null && y == null)
{
return true;
}
if (x == null || y == null)
{
return false;
}
return PathsEqual(x, y);
}
public int GetHashCode(string s)
{
return PathHashCode(s);
}
}
}
}
......@@ -271,7 +271,7 @@ private static void UpdateCodeAnalysisRuleSetPropertyInConfiguration(EnvDTE.Conf
if (codeAnalysisRuleSetFullPath.Equals(oldRuleSetFilePath, StringComparison.OrdinalIgnoreCase))
{
string newRuleSetRelativePath = FilePathUtilities.GetRelativePath(projectDirectoryFullPath, newRuleSetFilePath);
string newRuleSetRelativePath = PathUtilities.GetRelativePath(projectDirectoryFullPath, newRuleSetFilePath);
codeAnalysisRuleSetFileProperty.Value = newRuleSetRelativePath;
}
}
......
......@@ -29,7 +29,7 @@ public bool Serializable(Solution solution, string assemblyFilePath)
public bool TryGetSerializationPrefixAndVersion(Solution solution, string assemblyFilePath, out string prefix, out VersionStamp version)
{
prefix = FilePathUtilities.GetRelativePath(solution.FilePath, assemblyFilePath);
prefix = PathUtilities.GetRelativePath(solution.FilePath, assemblyFilePath);
version = VersionStamp.Create(File.GetLastWriteTimeUtc(assemblyFilePath));
return true;
......
......@@ -202,7 +202,7 @@ protected string GetFileName(string original, string mapped)
private string Combine(string path1, string path2)
{
if (FilePathUtilities.TryCombine(path1, path2, out var result))
if (TryCombine(path1, path2, out var result))
{
return result;
}
......@@ -210,6 +210,21 @@ private string Combine(string path1, string path2)
return string.Empty;
}
public static bool TryCombine(string path1, string path2, out string result)
{
try
{
// don't throw exception when either path1 or path2 contains illegal path char
result = System.IO.Path.Combine(path1, path2);
return true;
}
catch
{
result = null;
return false;
}
}
// we don't use these
public object Identity(int index)
{
......
......@@ -489,7 +489,7 @@ private void SetActiveRuleSetHandler(object sender, EventArgs e)
_tracker.SelectedHierarchy.TryGetCanonicalName(_tracker.SelectedItemId, out var ruleSetFileFullPath))
{
string projectDirectoryFullPath = Path.GetDirectoryName(project.FullName);
string ruleSetFileRelativePath = FilePathUtilities.GetRelativePath(projectDirectoryFullPath, ruleSetFileFullPath);
string ruleSetFileRelativePath = PathUtilities.GetRelativePath(projectDirectoryFullPath, ruleSetFileFullPath);
UpdateProjectConfigurationsToUseRuleSetFile(project, ruleSetFileRelativePath);
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
namespace Roslyn.Utilities
{
internal static class FilePathUtilities
{
public static bool IsNestedPath(string basePath, string fullPath)
{
return basePath.Length > 0
&& fullPath.Length > basePath.Length
&& fullPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase)
&& (PathUtilities.IsDirectorySeparator(basePath[basePath.Length - 1]) || PathUtilities.IsDirectorySeparator(fullPath[basePath.Length]));
}
public static string GetNestedPath(string baseDirectory, string fullPath)
{
if (IsNestedPath(baseDirectory, fullPath))
{
var relativePath = fullPath.Substring(baseDirectory.Length);
while (relativePath.Length > 0 && PathUtilities.IsDirectorySeparator(relativePath[0]))
{
relativePath = relativePath.Substring(1);
}
return relativePath;
}
return fullPath;
}
private static readonly char[] s_pathChars = new char[] { Path.VolumeSeparatorChar, Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
public static string GetRelativePath(string baseDirectory, string fullPath)
{
string relativePath = string.Empty;
if (IsNestedPath(baseDirectory, fullPath))
{
return GetNestedPath(baseDirectory, fullPath);
}
var basePathParts = baseDirectory.Split(s_pathChars);
var fullPathParts = fullPath.Split(s_pathChars);
if (basePathParts.Length == 0 || fullPathParts.Length == 0)
{
return fullPath;
}
int index = 0;
// find index where full path diverges from base path
for (; index < basePathParts.Length; index++)
{
if (!PathsEqual(basePathParts[index], fullPathParts[index]))
{
break;
}
}
// if the first part doesn't match, they don't even have the same volume
// so there can be no relative path.
if (index == 0)
{
return fullPath;
}
// add backup notation for remaining base path levels beyond the index
var remainingParts = basePathParts.Length - index;
if (remainingParts > 0)
{
string directorySeparator = Path.DirectorySeparatorChar.ToString();
for (int i = 0; i < remainingParts; i++)
{
relativePath = relativePath + ".." + directorySeparator;
}
}
// add the rest of the full path parts
for (int i = index; i < fullPathParts.Length; i++)
{
relativePath = Path.Combine(relativePath, fullPathParts[i]);
}
return relativePath;
}
public static bool PathsEqual(string path1, string path2)
{
return string.Compare(path1, path2, StringComparison.OrdinalIgnoreCase) == 0;
}
public static bool TryCombine(string path1, string path2, out string result)
{
try
{
// don't throw exception when either path1 or path2 contains illegal path char
result = Path.Combine(path1, path2);
return true;
}
catch
{
result = null;
return false;
}
}
}
}
......@@ -94,8 +94,8 @@ public static ProjectInfo CreateProjectInfo(string projectName, string language,
? Path.GetFullPath(fileArg.Path)
: Path.GetFullPath(Path.Combine(projectDirectory, fileArg.Path));
var relativePath = FilePathUtilities.GetRelativePath(projectDirectory, absolutePath);
var isWithinProject = FilePathUtilities.IsNestedPath(projectDirectory, absolutePath);
var relativePath = PathUtilities.GetRelativePath(projectDirectory, absolutePath);
var isWithinProject = PathUtilities.IsChildPath(projectDirectory, absolutePath);
var folderRoot = isWithinProject ? Path.GetDirectoryName(relativePath) : "";
var folders = isWithinProject ? GetFolders(relativePath) : null;
......@@ -121,8 +121,8 @@ public static ProjectInfo CreateProjectInfo(string projectName, string language,
? Path.GetFullPath(fileArg.Path)
: Path.GetFullPath(Path.Combine(projectDirectory, fileArg.Path));
var relativePath = FilePathUtilities.GetRelativePath(projectDirectory, absolutePath);
var isWithinProject = FilePathUtilities.IsNestedPath(projectDirectory, absolutePath);
var relativePath = PathUtilities.GetRelativePath(projectDirectory, absolutePath);
var isWithinProject = PathUtilities.IsChildPath(projectDirectory, absolutePath);
var folderRoot = isWithinProject ? Path.GetDirectoryName(relativePath) : "";
var folders = isWithinProject ? GetFolders(relativePath) : null;
......
......@@ -275,7 +275,7 @@ private bool TryGetUniqueId(string value, bool fileCheck, out int id)
try
{
var uniqueIdValue = fileCheck ? FilePathUtilities.GetRelativePath(Path.GetDirectoryName(SolutionFilePath), value) : value;
var uniqueIdValue = fileCheck ? PathUtilities.GetRelativePath(Path.GetDirectoryName(SolutionFilePath), value) : value;
id = _nameTableCache.GetOrAdd(value, _esentStorage.GetUniqueId(uniqueIdValue));
return true;
......
......@@ -226,7 +226,7 @@ private class LoadState
= new Dictionary<ProjectId, Dictionary<ProjectId, bool>>();
private readonly Dictionary<string, ProjectId> _projectPathToProjectIdMap
= new Dictionary<string, ProjectId>();
= new Dictionary<string, ProjectId>(PathUtilities.Comparer);
public LoadState(IReadOnlyDictionary<string, ProjectId> projectPathToProjectIdMap)
{
......
......@@ -213,7 +213,7 @@ public async Task<Project> OpenProjectAsync(string projectFilePath, Cancellation
{
return this.CurrentSolution.Projects
.Where(p => !string.IsNullOrEmpty(p.FilePath))
.ToImmutableDictionary(p => p.FilePath, p => p.Id);
.ToImmutableDictionary(p => p.FilePath, p => p.Id, PathUtilities.Comparer);
}
#endregion
......
......@@ -458,7 +458,7 @@ protected string GetReferenceFilePath(ProjectItemInstance projectItem)
public void AddDocument(string filePath, string logicalPath = null)
{
var relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, filePath);
var relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, filePath);
Dictionary<string, string> metadata = null;
if (logicalPath != null && relativePath != logicalPath)
......@@ -473,11 +473,11 @@ public void AddDocument(string filePath, string logicalPath = null)
public void RemoveDocument(string filePath)
{
var relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, filePath);
var relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, filePath);
var items = _loadedProject.GetItems("Compile");
var item = items.FirstOrDefault(it => FilePathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| FilePathUtilities.PathsEqual(it.EvaluatedInclude, filePath));
var item = items.FirstOrDefault(it => PathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| PathUtilities.PathsEqual(it.EvaluatedInclude, filePath));
if (item != null)
{
_loadedProject.RemoveItem(item);
......@@ -509,7 +509,7 @@ public void AddMetadataReference(MetadataReference reference, AssemblyIdentity i
}
else // other location -- need hint to find correct assembly
{
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, peRef.FilePath);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, peRef.FilePath);
var fileName = Path.GetFileNameWithoutExtension(peRef.FilePath);
metadata.Add("HintPath", relativePath);
_loadedProject.AddItem("Reference", fileName, metadata);
......@@ -519,7 +519,7 @@ public void AddMetadataReference(MetadataReference reference, AssemblyIdentity i
private bool IsInGAC(string filePath)
{
return GlobalAssemblyCacheLocation.RootLocations.Any(gloc => FilePathUtilities.IsNestedPath(gloc, filePath));
return GlobalAssemblyCacheLocation.RootLocations.Any(gloc => PathUtilities.IsChildPath(gloc, filePath));
}
private static string s_frameworkRoot;
......@@ -539,7 +539,7 @@ private static string FrameworkRoot
private bool IsFrameworkReferenceAssembly(string filePath)
{
return FilePathUtilities.IsNestedPath(FrameworkRoot, filePath);
return PathUtilities.IsChildPath(FrameworkRoot, filePath);
}
public void RemoveMetadataReference(MetadataReference reference, AssemblyIdentity identity)
......@@ -580,12 +580,12 @@ private MSB.Evaluation.ProjectItem FindReferenceItem(AssemblyIdentity identity,
// check for file path match
if (item == null)
{
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, filePath);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, filePath);
item = references.FirstOrDefault(it => FilePathUtilities.PathsEqual(it.EvaluatedInclude, filePath)
|| FilePathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| FilePathUtilities.PathsEqual(GetHintPath(it), filePath)
|| FilePathUtilities.PathsEqual(GetHintPath(it), relativePath));
item = references.FirstOrDefault(it => PathUtilities.PathsEqual(it.EvaluatedInclude, filePath)
|| PathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| PathUtilities.PathsEqual(GetHintPath(it), filePath)
|| PathUtilities.PathsEqual(GetHintPath(it), relativePath));
}
// check for partial name match
......@@ -617,13 +617,13 @@ public void AddProjectReference(string projectName, ProjectFileReference referen
metadata.Add("Aliases", string.Join(",", reference.Aliases));
}
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, reference.Path);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, reference.Path);
_loadedProject.AddItem("ProjectReference", relativePath, metadata);
}
public void RemoveProjectReference(string projectName, string projectFilePath)
{
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, projectFilePath);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, projectFilePath);
var item = FindProjectReferenceItem(projectName, projectFilePath);
if (item != null)
{
......@@ -634,13 +634,13 @@ public void RemoveProjectReference(string projectName, string projectFilePath)
private MSB.Evaluation.ProjectItem FindProjectReferenceItem(string projectName, string projectFilePath)
{
var references = _loadedProject.GetItems("ProjectReference");
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, projectFilePath);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, projectFilePath);
MSB.Evaluation.ProjectItem item = null;
// find by project file path
item = references.First(it => FilePathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| FilePathUtilities.PathsEqual(it.EvaluatedInclude, projectFilePath));
item = references.First(it => PathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| PathUtilities.PathsEqual(it.EvaluatedInclude, projectFilePath));
// try to find by project name
if (item == null)
......@@ -656,7 +656,7 @@ public void AddAnalyzerReference(AnalyzerReference reference)
var fileRef = reference as AnalyzerFileReference;
if (fileRef != null)
{
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, fileRef.FullPath);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, fileRef.FullPath);
_loadedProject.AddItem("Analyzer", relativePath);
}
}
......@@ -666,11 +666,11 @@ public void RemoveAnalyzerReference(AnalyzerReference reference)
var fileRef = reference as AnalyzerFileReference;
if (fileRef != null)
{
string relativePath = FilePathUtilities.GetRelativePath(_loadedProject.DirectoryPath, fileRef.FullPath);
string relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, fileRef.FullPath);
var analyzers = _loadedProject.GetItems("Analyzer");
var item = analyzers.FirstOrDefault(it => FilePathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| FilePathUtilities.PathsEqual(it.EvaluatedInclude, fileRef.FullPath));
var item = analyzers.FirstOrDefault(it => PathUtilities.PathsEqual(it.EvaluatedInclude, relativePath)
|| PathUtilities.PathsEqual(it.EvaluatedInclude, fileRef.FullPath));
if (item != null)
{
_loadedProject.RemoveItem(item);
......
......@@ -55,7 +55,6 @@
<Compile Include="Execution\DesktopReferenceSerializationServiceFactory.cs" />
<Compile Include="Execution\SerializationAnalyzerAssemblyLoader.cs" />
<Compile Include="Options\ExportOptionAttribute.cs" />
<Compile Include="InternalUtilities\FilePathUtilities.cs" />
<Compile Include="Log\EtwLogger.cs" />
<Compile Include="Log\RoslynEventSource.cs" />
<Compile Include="Options\Providers\ExportedOptionKeyOptionProvider.cs" />
......
......@@ -21,7 +21,7 @@ public void GetRelativePath_SameDirectory()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"C:\Alpha\Beta\Gamma\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"Doc.txt", actual: result);
}
......@@ -33,7 +33,7 @@ public void GetRelativePath_NestedOneLevelDown()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"C:\Alpha\Beta\Gamma\Delta\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"Delta\Doc.txt", actual: result);
}
......@@ -45,7 +45,7 @@ public void GetRelativePath_NestedTwoLevelsDown()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"C:\Alpha\Beta\Gamma\Delta\Epsilon\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"Delta\Epsilon\Doc.txt", actual: result);
}
......@@ -57,7 +57,7 @@ public void GetRelativePath_UpOneLevel()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"C:\Alpha\Beta\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"..\Doc.txt", actual: result);
}
......@@ -69,7 +69,7 @@ public void GetRelativePath_UpTwoLevels()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"C:\Alpha\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"..\..\Doc.txt", actual: result);
}
......@@ -81,7 +81,7 @@ public void GetRelativePath_UpTwoLevelsAndThenDown()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"C:\Alpha\Phi\Omega\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"..\..\Phi\Omega\Doc.txt", actual: result);
}
......@@ -93,7 +93,7 @@ public void GetRelativePath_OnADifferentDrive()
string baseDirectory = @"C:\Alpha\Beta\Gamma";
string fullPath = @"D:\Alpha\Beta\Gamma\Doc.txt";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"D:\Alpha\Beta\Gamma\Doc.txt", actual: result);
}
......@@ -105,7 +105,7 @@ public void GetRelativePath_WithBaseDirectoryMatchingIncompletePortionOfFullPath
string baseDirectory = @"C:\Alpha\Beta";
string fullPath = @"C:\Alpha\Beta2\Gamma";
string result = FilePathUtilities.GetRelativePath(baseDirectory, fullPath);
string result = PathUtilities.GetRelativePath(baseDirectory, fullPath);
Assert.Equal(expected: @"..\Beta2\Gamma", actual: result);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册