summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks/XamlTask.cs
blob: d4864ac3a35f435ef8de3f599dd37c00d1fd2b48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

using Mono.Cecil;

using Xamarin.Forms.Xaml;

namespace Xamarin.Forms.Build.Tasks
{
	public abstract class XamlTask : AppDomainIsolatedTask
	{
		[Required]
		public string Assembly { get; set; }
		public string DependencyPaths { get; set; }
		public string ReferencePath { get; set; }
		public int Verbosity { get; set; }
		public bool DebugSymbols { get; set; }

		internal XamlTask()
		{
		}

		protected Logger Logger { get; set; }

		public override bool Execute()
		{
			Logger = new Logger(Log, Verbosity);
			return Execute(null);
		}

		public abstract bool Execute(IList<Exception> thrownExceptions);

		protected static MethodDefinition DuplicateMethodDef(TypeDefinition typeDef, MethodDefinition methodDef, string newName)
		{
			var dup = new MethodDefinition(newName, methodDef.Attributes, methodDef.ReturnType);
			dup.Body = methodDef.Body;
			typeDef.Methods.Add(dup);
			return dup;
		}

		internal static ILRootNode ParseXaml(Stream stream, TypeReference typeReference)
		{
			ILRootNode rootnode = null;
			using (var reader = XmlReader.Create(stream)) {
				while (reader.Read()) {
					//Skip until element
					if (reader.NodeType == XmlNodeType.Whitespace)
						continue;
					if (reader.NodeType != XmlNodeType.Element) {
						Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
						continue;
					}

					XamlParser.ParseXaml(
						rootnode = new ILRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), typeReference, reader as IXmlNamespaceResolver), reader);
					break;
				}
			}
			return rootnode;
		}
	}

	static class CecilExtensions
	{
		public static bool IsXaml(this EmbeddedResource resource, out string classname)
		{
			classname = null;
			if (!resource.Name.EndsWith(".xaml", StringComparison.InvariantCulture))
				return false;

			using (var resourceStream = resource.GetResourceStream()) {
				var xmlDoc = new XmlDocument();
				xmlDoc.Load(resourceStream);

				var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);

				var root = xmlDoc.SelectSingleNode("/*", nsmgr);
				if (root == null)
					return false;

				var rootClass = root.Attributes ["Class", "http://schemas.microsoft.com/winfx/2006/xaml"] ??
								root.Attributes ["Class", "http://schemas.microsoft.com/winfx/2009/xaml"];
				if (rootClass == null)
					return false;
				classname = rootClass.Value;
				return true;
			}
		}
	}
}