summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/BuildAssembler/BuildComponents/References.cs
blob: ba23c6f176b9e93645bdf0f40dc62a814bb29ab0 (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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// Copyright © Microsoft Corporation.
// This source file is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace BuildComponents {

    public interface ISimpleReference {

        string Id { get; }

    }

    public abstract partial class Reference { }

    // Namespace

    public partial class NamespaceReference : Reference, ISimpleReference {

        internal NamespaceReference (string id) {
            this.namespaceId = id;
        }

        private string namespaceId;

        public string Id {
            get {
                return (namespaceId);
            }
        }

    }

    // Type

    public abstract partial class TypeReference : Reference { }

    public partial class SimpleTypeReference : TypeReference {

        internal SimpleTypeReference (string id) {
            this.typeId = id;
        }

        private string typeId;

        public string Id {
            get {
                return (typeId);
            }
        }


    }

    public partial class ReferenceTypeReference : TypeReference {

        private TypeReference referedToType;

        public TypeReference ReferedToType {
            get {
                return (referedToType);
            }
        }

        internal ReferenceTypeReference (TypeReference referedToType) {
            if (referedToType == null) throw new ArgumentNullException("referedToType");
            this.referedToType = referedToType;
        }
    }

    public partial class PointerTypeReference : TypeReference {

        internal PointerTypeReference (TypeReference pointedToType) {
            if (pointedToType == null) throw new ArgumentNullException("pointedToType");
            this.pointedToType = pointedToType;
        }

        private TypeReference pointedToType;

        public TypeReference PointedToType {
            get {
                return (pointedToType);
            }
        }

    }

    public partial class ArrayTypeReference : TypeReference {

        internal ArrayTypeReference (TypeReference elementType, int rank) {
            if (elementType == null) throw new ArgumentNullException("elementType");
            if (rank <= 0) throw new ArgumentOutOfRangeException("rank");
            this.elementType = elementType;
            this.rank = rank;
        }

        private int rank;

        private TypeReference elementType;

        public int Rank {
            get {
                return (rank);
            }
        }

        public TypeReference ElementType {
            get {
                return (elementType);
            }
        }

    }

    public class TemplateTypeReference : TypeReference {

        internal TemplateTypeReference (string templateId, int position) {
            if (template == null) throw new ArgumentNullException("template");
            if (position < 0) throw new ArgumentOutOfRangeException("position");
            this.template = null;   // fix this: create a reference
            this.position = position;
        }

        internal TemplateTypeReference (ISimpleReference template, int position) {
            if (template == null) throw new ArgumentNullException("template");
            if (position < 0) throw new ArgumentOutOfRangeException("position");
            this.template = template;
            this.position = position;
        }

        private ISimpleReference template;

        private int position;
    }

    public abstract partial class MemberReference : Reference {}

    public partial class SimpleMemberReference : MemberReference, ISimpleReference {

        internal SimpleMemberReference (string id) {
            if (id == null) throw new ArgumentNullException("id");
            this.memberId = id;
        }

        private string memberId;

        public string Id {
            get {
                return(memberId);
            }
        }



    }




    // ***** XML PARSING ****

    public partial class Reference {

        public static Reference Create (XmlReader element) {
            if (element == null) throw new ArgumentNullException("element");
            switch (element.LocalName) {
                case "namespace":
                    return (NamespaceReference.Create(element));
                case "member":
                return (MemberReference.Create(element));
                default:
                    return (TypeReference.Create(element));
            }
        }

        public static Reference Create (XPathNavigator node) {
            if (node == null) throw new ArgumentNullException("node");
            if (node.NodeType == XPathNodeType.Element) {
                string tag = node.LocalName;
                if (tag == "namespace") return (NamespaceReference.Create(node));
                //if (tag == "member") return (MemberReference.Create(node));
                return (TypeReference.Create(node));
            } else {
                return (null);
            }
        }

        protected static  XPathExpression referenceApiExpression = XPathExpression.Compile("string(@api)");


    }

    public partial class NamespaceReference {

        public static new NamespaceReference Create (XmlReader space) {
            if (space == null) throw new ArgumentNullException("space");

            string api = space.GetAttribute("api");

            return(new NamespaceReference(api));

        }

        public static new NamespaceReference Create (XPathNavigator space) {
            if (space == null) throw new ArgumentNullException("space");
            string api = (string) space.Evaluate(referenceApiExpression);
            return(new NamespaceReference(api));
        }

    }

    public partial class TypeReference {

        public static new TypeReference Create (XmlReader element) {
            if (element == null) throw new ArgumentNullException("element");
            switch (element.LocalName) {
                case "type":
                    // also handle specialization!
                    return(SimpleTypeReference.Create(element));
                case "referenceTo":
                    return(ReferenceTypeReference.Create(element));
                case "pointerTo":
                    return(PointerTypeReference.Create(element));
                case "arrayOf":
                    return(ArrayTypeReference.Create(element));

            }
            return (null);
        }

        public static new TypeReference Create (XPathNavigator element) {
            if (element == null) throw new ArgumentNullException("element");
            string tag = element.LocalName;
            if (tag == "type") {
                bool isSpecialized = (bool)element.Evaluate("boolean(.//specialization)");
                if (isSpecialized) {
                    // deal with specialization!
                    // return (CreateSpecializedTypeReference(element));
                    return (SimpleTypeReference.Create(element));
                } else {
                    return (SimpleTypeReference.Create(element));
                }
            } else if (tag == "arrayOf") {
                string rankValue = element.GetAttribute("rank", String.Empty);
                XPathNavigator elementNode = element.SelectSingleNode("*[1]");
                return (new ArrayTypeReference(TypeReference.Create(elementNode), Convert.ToInt32(rankValue)));
            } else if (tag == "referenceTo") {
                XPathNavigator referedToNode = element.SelectSingleNode("*[1]");
                return (new ReferenceTypeReference(TypeReference.Create(referedToNode)));
            } else if (tag == "pointerTo") {
                XPathNavigator pointedToNode = element.SelectSingleNode("*[1]");
                return (new PointerTypeReference(TypeReference.Create(pointedToNode)));
            } else if (tag == "template") {
                //string nameValue = element.GetAttribute("name", String.Empty);
                string indexValue = element.GetAttribute("index", String.Empty);
                string apiValue = element.GetAttribute("api", String.Empty);
                if ((!String.IsNullOrEmpty(apiValue)) && (!String.IsNullOrEmpty(indexValue))) {
                    return (new TemplateTypeReference(apiValue, Convert.ToInt32(indexValue)));
                    // return (new IndexedTemplateTypeReference(apiValue, Convert.ToInt32(indexValue)));
                } else {
                    throw new InvalidOperationException();
                    // return (new NamedTemplateTypeReference(nameValue));
                }
            }

            throw new InvalidOperationException(String.Format("INVALID '{0}'", tag));
        }

    }

    public partial class SimpleTypeReference {

        public static new SimpleTypeReference Create (XmlReader type) {
            if (type == null) throw new ArgumentNullException("type");
            string api = type.GetAttribute("api");
            return (new SimpleTypeReference(api));
        }

        public static new SimpleTypeReference Create  (XPathNavigator type) {
            if (type == null) throw new ArgumentNullException("type");
            string api = (string)type.Evaluate(referenceApiExpression);
            return(new SimpleTypeReference(api));
        }

    }

    public partial class ReferenceTypeReference {

        public static new ReferenceTypeReference Create (XmlReader referenceTo) {
            if (referenceTo == null) throw new ArgumentException("refernceTo");
            referenceTo.Read();
            TypeReference referedToType = TypeReference.Create(referenceTo);
            return (new ReferenceTypeReference(referedToType));
        }

        public static new ReferenceTypeReference Create (XPathNavigator referenceTo) {
            XPathNavigator referedToNode = referenceTo.SelectSingleNode("*[1]");
            TypeReference referedToType = TypeReference.Create(referedToNode);
            return (new ReferenceTypeReference(referedToType));
        }
    }

    public partial class PointerTypeReference {

        public static new PointerTypeReference Create (XmlReader pointerTo) {
            if (pointerTo == null) throw new ArgumentNullException("pointerTo");
            pointerTo.Read();
            TypeReference pointedToType = TypeReference.Create(pointerTo);
            return (new PointerTypeReference(pointedToType));
        }

        public static new PointerTypeReference Create (XPathNavigator pointerTo) {
            XPathNavigator pointedToNode = pointerTo.SelectSingleNode("*[1]");
            TypeReference pointedToType = TypeReference.Create(pointedToNode);
            return (new PointerTypeReference(pointedToType));
        }
    }

    public partial class ArrayTypeReference {

        public static new ArrayTypeReference Create (XmlReader arrayOf) {
            if (arrayOf == null) throw new ArgumentNullException("arrayOf");

            int rank = 1;
            string rankText = arrayOf.GetAttribute("rank");
            if (!String.IsNullOrEmpty(rankText)) rank = Convert.ToInt32(rankText);

            arrayOf.Read();
            TypeReference elementType = TypeReference.Create(arrayOf);

            return (new ArrayTypeReference(elementType, rank));
        }
    }
}