88using Java . Interop . Tools . TypeNameMappings ;
99using Microsoft . Android . Build . Tasks ;
1010using Microsoft . Build . Framework ;
11+ using Microsoft . Build . Utilities ;
1112using Mono . Cecil ;
1213using MonoDroid . Tuner ;
1314using Xamarin . Android . Tools ;
@@ -78,10 +79,6 @@ public override bool RunTask ()
7879 ReadSymbols = ReadSymbols ,
7980 } ;
8081
81- var writerParameters = new WriterParameters {
82- DeterministicMvid = Deterministic ,
83- } ;
84-
8582 Dictionary < AndroidTargetArch , Dictionary < string , ITaskItem > > perArchAssemblies = MonoAndroidHelper . GetPerArchAssemblies ( ResolvedAssemblies , Array . Empty < string > ( ) , validate : false ) ;
8683
8784 AssemblyPipeline ? pipeline = null ;
@@ -122,7 +119,7 @@ public override bool RunTask ()
122119
123120 Directory . CreateDirectory ( Path . GetDirectoryName ( destination . ItemSpec ) ) ;
124121
125- RunPipeline ( pipeline ! , source , destination , writerParameters ) ;
122+ RunPipeline ( pipeline ! , source , destination ) ;
126123 }
127124
128125 pipeline ? . Dispose ( ) ;
@@ -141,9 +138,26 @@ protected virtual void BuildPipeline (AssemblyPipeline pipeline, MSBuildLinkCont
141138
142139 findJavaObjectsStep . Initialize ( context ) ;
143140 pipeline . Steps . Add ( findJavaObjectsStep ) ;
141+
142+ // SaveChangedAssemblyStep
143+ var writerParameters = new WriterParameters {
144+ DeterministicMvid = Deterministic ,
145+ } ;
146+
147+ var saveChangedAssemblyStep = new SaveChangedAssemblyStep ( Log , writerParameters ) ;
148+ pipeline . Steps . Add ( saveChangedAssemblyStep ) ;
149+
150+ // FindTypeMapObjectsStep - this must be run after the assembly has been saved, as saving changes the MVID
151+ var findTypeMapObjectsStep = new FindTypeMapObjectsStep ( Log ) {
152+ ErrorOnCustomJavaObject = ErrorOnCustomJavaObject ,
153+ Debug = Debug ,
154+ } ;
155+
156+ findTypeMapObjectsStep . Initialize ( context ) ;
157+ pipeline . Steps . Add ( findTypeMapObjectsStep ) ;
144158 }
145159
146- void RunPipeline ( AssemblyPipeline pipeline , ITaskItem source , ITaskItem destination , WriterParameters writerParameters )
160+ void RunPipeline ( AssemblyPipeline pipeline , ITaskItem source , ITaskItem destination )
147161 {
148162 var assembly = pipeline . Resolver . GetAssembly ( source . ItemSpec ) ;
149163
@@ -157,28 +171,47 @@ void RunPipeline (AssemblyPipeline pipeline, ITaskItem source, ITaskItem destina
157171 IsUserAssembly = ResolvedUserAssemblies . Any ( a => a . ItemSpec == source . ItemSpec ) ,
158172 } ;
159173
160- var changed = pipeline . Run ( assembly , context ) ;
161-
162- if ( changed ) {
163- Log . LogDebugMessage ( $ "Saving modified assembly: { destination . ItemSpec } ") ;
164- Directory . CreateDirectory ( Path . GetDirectoryName ( destination . ItemSpec ) ) ;
165- writerParameters . WriteSymbols = assembly . MainModule . HasSymbols ;
166- assembly . Write ( destination . ItemSpec , writerParameters ) ;
167- } else {
168- // If we didn't write a modified file, copy the original to the destination
169- CopyIfChanged ( source , destination ) ;
170- }
174+ pipeline . Run ( assembly , context ) ;
171175 }
172176
173- void CopyIfChanged ( ITaskItem source , ITaskItem destination )
177+ class SaveChangedAssemblyStep : IAssemblyModifierPipelineStep
174178 {
175- if ( MonoAndroidHelper . CopyAssemblyAndSymbols ( source . ItemSpec , destination . ItemSpec ) ) {
176- Log . LogDebugMessage ( $ "Copied: { destination . ItemSpec } ") ;
177- } else {
178- Log . LogDebugMessage ( $ "Skipped unchanged file: { destination . ItemSpec } ") ;
179+ public TaskLoggingHelper Log { get ; set ; }
180+
181+ public WriterParameters WriterParameters { get ; set ; }
182+
183+ public SaveChangedAssemblyStep ( TaskLoggingHelper log , WriterParameters writerParameters )
184+ {
185+ Log = log ;
186+ WriterParameters = writerParameters ;
187+ }
179188
180- // NOTE: We still need to update the timestamp on this file, or this target would run again
181- File . SetLastWriteTimeUtc ( destination . ItemSpec , DateTime . UtcNow ) ;
189+ public void ProcessAssembly ( AssemblyDefinition assembly , StepContext context )
190+ {
191+ if ( context . IsAssemblyModified ) {
192+ Log . LogDebugMessage ( $ "Saving modified assembly: { context . Destination . ItemSpec } ") ;
193+ Directory . CreateDirectory ( Path . GetDirectoryName ( context . Destination . ItemSpec ) ) ;
194+ WriterParameters . WriteSymbols = assembly . MainModule . HasSymbols ;
195+ assembly . Write ( context . Destination . ItemSpec , WriterParameters ) ;
196+ } else {
197+ // If we didn't write a modified file, copy the original to the destination
198+ CopyIfChanged ( context . Source , context . Destination ) ;
199+ }
200+
201+ // We just saved the assembly, so it is no longer modified
202+ context . IsAssemblyModified = false ;
203+ }
204+
205+ void CopyIfChanged ( ITaskItem source , ITaskItem destination )
206+ {
207+ if ( MonoAndroidHelper . CopyAssemblyAndSymbols ( source . ItemSpec , destination . ItemSpec ) ) {
208+ Log . LogDebugMessage ( $ "Copied: { destination . ItemSpec } ") ;
209+ } else {
210+ Log . LogDebugMessage ( $ "Skipped unchanged file: { destination . ItemSpec } ") ;
211+
212+ // NOTE: We still need to update the timestamp on this file, or this target would run again
213+ File . SetLastWriteTimeUtc ( destination . ItemSpec , DateTime . UtcNow ) ;
214+ }
182215 }
183216 }
184217}
0 commit comments