File: CompiledValueProviders\StyleSheetProvider.cs
Web Access
Project: src\src\Controls\src\Build.Tasks\Controls.Build.Tasks.csproj (Microsoft.Maui.Controls.Build.Tasks)
using System;
using System.Collections.Generic;
using Microsoft.Maui.Controls.Build.Tasks;
using Microsoft.Maui.Controls.Xaml;
using Mono.Cecil;
using Mono.Cecil.Cil;
using static Mono.Cecil.Cil.Instruction;
using static Mono.Cecil.Cil.OpCodes;
 
namespace Microsoft.Maui.Controls.XamlC
{
	class StyleSheetProvider : ICompiledValueProvider
	{
		public IEnumerable<Instruction> ProvideValue(VariableDefinitionReference vardefref, ModuleDefinition module, BaseNode node, ILContext context)
		{
			INode sourceNode = null;
			((IElementNode)node).Properties.TryGetValue(new XmlName("", "Source"), out sourceNode);
			if (sourceNode == null)
				((IElementNode)node).Properties.TryGetValue(new XmlName(XamlParser.MauiUri, "Source"), out sourceNode);
 
			INode styleNode = null;
			if (!((IElementNode)node).Properties.TryGetValue(new XmlName("", "Style"), out styleNode) &&
				!((IElementNode)node).Properties.TryGetValue(new XmlName(XamlParser.MauiUri, "Style"), out styleNode) &&
				((IElementNode)node).CollectionItems.Count == 1)
				styleNode = ((IElementNode)node).CollectionItems[0];
 
			if (sourceNode != null && styleNode != null)
				throw new BuildException(BuildExceptionCode.StyleSheetSourceOrContent, node, null);
 
			if (sourceNode == null && styleNode == null)
				throw new BuildException(BuildExceptionCode.StyleSheetNoSourceOrContent, node, null);
 
			if (styleNode != null && !(styleNode is ValueNode))
				throw new BuildException(BuildExceptionCode.StyleSheetStyleNotALiteral, node, null);
 
			if (sourceNode != null && !(sourceNode is ValueNode))
				throw new BuildException(BuildExceptionCode.StyleSheetSourceNotALiteral, node, null);
 
			if (styleNode != null)
			{
				var style = (styleNode as ValueNode).Value as string;
				yield return Create(Ldstr, style);
				yield return Create(Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet"),
																	   methodName: "FromString",
																	   parameterTypes: new[] { ("mscorlib", "System", "String") },
																	   isStatic: true));
			}
			else
			{
				var source = (sourceNode as ValueNode)?.Value as string;
				INode rootNode = node;
				while (!(rootNode is ILRootNode))
					rootNode = rootNode.Parent;
 
				var rootTargetPath = RDSourceTypeConverter.GetPathForType(context, module, ((ILRootNode)rootNode).TypeReference);
				var uri = new Uri(source, UriKind.Relative);
 
				var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath);
				//fail early
				if (XamlCTask.GetResourceIdForPath(context.Cache, module, resourcePath) == null)
					throw new XamlParseException($"Resource '{source}' not found.", node);
 
				yield return Create(Ldstr, resourcePath); //resourcePath
 
				yield return Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference));
				yield return Create(Call, module.ImportMethodReference(context.Cache, ("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
				yield return Create(Callvirt, module.ImportPropertyGetterReference(context.Cache, ("mscorlib", "System", "Type"), propertyName: "Assembly", flatten: true)); //assembly
 
				foreach (var instruction in node.PushXmlLineInfo(context))
					yield return instruction; //lineinfo
 
				yield return Create(Call, module.ImportMethodReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet"),
																	   methodName: "FromResource",
																	   parameterTypes: new[] { ("mscorlib", "System", "String"), ("mscorlib", "System.Reflection", "Assembly"), ("System.Xml.ReaderWriter", "System.Xml", "IXmlLineInfo") },
																	   isStatic: true));
			}
 
			//the variable is of type `object`. fix that
			var vardef = new VariableDefinition(module.ImportReference(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.StyleSheets", "StyleSheet")));
			yield return Create(Stloc, vardef);
			vardefref.VariableDefinition = vardef;
		}
	}
}