Forge
csharp551a3611
1#nullable enable
2
3namespace RoslynMcp.ServiceLayer.WorkspaceNavigation;
4
5/// <summary>Пути для навигации: тот же MSBuild-эвристики, что в Cascade IDE <c>McpSolutionTree</c> (без общего кода).</summary>
6public static class WorkspaceNavigationPathHelpers
7{
8 /// <summary>
9 /// Ближайший вверх по диску <c>.csproj</c>, которому по соглашению принадлежит файл.
10 /// </summary>
11 public static string? ResolveOwningProjectPath(string fileFullPath)
12 {
13 if (string.IsNullOrWhiteSpace(fileFullPath))
14 return null;
15 string full;
16 try
17 {
18 full = Path.GetFullPath(fileFullPath.Trim());
19 }
20 catch
21 {
22 return null;
23 }
24
25 var dir = Path.GetDirectoryName(full);
26 while (!string.IsNullOrEmpty(dir))
27 {
28 string[] csprojs;
29 try
30 {
31 csprojs = Directory.GetFiles(dir, "*.csproj");
32 }
33 catch
34 {
35 break;
36 }
37
38 if (csprojs.Length > 0)
39 {
40 if (csprojs.Length == 1)
41 return Path.GetFullPath(csprojs[0]);
42 var folderName = Path.GetFileName(dir);
43 var match = csprojs.FirstOrDefault(p =>
44 string.Equals(Path.GetFileNameWithoutExtension(p), folderName, StringComparison.OrdinalIgnoreCase));
45 return Path.GetFullPath(match ?? csprojs[0]);
46 }
47
48 try
49 {
50 dir = Path.GetDirectoryName(dir);
51 }
52 catch
53 {
54 break;
55 }
56 }
57
58 return null;
59 }
60
61 public static bool IsBuildArtifactPath(string fullPath)
62 {
63 if (string.IsNullOrEmpty(fullPath))
64 return false;
65 return fullPath.Contains($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase)
66 || fullPath.Contains($"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase)
67 || fullPath.Contains("/obj/", StringComparison.OrdinalIgnoreCase)
68 || fullPath.Contains("/bin/", StringComparison.OrdinalIgnoreCase);
69 }
70
71 public static string? GetRelativePath(string? solutionPath, string? fullPath)
72 {
73 if (string.IsNullOrEmpty(solutionPath) || string.IsNullOrEmpty(fullPath))
74 return null;
75 var solutionDir = Path.GetDirectoryName(solutionPath);
76 if (string.IsNullOrEmpty(solutionDir))
77 return null;
78 try
79 {
80 return Path.GetRelativePath(solutionDir, fullPath);
81 }
82 catch
83 {
84 return null;
85 }
86 }
87}
88
View only · write via MCP/CIDE