Example #1
0
        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 = XamlCTask.GetPathForType(module, ((ILRootNode)rootNode).TypeReference);
            var uri            = new Uri(value, UriKind.Relative);

            var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);

            //fail early
            var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath);

            if (resourceId == null)
            {
                throw new BuildException(BuildExceptionCode.ResourceMissing, node, null, value);
            }

            var resourceDictionaryType = ("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary");

            //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)
            foreach (var instruction in context.Variables[rdNode].LoadAs(module.GetTypeDefinition(resourceDictionaryType), module))
            {
                yield return(instruction);
            }
            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(("System", "System", "Uri")));

            body.Variables.Add(uriVarDef);
            yield return(Create(Stloc, uriVarDef));

            yield return(Create(Ldstr, resourcePath));            //resourcePath

            yield return(Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference)));

            yield return(Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true)));
        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 = XamlCTask.GetPathForType(module, ((ILRootNode)rootNode).TypeReference);
            var uri            = new Uri(value, UriKind.Relative);

            var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);

            //fail early
            var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath);

            if (resourceId == null)
            {
                throw new XamlParseException($"Resource '{value}' not found.", node);
            }


            //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(("System", "System", "Uri")));

            body.Variables.Add(uriVarDef);
            yield return(Create(Stloc, uriVarDef));

            yield return(Create(Ldstr, resourcePath));            //resourcePath

            yield return(Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference)));

            yield return(Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic)));

            yield return(Create(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", paramCount: 1, predicate: md => md.IsStatic)));

            yield return(Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System.Reflection", "TypeInfo"), propertyName: "Assembly", flatten: true)));

            foreach (var instruction in node.PushXmlLineInfo(context))
            {
                yield return(instruction);                //lineinfo
            }
            yield return(Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"), methodName: "SetAndLoadSource", paramCount: 4)));

            //ldloc the stored uri as return value
            yield return(Create(Ldloc, uriVarDef));
        }
Example #3
0
        public IEnumerable <Instruction> ConvertFromString(string value, ILContext context, BaseNode node)
        {
            var currentModule = 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 = XamlCTask.GetPathForType(currentModule, ((ILRootNode)rootNode).TypeReference);

            var    module  = currentModule;
            string asmName = null;

            if (value.Contains(";assembly="))
            {
                var parts = value.Split(new[] { ";assembly=" }, StringSplitOptions.RemoveEmptyEntries);
                value   = parts[0];
                asmName = parts[1];
                if (currentModule.Assembly.Name.Name != asmName)
                {
                    var ar = currentModule.AssemblyReferences.FirstOrDefault(ar => ar.Name == asmName);
                    if (ar == null)
                    {
                        throw new BuildException(BuildExceptionCode.ResourceMissing, node, null, value);
                    }
                    module = currentModule.AssemblyResolver.Resolve(ar).MainModule;
                }
            }
            var uri = new Uri(value, UriKind.Relative);

            var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);

            //fail early
            var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath);

            if (resourceId == null)
            {
                throw new BuildException(BuildExceptionCode.ResourceMissing, node, null, value);
            }

            var resourceDictionaryType = ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary");

            //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)
            foreach (var instruction in context.Variables[rdNode].LoadAs(currentModule.GetTypeDefinition(resourceDictionaryType), currentModule))
            {
                yield return(instruction);
            }
            //reappend assembly= in all cases, see other RD converter
            if (!string.IsNullOrEmpty(asmName))
            {
                value = $"{value};assembly={asmName}";
            }
            else
            {
                value = $"{value};assembly={((ILRootNode)rootNode).TypeReference.Module.Assembly.Name.Name}";
            }
            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(currentModule.ImportReference(("System", "System", "Uri")));

            body.Variables.Add(uriVarDef);
            yield return(Create(Stloc, uriVarDef));

            yield return(Create(Ldstr, resourcePath));            //resourcePath

            if (!string.IsNullOrEmpty(asmName))
            {
                yield return(Create(Ldstr, asmName));

                yield return(Create(Call, currentModule.ImportMethodReference(("mscorlib", "System.Reflection", "Assembly"), methodName: "Load", parameterTypes: new[] { ("mscorlib", "System", "String") }, isStatic: true)));
Example #4
0
        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 = XamlCTask.GetPathForType(module, ((ILRootNode)rootNode).TypeReference);
            var uri            = new Uri(value, UriKind.Relative);

            var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);

            //fail early
            var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath);

            if (resourceId == null)
            {
                throw new XamlParseException($"Resource '{value}' not found.", node);
            }


            //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, resourcePath));            //resourcePath

            var getTypeFromHandle = module.ImportReference(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
            var getTypeInfo       = module.ImportReference(typeof(System.Reflection.IntrospectionExtensions).GetMethod("GetTypeInfo", new Type[] { typeof(Type) }));
            var getAssembly       = module.ImportReference(typeof(System.Reflection.TypeInfo).GetProperty("Assembly").GetMethod);

            yield return(Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference)));

            yield return(Create(Call, module.ImportReference(getTypeFromHandle)));

            yield return(Create(Call, module.ImportReference(getTypeInfo)));

            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));
        }