1 //------------------------------------------------------------------------------
2 // <copyright file="StaticDataManager.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 using System
.Collections
;
10 using System
.Collections
.Generic
;
11 using System
.Diagnostics
;
12 using System
.Reflection
;
13 using System
.Xml
.Xsl
.Qil
;
14 using System
.Xml
.Xsl
.Runtime
;
16 namespace System
.Xml
.Xsl
.IlGen
{
19 /// This internal class maintains a list of unique values. Each unique value is assigned a unique ID, which can
20 /// be used to quickly access the value, since it corresponds to the value's position in the list.
22 internal class UniqueList
<T
> {
23 private Dictionary
<T
, int> lookup
= new Dictionary
<T
, int>();
24 private List
<T
> list
= new List
<T
>();
27 /// If "value" is already in the list, do not add it. Return the unique ID of the value in the list.
29 public int Add(T
value) {
32 if (!this.lookup
.ContainsKey(value)) {
33 // The value does not yet exist, so add it to the list
35 this.lookup
.Add(value, id
);
39 id
= this.lookup
[value];
46 /// Return an array of the unique values.
48 public T
[] ToArray() {
49 return list
.ToArray();
55 /// Manages all static data that is used by the runtime. This includes:
56 /// 1. All NCName and QName atoms that will be used at run-time
57 /// 2. All QName filters that will be used at run-time
58 /// 3. All Xml types that will be used at run-time
59 /// 4. All global variables and parameters
61 internal class StaticDataManager
{
62 private UniqueList
<string> uniqueNames
;
63 private UniqueList
<Int32Pair
> uniqueFilters
;
64 private List
<StringPair
[]> prefixMappingsList
;
65 private List
<string> globalNames
;
66 private UniqueList
<EarlyBoundInfo
> earlyInfo
;
67 private UniqueList
<XmlQueryType
> uniqueXmlTypes
;
68 private UniqueList
<XmlCollation
> uniqueCollations
;
71 /// Add "name" to the list of unique names that are used by this query. Return the index of
72 /// the unique name in the list.
74 public int DeclareName(string name
) {
75 if (this.uniqueNames
== null)
76 this.uniqueNames
= new UniqueList
<string>();
78 return this.uniqueNames
.Add(name
);
82 /// Return an array of all names that are used by the query (null if no names).
84 public string[] Names
{
85 get { return (this.uniqueNames != null) ? this.uniqueNames.ToArray() : null; }
89 /// Add a name filter to the list of unique filters that are used by this query. Return the index of
90 /// the unique filter in the list.
92 public int DeclareNameFilter(string locName
, string nsUri
) {
93 if (this.uniqueFilters
== null)
94 this.uniqueFilters
= new UniqueList
<Int32Pair
>();
96 return this.uniqueFilters
.Add(new Int32Pair(DeclareName(locName
), DeclareName(nsUri
)));
100 /// Return an array of all name filters, where each name filter is represented as a pair of integer offsets (localName, namespaceUri)
101 /// into the Names array (null if no name filters).
103 public Int32Pair
[] NameFilters
{
104 get { return (this.uniqueFilters != null) ? this.uniqueFilters.ToArray() : null; }
108 /// Add a list of QilExpression NamespaceDeclarations to an array of strings (prefix followed by namespace URI).
109 /// Return index of the prefix mappings within this array.
111 public int DeclarePrefixMappings(IList
<QilNode
> list
) {
112 StringPair
[] prefixMappings
;
114 // Fill mappings array
115 prefixMappings
= new StringPair
[list
.Count
];
116 for (int i
= 0; i
< list
.Count
; i
++) {
117 // Each entry in mappings array must be a constant NamespaceDeclaration
118 QilBinary ndNmspDecl
= (QilBinary
) list
[i
];
119 Debug
.Assert(ndNmspDecl
!= null);
120 Debug
.Assert(ndNmspDecl
.Left
is QilLiteral
&& ndNmspDecl
.Right
is QilLiteral
);
122 prefixMappings
[i
] = new StringPair((string) (QilLiteral
) ndNmspDecl
.Left
, (string) (QilLiteral
) ndNmspDecl
.Right
);
125 // Add mappings to list and return index
126 if (this.prefixMappingsList
== null)
127 this.prefixMappingsList
= new List
<StringPair
[]>();
129 this.prefixMappingsList
.Add(prefixMappings
);
130 return this.prefixMappingsList
.Count
- 1;
134 /// Return an array of all prefix mappings that are used by the query to compute names (null if no mappings).
136 public StringPair
[][] PrefixMappingsList
{
137 get { return (this.prefixMappingsList != null) ? this.prefixMappingsList.ToArray() : null; }
141 /// Declare a new global variable or parameter.
143 public int DeclareGlobalValue(string name
) {
146 if (this.globalNames
== null)
147 this.globalNames
= new List
<string>();
149 idx
= this.globalNames
.Count
;
150 this.globalNames
.Add(name
);
155 /// Return an array containing the names of all global variables and parameters.
157 public string[] GlobalNames
{
158 get { return (this.globalNames != null) ? this.globalNames.ToArray() : null; }
162 /// Add early bound information to a list that is used by this query. Return the index of
163 /// the early bound information in the list.
165 public int DeclareEarlyBound(string namespaceUri
, Type ebType
) {
166 if (this.earlyInfo
== null)
167 this.earlyInfo
= new UniqueList
<EarlyBoundInfo
>();
169 return this.earlyInfo
.Add(new EarlyBoundInfo(namespaceUri
, ebType
));
173 /// Return an array of all early bound information that is used by the query (null if none is used).
175 public EarlyBoundInfo
[] EarlyBound
{
177 if (this.earlyInfo
!= null)
178 return this.earlyInfo
.ToArray();
185 /// Add "type" to the list of unique types that are used by this query. Return the index of
186 /// the unique type in the list.
188 public int DeclareXmlType(XmlQueryType type
) {
189 if (this.uniqueXmlTypes
== null)
190 this.uniqueXmlTypes
= new UniqueList
<XmlQueryType
>();
192 XmlQueryTypeFactory
.CheckSerializability(type
);
193 return this.uniqueXmlTypes
.Add(type
);
197 /// Return an array of all types that are used by the query (null if no names).
199 public XmlQueryType
[] XmlTypes
{
200 get { return (this.uniqueXmlTypes != null) ? this.uniqueXmlTypes.ToArray() : null; }
204 /// Add "collation" to the list of unique collations that are used by this query. Return the index of
205 /// the unique collation in the list.
207 public int DeclareCollation(string collation
) {
208 if (this.uniqueCollations
== null)
209 this.uniqueCollations
= new UniqueList
<XmlCollation
>();
211 return this.uniqueCollations
.Add(XmlCollation
.Create(collation
));
215 /// Return an array of all collations that are used by the query (null if no names).
217 public XmlCollation
[] Collations
{
218 get { return (this.uniqueCollations != null) ? this.uniqueCollations.ToArray() : null; }