This repository has been archived by the owner on May 1, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xaml[C]] ResourceDictionary.Source (#1229)
* [Xaml[C]] ResourceDictionary.Source * [Xaml[C]] update to the new XamlResourceIdAttribute * [Xaml[C]] load RD with codebehind even when referenced through Source * [Xaml] make sure we do not generate file:// uri * fix typo
- Loading branch information
1 parent
c341958
commit 43143bd
Showing
32 changed files
with
552 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
Xamarin.Forms.Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
using Mono.Cecil; | ||
using Mono.Cecil.Cil; | ||
|
||
using static Mono.Cecil.Cil.Instruction; | ||
using static Mono.Cecil.Cil.OpCodes; | ||
|
||
using Xamarin.Forms.Build.Tasks; | ||
using Xamarin.Forms.Xaml; | ||
|
||
namespace Xamarin.Forms.Core.XamlC | ||
{ | ||
class RDSourceTypeConverter : ICompiledTypeConverter | ||
{ | ||
public IEnumerable<Instruction> ConvertFromString(string value, ILContext context, BaseNode node) | ||
{ | ||
var module = context.Body.Method.Module; | ||
var body = context.Body; | ||
|
||
INode rootNode = node; | ||
while (!(rootNode is ILRootNode)) | ||
rootNode = rootNode.Parent; | ||
|
||
var rdNode = node.Parent as IElementNode; | ||
|
||
var rootTargetPath = GetPathForType(module, ((ILRootNode)rootNode).TypeReference); | ||
var uri = new Uri(value, UriKind.Relative); | ||
|
||
var resourceId = ResourceDictionary.RDSourceTypeConverter.GetResourceId(uri, rootTargetPath, s => GetResourceIdForPath(module, s)); | ||
//abuse the converter, produce some side effect, but leave the stack untouched | ||
//public void SetAndLoadSource(Uri value, string resourceID, Assembly assembly, System.Xml.IXmlLineInfo lineInfo) | ||
yield return Create(Ldloc, context.Variables[rdNode]); //the resourcedictionary | ||
foreach (var instruction in (new UriTypeConverter()).ConvertFromString(value, context, node)) | ||
yield return instruction; //the Uri | ||
|
||
//keep the Uri for later | ||
yield return Create(Dup); | ||
var uriVarDef = new VariableDefinition(module.ImportReference(typeof(Uri))); | ||
body.Variables.Add(uriVarDef); | ||
yield return Create(Stloc, uriVarDef); | ||
|
||
yield return Create(Ldstr, resourceId); //resourceId | ||
|
||
var getTypeFromHandle = module.ImportReference(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); | ||
var getAssembly = module.ImportReference(typeof(Type).GetProperty("Assembly").GetGetMethod()); | ||
yield return Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference)); | ||
yield return Create(Call, module.ImportReference(getTypeFromHandle)); | ||
yield return Create(Callvirt, module.ImportReference(getAssembly)); //assembly | ||
|
||
foreach (var instruction in node.PushXmlLineInfo(context)) | ||
yield return instruction; //lineinfo | ||
|
||
var setAndLoadSource = module.ImportReference(typeof(ResourceDictionary).GetMethod("SetAndLoadSource")); | ||
yield return Create(Callvirt, module.ImportReference(setAndLoadSource)); | ||
|
||
//ldloc the stored uri as return value | ||
yield return Create(Ldloc, uriVarDef); | ||
} | ||
|
||
static string GetPathForType(ModuleDefinition module, TypeReference type) | ||
{ | ||
foreach (var ca in type.Module.GetCustomAttributes()) { | ||
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(typeof(XamlResourceIdAttribute)))) | ||
continue; | ||
if (!TypeRefComparer.Default.Equals(ca.ConstructorArguments[2].Value as TypeReference, type)) | ||
continue; | ||
return ca.ConstructorArguments[1].Value as string; | ||
} | ||
return null; | ||
} | ||
|
||
static string GetResourceIdForPath(ModuleDefinition module, string path) | ||
{ | ||
foreach (var ca in module.GetCustomAttributes()) { | ||
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(typeof(XamlResourceIdAttribute)))) | ||
continue; | ||
if (ca.ConstructorArguments[1].Value as string != path) | ||
continue; | ||
return ca.ConstructorArguments[0].Value as string; | ||
} | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.