This repository has been archived by the owner on May 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
XamlTask.cs
122 lines (103 loc) · 3.42 KB
/
XamlTask.cs
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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;
using Mono.Cecil.Cil;
using Mono.Cecil.Pdb;
using Mono.Cecil.Mdb;
using System.ComponentModel;
namespace Xamarin.Forms.Build.Tasks
{
[LoadInSeparateAppDomain]
public abstract class XamlTask : MarshalByRefObject, ITask
{
[Required]
public string Assembly { get; set; }
public string DependencyPaths { get; set; }
public string ReferencePath { get; set; }
[Obsolete("this is no longer used")]
[EditorBrowsable(EditorBrowsableState.Never)]
public int Verbosity { get; set; }
public bool DebugSymbols { get; set; }
public string DebugType { get; set; }
protected TaskLoggingHelper LoggingHelper { get; }
internal XamlTask()
{
LoggingHelper = new TaskLoggingHelper(this);
}
public IBuildEngine BuildEngine { get; set; }
public ITaskHost HostObject { get; set; }
public bool Execute()
{
IList<Exception> _;
return Execute(out _);
}
public abstract bool Execute(out IList<Exception> thrownExceptions);
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, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition), reader);
break;
}
}
return rootnode;
}
}
static class CecilExtensions
{
public static bool IsXaml(this EmbeddedResource resource, ModuleDefinition module, 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", XamlParser.X2006Uri] ??
root.Attributes["Class", XamlParser.X2009Uri];
if (rootClass != null) {
classname = rootClass.Value;
return true;
}
//no x:Class, but it might be a RD without x:Class and with <?xaml-comp compile="true" ?>
//in that case, it has a XamlResourceIdAttribute
var typeRef = GetTypeForResourceId(module, resource.Name);
if (typeRef != null) {
classname = typeRef.FullName;
return true;
}
return false;
}
}
static TypeReference GetTypeForResourceId(ModuleDefinition module, string resourceId)
{
foreach (var ca in module.GetCustomAttributes()) {
if (!TypeRefComparer.Default.Equals(ca.AttributeType, module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "XamlResourceIdAttribute"))))
continue;
if (ca.ConstructorArguments[0].Value as string != resourceId)
continue;
return ca.ConstructorArguments[2].Value as TypeReference;
}
return null;
}
}
}