11using Avalonia ;
22using System ;
3+ using System . CodeDom . Compiler ;
34using System . Collections . Generic ;
45using System . IO ;
6+ using System . Reflection ;
57// ReSharper disable once RedundantUsingDirective
68using System . Linq ;
79using System . Threading ;
1315using GitHubReleaseChecker ;
1416using Microsoft . Extensions . DependencyInjection ;
1517using Microsoft . Extensions . Hosting ;
18+ using Microsoft . Extensions . Logging ;
1619using MSURandomizerLibrary ;
1720using MSUScripter . Models ;
1821using MSUScripter . Services ;
22+ using MSUScripter . ViewModels ;
23+ using ReactiveUI ;
24+ using ReactiveUI . SourceGenerators ;
1925using Serilog ;
2026using Win32RenderingMode = Avalonia . Win32RenderingMode ;
2127
@@ -32,7 +38,6 @@ class Program
3238 [ STAThread ]
3339 public static void Main ( string [ ] args )
3440 {
35-
3641 var loggerConfiguration = new LoggerConfiguration ( ) ;
3742
3843#if DEBUG
@@ -57,6 +62,10 @@ public static void Main(string[] args)
5762#endif
5863 . CreateLogger ( ) ;
5964
65+ #if DEBUG
66+ CheckReactiveProperties ( ) ;
67+ #endif
68+
6069 if ( args . Length == 1 && args [ 0 ] . EndsWith ( ".msup" , StringComparison . OrdinalIgnoreCase ) && File . Exists ( args [ 0 ] ) )
6170 {
6271 StartingProject = args [ 0 ] ;
@@ -121,6 +130,7 @@ private static IServiceCollection ConfigureServices(IServiceCollection collectio
121130 . AddSingleton < StatusBarService > ( )
122131 . AddSingleton < PythonCompanionService > ( )
123132 . AddSingleton < DependencyInstallerService > ( )
133+ . AddSingleton < PcmModifierService > ( )
124134 . AddAvaloniaControlServices < Program > ( )
125135 . AddTransient < ApplicationInitializationService > ( ) ;
126136
@@ -166,5 +176,46 @@ await Dispatcher.UIThread.Invoke(async () =>
166176#else
167177 private static string LogPath => Path . Combine ( Directories . LogFolder , "msu-scripter_.log" ) ;
168178#endif
179+
180+ private static void CheckReactiveProperties ( )
181+ {
182+ var assemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
183+
184+ foreach ( var asm in assemblies )
185+ {
186+ foreach ( var type in asm . GetTypes ( ) )
187+ {
188+ if ( ! InheritsFromType < ReactiveObject > ( type ) )
189+ {
190+ continue ;
191+ }
192+
193+ var props = type . GetProperties (
194+ BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic )
195+ . Select ( x => ( Property : x , Attributes : x . GetCustomAttributes ( true ) ) )
196+ . Where ( x => x . Attributes . Any ( a => a is ReactiveAttribute ) && ! x . Attributes . Any ( a => a is GeneratedCodeAttribute ) )
197+ . ToList ( ) ;
198+
199+ foreach ( var prop in props )
200+ {
201+ Log . Logger . Warning ( "Class {Class} property {Property} has ReactiveAttribute but is missing partial" , type . FullName , prop . Property . Name ) ;
202+ }
203+ }
204+ }
205+ }
206+
207+ static bool InheritsFromType < T > ( Type type )
208+ {
209+ var checkType = type ;
210+ while ( checkType != null && checkType != typeof ( object ) )
211+ {
212+ if ( checkType == typeof ( T ) )
213+ return true ;
214+
215+ checkType = checkType . BaseType ;
216+ }
217+
218+ return false ;
219+ }
169220
170221}
0 commit comments