11// Copyright (C) 2011, Xamarin Inc.
22// Copyright (C) 2010, Novell Inc.
33
4- using System ;
5- using System . Collections . Generic ;
6- using System . Linq ;
74using Microsoft . Build . Framework ;
85using Microsoft . Build . Utilities ;
9- using Mono . Cecil ;
106using MonoDroid . Tuner ;
7+ using NuGet . Frameworks ;
8+ using NuGet . ProjectModel ;
9+ using System ;
10+ using System . Collections . Generic ;
1111using System . IO ;
12+ using System . Linq ;
13+ using System . Reflection . Metadata ;
1214using System . Text ;
1315using Xamarin . Android . Tools ;
14- using NuGet . Common ;
15- using NuGet . Frameworks ;
16- using NuGet . ProjectModel ;
17-
18- using Java . Interop . Tools . Cecil ;
1916
2017namespace Xamarin . Android . Tasks
2118{
@@ -62,7 +59,7 @@ public override bool Execute ()
6259 Yield ( ) ;
6360 try {
6461 System . Threading . Tasks . Task . Run ( ( ) => {
65- using ( var resolver = new DirectoryAssemblyResolver ( this . CreateTaskLogger ( ) , loadDebugSymbols : false ) ) {
62+ using ( var resolver = new MetadataResolver ( ) ) {
6663 Execute ( resolver ) ;
6764 }
6865 } , Token ) . ContinueWith ( Complete ) ;
@@ -72,14 +69,13 @@ public override bool Execute ()
7269 }
7370 }
7471
75- void Execute ( DirectoryAssemblyResolver resolver )
72+ void Execute ( MetadataResolver resolver )
7673 {
77- foreach ( var dir in ReferenceAssembliesDirectory . Split ( new char [ ] { ';' } , StringSplitOptions . RemoveEmptyEntries ) )
78- resolver . SearchDirectories . Add ( dir ) ;
74+ var assemblies = new Dictionary < string , ITaskItem > ( Assemblies . Length ) ;
75+ foreach ( var dir in ReferenceAssembliesDirectory . Split ( new char [ ] { ';' } , StringSplitOptions . RemoveEmptyEntries ) )
76+ resolver . AddSearchDirectory ( dir ) ;
7977
80- var assemblies = new Dictionary < string , ITaskItem > ( ) ;
81-
82- var topAssemblyReferences = new List < AssemblyDefinition > ( ) ;
78+ var topAssemblyReferences = new List < string > ( Assemblies . Length ) ;
8379 var logger = new NuGetLogger ( ( s ) => {
8480 LogDebugMessage ( "{0}" , s ) ;
8581 } ) ;
@@ -92,32 +88,28 @@ void Execute (DirectoryAssemblyResolver resolver)
9288 try {
9389 foreach ( var assembly in Assemblies ) {
9490 var assembly_path = Path . GetDirectoryName ( assembly . ItemSpec ) ;
95-
96- if ( ! resolver . SearchDirectories . Contains ( assembly_path ) )
97- resolver . SearchDirectories . Add ( assembly_path ) ;
91+ resolver . AddSearchDirectory ( assembly_path ) ;
9892
9993 // Add each user assembly and all referenced assemblies (recursive)
100- var assemblyDef = resolver . Load ( assembly . ItemSpec ) ;
101- if ( assemblyDef == null )
102- throw new InvalidOperationException ( "Failed to load assembly " + assembly . ItemSpec ) ;
103- if ( MonoAndroidHelper . IsReferenceAssembly ( assemblyDef ) ) {
94+ string resolved_assembly = resolver . Resolve ( assembly . ItemSpec ) ;
95+ if ( MonoAndroidHelper . IsReferenceAssembly ( resolved_assembly ) ) {
10496 // Resolve "runtime" library
105- var asmFullPath = Path . GetFullPath ( assembly . ItemSpec ) ;
10697 if ( lockFile != null )
107- assemblyDef = ResolveRuntimeAssemblyForReferenceAssembly ( lockFile , resolver , asmFullPath ) ;
108- if ( lockFile == null || assemblyDef == null ) {
109- LogCodedWarning ( "XA0107" , asmFullPath , 0 , "Ignoring {0} as it is a Reference Assembly" , asmFullPath ) ;
98+ resolved_assembly = ResolveRuntimeAssemblyForReferenceAssembly ( lockFile , assembly . ItemSpec ) ;
99+ if ( lockFile == null || resolved_assembly == null ) {
100+ LogCodedWarning ( "XA0107" , resolved_assembly , 0 , "Ignoring {0} as it is a Reference Assembly" , resolved_assembly ) ;
110101 continue ;
111102 }
112103 }
113- topAssemblyReferences . Add ( assemblyDef ) ;
104+ topAssemblyReferences . Add ( resolved_assembly ) ;
114105 var taskItem = new TaskItem ( assembly ) {
115- ItemSpec = Path . GetFullPath ( assemblyDef . MainModule . FileName ) ,
106+ ItemSpec = Path . GetFullPath ( resolved_assembly ) ,
116107 } ;
117108 if ( string . IsNullOrEmpty ( taskItem . GetMetadata ( "ReferenceAssembly" ) ) ) {
118109 taskItem . SetMetadata ( "ReferenceAssembly" , taskItem . ItemSpec ) ;
119110 }
120- assemblies [ assemblyDef . Name . Name ] = taskItem ;
111+ string assemblyName = Path . GetFileNameWithoutExtension ( resolved_assembly ) ;
112+ assemblies [ assemblyName ] = taskItem ;
121113 }
122114 } catch ( Exception ex ) {
123115 LogError ( "Exception while loading assemblies: {0}" , ex ) ;
@@ -171,7 +163,7 @@ void Execute (DirectoryAssemblyResolver resolver)
171163 readonly Dictionary < string , int > api_levels = new Dictionary < string , int > ( ) ;
172164 int indent = 2 ;
173165
174- AssemblyDefinition ResolveRuntimeAssemblyForReferenceAssembly ( LockFile lockFile , DirectoryAssemblyResolver resolver , string assemblyPath )
166+ string ResolveRuntimeAssemblyForReferenceAssembly ( LockFile lockFile , string assemblyPath )
175167 {
176168 if ( string . IsNullOrEmpty ( TargetMoniker ) )
177169 return null ;
@@ -200,16 +192,16 @@ AssemblyDefinition ResolveRuntimeAssemblyForReferenceAssembly (LockFile lockFile
200192 path = Path . Combine ( folder . Path , libraryPath . Path , runtime . Path ) . Replace ( '/' , Path . DirectorySeparatorChar ) ;
201193 if ( ! File . Exists ( path ) )
202194 continue ;
203- LogDebugMessage ( $ "Attempting to load { path } ") ;
204- return resolver . Load ( path , forceLoad : true ) ;
195+ return path ;
205196 }
206197 return null ;
207198 }
208199
209- void AddAssemblyReferences ( DirectoryAssemblyResolver resolver , Dictionary < string , ITaskItem > assemblies , AssemblyDefinition assembly , List < string > resolutionPath )
200+ void AddAssemblyReferences ( MetadataResolver resolver , Dictionary < string , ITaskItem > assemblies , string assemblyPath , List < string > resolutionPath )
210201 {
211- var assemblyName = assembly . Name . Name ;
212- var fullPath = Path . GetFullPath ( assembly . MainModule . FileName ) ;
202+ var reader = resolver . GetAssemblyReader ( assemblyPath ) ;
203+ var assembly = reader . GetAssemblyDefinition ( ) ;
204+ var assemblyName = reader . GetString ( assembly . Name ) ;
213205
214206 // Don't repeat assemblies we've already done
215207 bool topLevel = resolutionPath == null ;
@@ -219,22 +211,23 @@ void AddAssemblyReferences (DirectoryAssemblyResolver resolver, Dictionary<strin
219211 if ( resolutionPath == null )
220212 resolutionPath = new List < string > ( ) ;
221213
222- CheckAssemblyAttributes ( assembly ) ;
214+ CheckAssemblyAttributes ( assembly , reader ) ;
223215
224- LogMessage ( "{0}Adding assembly reference for {1}, recursively..." , new string ( ' ' , indent ) , assembly . Name ) ;
225- resolutionPath . Add ( assembly . Name . Name ) ;
216+ LogMessage ( "{0}Adding assembly reference for {1}, recursively..." , new string ( ' ' , indent ) , assemblyName ) ;
217+ resolutionPath . Add ( assemblyName ) ;
226218 indent += 2 ;
227219
228220 // Add this assembly
229221 if ( ! topLevel ) {
230- assemblies [ assemblyName ] = CreateAssemblyTaskItem ( fullPath ) ;
222+ assemblies [ assemblyName ] = CreateAssemblyTaskItem ( Path . GetFullPath ( assemblyPath ) ) ;
231223 }
232224
233225 // Recurse into each referenced assembly
234- foreach ( AssemblyNameReference reference in assembly . MainModule . AssemblyReferences ) {
235- AssemblyDefinition reference_assembly ;
226+ foreach ( var handle in reader . AssemblyReferences ) {
227+ var reference = reader . GetAssemblyReference ( handle ) ;
228+ string reference_assembly ;
236229 try {
237- reference_assembly = resolver . Resolve ( reference ) ;
230+ reference_assembly = resolver . Resolve ( reader . GetString ( reference . Name ) ) ;
238231 } catch ( FileNotFoundException ex ) {
239232 var references = new StringBuilder ( ) ;
240233 for ( int i = 0 ; i < resolutionPath . Count ; i ++ ) {
@@ -261,25 +254,30 @@ void AddAssemblyReferences (DirectoryAssemblyResolver resolver, Dictionary<strin
261254 resolutionPath . RemoveAt ( resolutionPath . Count - 1 ) ;
262255 }
263256
264- void CheckAssemblyAttributes ( AssemblyDefinition assembly )
257+ void CheckAssemblyAttributes ( AssemblyDefinition assembly , MetadataReader reader )
265258 {
266- foreach ( var att in assembly . CustomAttributes ) {
267- switch ( att . AttributeType . FullName ) {
259+ foreach ( var handle in assembly . GetCustomAttributes ( ) ) {
260+ var attribute = reader . GetCustomAttribute ( handle ) ;
261+ switch ( reader . GetCustomAttributeFullName ( attribute ) ) {
268262 case "Java.Interop.DoNotPackageAttribute" : {
269- string file = ( string ) att . ConstructorArguments . First ( ) . Value ;
270- if ( string . IsNullOrWhiteSpace ( file ) )
271- LogError ( "In referenced assembly {0}, Java.Interop.DoNotPackageAttribute requires non-null file name." , assembly . FullName ) ;
272- do_not_package_atts . Add ( Path . GetFileName ( file ) ) ;
263+ var decoded = attribute . DecodeValue ( DummyCustomAttributeProvider . Instance ) ;
264+ if ( decoded . FixedArguments . Length > 0 ) {
265+ string file = decoded . FixedArguments [ 0 ] . Value ? . ToString ( ) ;
266+ if ( string . IsNullOrWhiteSpace ( file ) )
267+ LogError ( "In referenced assembly {0}, Java.Interop.DoNotPackageAttribute requires non-null file name." , assembly . GetAssemblyName ( ) . FullName ) ;
268+ do_not_package_atts . Add ( Path . GetFileName ( file ) ) ;
269+ }
273270 }
274271 break ;
275272 case "System.Runtime.Versioning.TargetFrameworkAttribute" : {
276- foreach ( var p in att . ConstructorArguments ) {
277- var value = p . Value . ToString ( ) ;
278- if ( value . StartsWith ( "MonoAndroid" ) ) {
273+ var decoded = attribute . DecodeValue ( DummyCustomAttributeProvider . Instance ) ;
274+ foreach ( var p in decoded . FixedArguments ) {
275+ var value = p . Value ? . ToString ( ) ;
276+ if ( value != null && value . StartsWith ( "MonoAndroid" , StringComparison . Ordinal ) ) {
279277 var values = value . Split ( '=' ) ;
280278 var apiLevel = MonoAndroidHelper . SupportedVersions . GetApiLevelFromFrameworkVersion ( values [ 1 ] ) ;
281279 if ( apiLevel != null ) {
282- var assemblyName = assembly . Name . Name ;
280+ var assemblyName = reader . GetString ( assembly . Name ) ;
283281 Log . LogDebugMessage ( "{0}={1}" , assemblyName , apiLevel ) ;
284282 api_levels [ assemblyName ] = apiLevel . Value ;
285283 }
@@ -305,7 +303,7 @@ static LinkModes ParseLinkMode (string linkmode)
305303 return mode ;
306304 }
307305
308- void AddI18nAssemblies ( DirectoryAssemblyResolver resolver , Dictionary < string , ITaskItem > assemblies )
306+ void AddI18nAssemblies ( MetadataResolver resolver , Dictionary < string , ITaskItem > assemblies )
309307 {
310308 var i18n = Linker . ParseI18nAssemblies ( I18nAssemblies ) ;
311309 var link = ParseLinkMode ( LinkMode ) ;
@@ -332,10 +330,10 @@ void AddI18nAssemblies (DirectoryAssemblyResolver resolver, Dictionary<string, I
332330 ResolveI18nAssembly ( resolver , "I18N.West" , assemblies ) ;
333331 }
334332
335- void ResolveI18nAssembly ( DirectoryAssemblyResolver resolver , string name , Dictionary < string , ITaskItem > assemblies )
333+ void ResolveI18nAssembly ( MetadataResolver resolver , string name , Dictionary < string , ITaskItem > assemblies )
336334 {
337- var assembly = resolver . Resolve ( AssemblyNameReference . Parse ( name ) ) ;
338- var assemblyFullPath = Path . GetFullPath ( assembly . MainModule . FileName ) ;
335+ var assembly = resolver . Resolve ( name ) ;
336+ var assemblyFullPath = Path . GetFullPath ( assembly ) ;
339337 assemblies [ name ] = CreateAssemblyTaskItem ( assemblyFullPath ) ;
340338 }
341339
0 commit comments