Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / IlGen / StaticDataManager.cs
blobc04cebf1e9c0d3cc8b87aba16e5e1e1644c5c502
1 //------------------------------------------------------------------------------
2 // <copyright file="StaticDataManager.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
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 {
18 /// <summary>
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.
21 /// </summary>
22 internal class UniqueList<T> {
23 private Dictionary<T, int> lookup = new Dictionary<T, int>();
24 private List<T> list = new List<T>();
26 /// <summary>
27 /// If "value" is already in the list, do not add it. Return the unique ID of the value in the list.
28 /// </summary>
29 public int Add(T value) {
30 int id;
32 if (!this.lookup.ContainsKey(value)) {
33 // The value does not yet exist, so add it to the list
34 id = list.Count;
35 this.lookup.Add(value, id);
36 this.list.Add(value);
38 else {
39 id = this.lookup[value];
42 return id;
45 /// <summary>
46 /// Return an array of the unique values.
47 /// </summary>
48 public T[] ToArray() {
49 return list.ToArray();
54 /// <summary>
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
60 /// </summary>
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;
70 /// <summary>
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.
73 /// </summary>
74 public int DeclareName(string name) {
75 if (this.uniqueNames == null)
76 this.uniqueNames = new UniqueList<string>();
78 return this.uniqueNames.Add(name);
81 /// <summary>
82 /// Return an array of all names that are used by the query (null if no names).
83 /// </summary>
84 public string[] Names {
85 get { return (this.uniqueNames != null) ? this.uniqueNames.ToArray() : null; }
88 /// <summary>
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.
91 /// </summary>
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)));
99 /// <summary>
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).
102 /// </summary>
103 public Int32Pair[] NameFilters {
104 get { return (this.uniqueFilters != null) ? this.uniqueFilters.ToArray() : null; }
107 /// <summary>
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.
110 /// </summary>
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;
133 /// <summary>
134 /// Return an array of all prefix mappings that are used by the query to compute names (null if no mappings).
135 /// </summary>
136 public StringPair[][] PrefixMappingsList {
137 get { return (this.prefixMappingsList != null) ? this.prefixMappingsList.ToArray() : null; }
140 /// <summary>
141 /// Declare a new global variable or parameter.
142 /// </summary>
143 public int DeclareGlobalValue(string name) {
144 int idx;
146 if (this.globalNames == null)
147 this.globalNames = new List<string>();
149 idx = this.globalNames.Count;
150 this.globalNames.Add(name);
151 return idx;
154 /// <summary>
155 /// Return an array containing the names of all global variables and parameters.
156 /// </summary>
157 public string[] GlobalNames {
158 get { return (this.globalNames != null) ? this.globalNames.ToArray() : null; }
161 /// <summary>
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.
164 /// </summary>
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));
172 /// <summary>
173 /// Return an array of all early bound information that is used by the query (null if none is used).
174 /// </summary>
175 public EarlyBoundInfo[] EarlyBound {
176 get {
177 if (this.earlyInfo != null)
178 return this.earlyInfo.ToArray();
180 return null;
184 /// <summary>
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.
187 /// </summary>
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);
196 /// <summary>
197 /// Return an array of all types that are used by the query (null if no names).
198 /// </summary>
199 public XmlQueryType[] XmlTypes {
200 get { return (this.uniqueXmlTypes != null) ? this.uniqueXmlTypes.ToArray() : null; }
203 /// <summary>
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.
206 /// </summary>
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));
214 /// <summary>
215 /// Return an array of all collations that are used by the query (null if no names).
216 /// </summary>
217 public XmlCollation[] Collations {
218 get { return (this.uniqueCollations != null) ? this.uniqueCollations.ToArray() : null; }