@@ -10,6 +10,115 @@ namespace CodingWithCalvin.ProjectRenamifier.Services
1010 /// </summary>
1111 internal static class SourceFileService
1212 {
13+ /// <summary>
14+ /// Updates fully qualified type references in all .cs files across the entire solution.
15+ /// For example: OldName.MyClass → NewName.MyClass
16+ /// </summary>
17+ /// <param name="solution">The solution to scan.</param>
18+ /// <param name="oldNamespace">The old namespace to find.</param>
19+ /// <param name="newNamespace">The new namespace to replace with.</param>
20+ /// <returns>The number of files modified.</returns>
21+ public static int UpdateFullyQualifiedReferencesInSolution ( Solution solution , string oldNamespace , string newNamespace )
22+ {
23+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
24+
25+ var modifiedCount = 0 ;
26+
27+ foreach ( Project project in solution . Projects )
28+ {
29+ modifiedCount += UpdateFullyQualifiedReferencesInProjectTree ( project , oldNamespace , newNamespace ) ;
30+ }
31+
32+ return modifiedCount ;
33+ }
34+
35+ /// <summary>
36+ /// Recursively updates fully qualified references in a project (handles solution folders).
37+ /// </summary>
38+ private static int UpdateFullyQualifiedReferencesInProjectTree ( Project project , string oldNamespace , string newNamespace )
39+ {
40+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
41+
42+ if ( project == null )
43+ {
44+ return 0 ;
45+ }
46+
47+ // Handle solution folders
48+ if ( project . Kind == EnvDTE . Constants . vsProjectKindSolutionItems )
49+ {
50+ var count = 0 ;
51+ foreach ( ProjectItem item in project . ProjectItems )
52+ {
53+ if ( item . SubProject != null )
54+ {
55+ count += UpdateFullyQualifiedReferencesInProjectTree ( item . SubProject , oldNamespace , newNamespace ) ;
56+ }
57+ }
58+ return count ;
59+ }
60+
61+ // Process actual project
62+ if ( ! string . IsNullOrEmpty ( project . FullName ) && File . Exists ( project . FullName ) )
63+ {
64+ var projectDirectory = Path . GetDirectoryName ( project . FullName ) ;
65+ if ( ! string . IsNullOrEmpty ( projectDirectory ) && Directory . Exists ( projectDirectory ) )
66+ {
67+ return UpdateFullyQualifiedReferencesInDirectory ( projectDirectory , oldNamespace , newNamespace ) ;
68+ }
69+ }
70+
71+ return 0 ;
72+ }
73+
74+ /// <summary>
75+ /// Updates fully qualified references in all .cs files within a directory.
76+ /// </summary>
77+ private static int UpdateFullyQualifiedReferencesInDirectory ( string directory , string oldNamespace , string newNamespace )
78+ {
79+ var csFiles = Directory . GetFiles ( directory , "*.cs" , SearchOption . AllDirectories ) ;
80+ var modifiedCount = 0 ;
81+
82+ foreach ( var filePath in csFiles )
83+ {
84+ if ( UpdateFullyQualifiedReferencesInFile ( filePath , oldNamespace , newNamespace ) )
85+ {
86+ modifiedCount ++ ;
87+ }
88+ }
89+
90+ return modifiedCount ;
91+ }
92+
93+ /// <summary>
94+ /// Updates fully qualified type references in a single source file.
95+ /// Matches patterns like OldName.MyClass, OldName.Sub.Type but not SomeOldName.Type
96+ /// </summary>
97+ /// <param name="filePath">Full path to the .cs file.</param>
98+ /// <param name="oldNamespace">The old namespace to find.</param>
99+ /// <param name="newNamespace">The new namespace to replace with.</param>
100+ /// <returns>True if the file was modified, false otherwise.</returns>
101+ public static bool UpdateFullyQualifiedReferencesInFile ( string filePath , string oldNamespace , string newNamespace )
102+ {
103+ var encoding = DetectEncoding ( filePath ) ;
104+ var content = File . ReadAllText ( filePath , encoding ) ;
105+ var originalContent = content ;
106+
107+ // Pattern matches OldName followed by a dot and an identifier
108+ // Uses word boundary \b to avoid matching partial names like SomeOldName
109+ // Matches: OldName.Class, OldName.Sub.Class, etc.
110+ var pattern = $@ "\b{ Regex . Escape ( oldNamespace ) } \.";
111+ content = Regex . Replace ( content , pattern , $ "{ newNamespace } .") ;
112+
113+ if ( content != originalContent )
114+ {
115+ File . WriteAllText ( filePath , content , encoding ) ;
116+ return true ;
117+ }
118+
119+ return false ;
120+ }
121+
13122 /// <summary>
14123 /// Updates using statements in all .cs files across the entire solution.
15124 /// </summary>
0 commit comments