public static void Compile(Type type, out MethodDefinition methdoDefinition) { methdoDefinition = null; var assembly = type.Assembly.Location; var refs = from an in type.Assembly.GetReferencedAssemblies() let a = System.Reflection.Assembly.Load(an) select a.Location; var xamlc = new XamlCTask { Assembly = assembly, ReferencePath = string.Join(";", refs), KeepXamlResources = true, OptimizeIL = true, DebugSymbols = false, ReadOnly = true, Type = type.FullName }; IList <Exception> exceptions; if (xamlc.Execute(out exceptions) || exceptions == null || !exceptions.Any()) { methdoDefinition = xamlc.InitCompForType; return; } if (exceptions.Count > 1) { throw new AggregateException(exceptions); } throw exceptions[0]; }
public static void Compile(Type type, out MethodDefinition methdoDefinition) { methdoDefinition = null; var assembly = type.Assembly.Location; var refs = from an in type.Assembly.GetReferencedAssemblies() let a = System.Reflection.Assembly.Load(an) select a.Location; var xamlc = new XamlCTask { Assembly = assembly, ReferencePath = refs.ToArray(), KeepXamlResources = true, OptimizeIL = true, DebugSymbols = false, ValidateOnly = true, Type = type.FullName, BuildEngine = new MSBuild.UnitTests.DummyBuildEngine() }; if (xamlc.Execute(out IList <Exception> exceptions) || exceptions == null || !exceptions.Any()) { methdoDefinition = xamlc.InitCompForType; return; } if (exceptions.Count > 1) { throw new AggregateException(exceptions); } throw exceptions[0]; }
public static void Main(string[] args) { bool help = false; int verbosity = 1; bool keep = false; bool optimize = false; bool decompile = false; string paths = null; string refs = null; List <string> extra = null; var p = new OptionSet { { "h|?|help", "Print this help message", v => help = true }, { "v=|verbosity=", "0 is quiet, 1 is normal, 2 is verbose", v => verbosity = Int32.Parse(v) }, { "o|optimize", "Optimize generated IL", v => optimize = true }, { "keep", "do not strip compiled embedded xaml", v => keep = true }, { "p=|paths=|dependencypaths=", "look for dependencies in (comma separated) list of paths", v => paths = v }, { "r=", "referencepath", v => refs = v }, { "d|decompile", v => decompile = true } }; if (help || args.Length < 1) { ShowHelp(p); Environment.Exit(0); } try { extra = p.Parse(args); } catch (OptionException) { Console.WriteLine("Type `xamlc --help' for more information."); return; } if (extra.Count == 0) { if (verbosity > 0) { Console.WriteLine("assembly missing"); ShowHelp(p); } Environment.Exit(0); } var assembly = extra[0]; var xamlc = new XamlCTask { Assembly = assembly, Verbosity = verbosity, KeepXamlResources = keep, OptimizeIL = optimize, DependencyPaths = paths, ReferencePath = refs, OutputGeneratedILAsCode = decompile, }; xamlc.Execute(null); }
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 static void Compile(Type type) { var assembly = type.Assembly.Location; var refs = from an in type.Assembly.GetReferencedAssemblies() let a = System.Reflection.Assembly.Load(an) select a.Location; var xamlc = new XamlCTask { Assembly = assembly, ReferencePath = string.Join(";", refs), KeepXamlResources = true, Type = type.FullName }; var exceptions = new List <Exception>(); if (!xamlc.Compile(exceptions) && exceptions.Any()) { throw exceptions [0]; } }
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.XFUri, "Source"), out sourceNode); } INode styleNode = null; if (!((IElementNode)node).Properties.TryGetValue(new XmlName("", "Style"), out styleNode) && !((IElementNode)node).Properties.TryGetValue(new XmlName(XamlParser.XFUri, "Style"), out styleNode) && ((IElementNode)node).CollectionItems.Count == 1) { styleNode = ((IElementNode)node).CollectionItems[0]; } if (sourceNode != null && styleNode != null) { throw new XamlParseException("StyleSheet can not have both a Source and a content", node); } if (sourceNode == null && styleNode == null) { throw new XamlParseException("StyleSheet require either a Source or a content", node); } if (styleNode != null && !(styleNode is ValueNode)) { throw new XamlParseException("Style property or Content is not a string literal", node); } if (sourceNode != null && !(sourceNode is ValueNode)) { throw new XamlParseException("Source property is not a string literal", node); } if (styleNode != null) { var style = (styleNode as ValueNode).Value as string; yield return(Create(Ldstr, style)); yield return(Create(Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.StyleSheets", "StyleSheet"), methodName: "FromString", paramCount: 1, predicate: md => md.IsStatic))); } else { var source = (sourceNode as ValueNode)?.Value as string; INode rootNode = node; while (!(rootNode is ILRootNode)) { rootNode = rootNode.Parent; } var rootTargetPath = RDSourceTypeConverter.GetPathForType(module, ((ILRootNode)rootNode).TypeReference); var uri = new Uri(source, UriKind.Relative); var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath); //fail early var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath); if (resourceId == null) { throw new XamlParseException($"Resource '{source}' not found.", node); } 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))); yield return(Create(Ldstr, resourceId)); //resourceId foreach (var instruction in node.PushXmlLineInfo(context)) { yield return(instruction); //lineinfo } yield return(Create(Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.StyleSheets", "StyleSheet"), methodName: "FromAssemblyResource", paramCount: 3, predicate: md => md.IsStatic))); } //the variable is of type `object`. fix that var vardef = new VariableDefinition(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.StyleSheets", "StyleSheet"))); yield return(Create(Stloc, vardef)); vardefref.VariableDefinition = vardef; }
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)));
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.XFUri, "Source"), out sourceNode); } INode styleNode = null; if (!((IElementNode)node).Properties.TryGetValue(new XmlName("", "Style"), out styleNode) && !((IElementNode)node).Properties.TryGetValue(new XmlName(XamlParser.XFUri, "Style"), out styleNode) && ((IElementNode)node).CollectionItems.Count == 1) { styleNode = ((IElementNode)node).CollectionItems[0]; } if (sourceNode != null && styleNode != null) { throw new XamlParseException($"StyleSheet can not have both a Source and a content", node); } if (sourceNode == null && styleNode == null) { throw new XamlParseException($"StyleSheet require either a Source or a content", node); } if (styleNode != null && !(styleNode is ValueNode)) { throw new XamlParseException($"Style property or Content is not a string literal", node); } if (sourceNode != null && !(sourceNode is ValueNode)) { throw new XamlParseException($"Source property is not a string literal", node); } if (styleNode != null) { var style = (styleNode as ValueNode).Value as string; yield return(Create(Ldstr, style)); var fromString = module.ImportReferenceCached(typeof(StyleSheets.StyleSheet).GetMethods().FirstOrDefault(mi => mi.Name == nameof(StyleSheets.StyleSheet.FromString) && mi.GetParameters().Length == 1)); yield return(Create(Call, module.ImportReference(fromString))); } else { string source = (sourceNode as ValueNode)?.Value as string; INode rootNode = node; while (!(rootNode is ILRootNode)) { rootNode = rootNode.Parent; } var rootTargetPath = RDSourceTypeConverter.GetPathForType(module, ((ILRootNode)rootNode).TypeReference); var uri = new Uri(source, UriKind.Relative); var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(uri, rootTargetPath); //fail early var resourceId = XamlCTask.GetResourceIdForPath(module, resourcePath); if (resourceId == null) { throw new XamlParseException($"Resource '{source}' not found.", node); } var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new[] { typeof(RuntimeTypeHandle) })); var getAssembly = module.ImportReferenceCached(typeof(Type).GetProperty(nameof(Type.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 yield return(Create(Ldstr, resourceId)); //resourceId foreach (var instruction in node.PushXmlLineInfo(context)) { yield return(instruction); //lineinfo } var fromAssemblyResource = module.ImportReferenceCached(typeof(StyleSheets.StyleSheet).GetMethods().FirstOrDefault(mi => mi.Name == nameof(StyleSheets.StyleSheet.FromAssemblyResource) && mi.GetParameters().Length == 3)); yield return(Create(Call, module.ImportReference(fromAssemblyResource))); } //the variable is of type `object`. fix that var vardef = new VariableDefinition(module.ImportReferenceCached(typeof(StyleSheets.StyleSheet))); yield return(Create(Stloc, vardef)); vardefref.VariableDefinition = vardef; }
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)); }
public void Modify(IEnumerable <UnityEditor.Compilation.Assembly> lockedAssemblies, IEnumerable <string> sources = null) { var modifiers = new List <ILModifier>(); EditorApplication.LockReloadAssemblies(); try { using (var resolver = new Resolver()) { var xamarin = new ILXamarin(resolver); foreach (var assembly in lockedAssemblies) { var definition = resolver.Add(assembly.outputPath, true); if (definition != null) { modifiers.Add(new ILModifier(assembly, definition)); } } var engine = new Build.BuildEngine(); var logger = new Build.Logger(); logger.Verbosity = Settings.Verbosity; logger.Initialize(engine); while (modifiers.Count > 0) { var modifier = modifiers.Last(); try { foreach (var reference in modifier.compilation.allReferences) { resolver.Add(reference, false); } var modified = modifier.Modify(xamarin, _types, sources); if (modified) { modifier.Write(); } if (modified) { resolver.DisposeAssembly(modifier.compilation.outputPath, modifier.definition); var task = new XamlCTask(); task.BuildEngine = engine; task.Assembly = modifier.compilation.outputPath; task.DebugSymbols = Settings.DebugSymbols.value; task.DebugType = "portable"; task.OptimizeIL = Settings.OptimizeIL.value; task.CompileByDefault = true; task.DefaultAssemblyResolver = resolver; engine.ProjectFileOfTaskNode = task.Assembly; task.Execute(); } } catch (Exception exception) { Debug.LogException(exception); } finally { modifiers.RemoveAt(modifiers.Count - 1); modifier.Dispose(); } } } } finally { EditorApplication.UnlockReloadAssemblies(); foreach (var modifier in modifiers) { modifier.Dispose(); } } }
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)); }