11using System ;
22using System . Collections . Generic ;
3+ using System . Linq ;
34using Mono . Cecil ;
45using Mono . Cecil . Cil ;
56using Xamarin . Forms . Build . Tasks ;
@@ -13,7 +14,7 @@ class RDSourceTypeConverter : ICompiledTypeConverter
1314 {
1415 public IEnumerable < Instruction > ConvertFromString ( string value , ILContext context , BaseNode node )
1516 {
16- var module = context . Body . Method . Module ;
17+ var currentModule = context . Body . Method . Module ;
1718 var body = context . Body ;
1819
1920 INode rootNode = node ;
@@ -22,7 +23,23 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
2223
2324 var rdNode = node . Parent as IElementNode ;
2425
25- var rootTargetPath = XamlCTask . GetPathForType ( module , ( ( ILRootNode ) rootNode ) . TypeReference ) ;
26+ var rootTargetPath = XamlCTask . GetPathForType ( currentModule , ( ( ILRootNode ) rootNode ) . TypeReference ) ;
27+
28+ var module = currentModule ;
29+ string asmName = null ;
30+ if ( value . Contains ( ";assembly=" ) )
31+ {
32+ var parts = value . Split ( new [ ] { ";assembly=" } , StringSplitOptions . RemoveEmptyEntries ) ;
33+ value = parts [ 0 ] ;
34+ asmName = parts [ 1 ] ;
35+ if ( currentModule . Assembly . Name . Name != asmName )
36+ {
37+ var ar = currentModule . AssemblyReferences . FirstOrDefault ( ar => ar . Name == asmName ) ;
38+ if ( ar == null )
39+ throw new BuildException ( BuildExceptionCode . ResourceMissing , node , null , value ) ;
40+ module = currentModule . AssemblyResolver . Resolve ( ar ) . MainModule ;
41+ }
42+ }
2643 var uri = new Uri ( value , UriKind . Relative ) ;
2744
2845 var resourcePath = ResourceDictionary . RDSourceTypeConverter . GetResourcePath ( uri , rootTargetPath ) ;
@@ -36,25 +53,38 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
3653
3754 //abuse the converter, produce some side effect, but leave the stack untouched
3855 //public void SetAndLoadSource(Uri value, string resourceID, Assembly assembly, System.Xml.IXmlLineInfo lineInfo)
39- foreach ( var instruction in context . Variables [ rdNode ] . LoadAs ( module . GetTypeDefinition ( resourceDictionaryType ) , module ) )
56+ foreach ( var instruction in context . Variables [ rdNode ] . LoadAs ( currentModule . GetTypeDefinition ( resourceDictionaryType ) , currentModule ) )
4057 yield return instruction ;
58+ //reappend assembly= in all cases, see other RD converter
59+ if ( ! string . IsNullOrEmpty ( asmName ) )
60+ value = $ "{ value } ;assembly={ asmName } ";
61+ else
62+ value = $ "{ value } ;assembly={ ( ( ILRootNode ) rootNode ) . TypeReference . Module . Assembly . Name . Name } ";
4163 foreach ( var instruction in ( new UriTypeConverter ( ) ) . ConvertFromString ( value , context , node ) )
4264 yield return instruction ; //the Uri
4365
4466 //keep the Uri for later
4567 yield return Create ( Dup ) ;
46- var uriVarDef = new VariableDefinition ( module . ImportReference ( ( "System" , "System" , "Uri" ) ) ) ;
68+ var uriVarDef = new VariableDefinition ( currentModule . ImportReference ( ( "System" , "System" , "Uri" ) ) ) ;
4769 body . Variables . Add ( uriVarDef ) ;
4870 yield return Create ( Stloc , uriVarDef ) ;
4971 yield return Create ( Ldstr , resourcePath ) ; //resourcePath
50- yield return Create ( Ldtoken , module . ImportReference ( ( ( ILRootNode ) rootNode ) . TypeReference ) ) ;
51- yield return Create ( Call , module . ImportMethodReference ( ( "mscorlib" , "System" , "Type" ) , methodName : "GetTypeFromHandle" , parameterTypes : new [ ] { ( "mscorlib" , "System" , "RuntimeTypeHandle" ) } , isStatic : true ) ) ;
52- yield return Create ( Call , module . ImportMethodReference ( ( "mscorlib" , "System.Reflection" , "IntrospectionExtensions" ) , methodName : "GetTypeInfo" , parameterTypes : new [ ] { ( "mscorlib" , "System" , "Type" ) } , isStatic : true ) ) ;
53- yield return Create ( Callvirt , module . ImportPropertyGetterReference ( ( "mscorlib" , "System.Reflection" , "TypeInfo" ) , propertyName : "Assembly" , flatten : true ) ) ;
5472
73+ if ( ! string . IsNullOrEmpty ( asmName ) )
74+ {
75+ yield return Create ( Ldstr , asmName ) ;
76+ yield return Create ( Call , currentModule . ImportMethodReference ( ( "mscorlib" , "System.Reflection" , "Assembly" ) , methodName : "Load" , parameterTypes : new [ ] { ( "mscorlib" , "System" , "String" ) } , isStatic : true ) ) ;
77+ }
78+ else //we could use assembly.Load in the 'else' part too, but I don't want to change working code right now
79+ {
80+ yield return Create ( Ldtoken , currentModule . ImportReference ( ( ( ILRootNode ) rootNode ) . TypeReference ) ) ;
81+ yield return Create ( Call , currentModule . ImportMethodReference ( ( "mscorlib" , "System" , "Type" ) , methodName : "GetTypeFromHandle" , parameterTypes : new [ ] { ( "mscorlib" , "System" , "RuntimeTypeHandle" ) } , isStatic : true ) ) ;
82+ yield return Create ( Call , currentModule . ImportMethodReference ( ( "mscorlib" , "System.Reflection" , "IntrospectionExtensions" ) , methodName : "GetTypeInfo" , parameterTypes : new [ ] { ( "mscorlib" , "System" , "Type" ) } , isStatic : true ) ) ;
83+ yield return Create ( Callvirt , currentModule . ImportPropertyGetterReference ( ( "mscorlib" , "System.Reflection" , "TypeInfo" ) , propertyName : "Assembly" , flatten : true ) ) ;
84+ }
5585 foreach ( var instruction in node . PushXmlLineInfo ( context ) )
5686 yield return instruction ; //lineinfo
57- yield return Create ( Callvirt , module . ImportMethodReference ( resourceDictionaryType ,
87+ yield return Create ( Callvirt , currentModule . ImportMethodReference ( resourceDictionaryType ,
5888 methodName : "SetAndLoadSource" ,
5989 parameterTypes : new [ ] { ( "System" , "System" , "Uri" ) , ( "mscorlib" , "System" , "String" ) , ( "mscorlib" , "System.Reflection" , "Assembly" ) , ( "System.Xml.ReaderWriter" , "System.Xml" , "IXmlLineInfo" ) } ) ) ;
6090 //ldloc the stored uri as return value
0 commit comments