XPathExpr.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System.Collections;
  7. using System.Runtime;
  8. using System.Xml.XPath;
  9. using System.Xml.Xsl;
  10. internal enum XPathExprType : byte
  11. {
  12. Unknown,
  13. Or,
  14. And,
  15. Relational,
  16. Union,
  17. LocationPath,
  18. RelativePath,
  19. PathStep,
  20. XsltVariable,
  21. String,
  22. Number,
  23. Function,
  24. XsltFunction,
  25. Math,
  26. Filter,
  27. Path
  28. }
  29. internal class XPathExpr
  30. {
  31. ValueDataType returnType;
  32. XPathExprList subExpr;
  33. XPathExprType type;
  34. bool negate;
  35. bool castRequired;
  36. internal XPathExpr(XPathExprType type, ValueDataType returnType, XPathExprList subExpr)
  37. : this(type, returnType)
  38. {
  39. this.subExpr = subExpr;
  40. }
  41. internal XPathExpr(XPathExprType type, ValueDataType returnType)
  42. {
  43. this.type = type;
  44. this.returnType = returnType;
  45. }
  46. internal virtual bool IsLiteral
  47. {
  48. get
  49. {
  50. return false;
  51. }
  52. }
  53. internal bool Negate
  54. {
  55. get
  56. {
  57. return this.negate;
  58. }
  59. set
  60. {
  61. this.negate = value;
  62. }
  63. }
  64. internal ValueDataType ReturnType
  65. {
  66. get
  67. {
  68. return this.returnType;
  69. }
  70. set
  71. {
  72. this.returnType = value;
  73. }
  74. }
  75. internal int SubExprCount
  76. {
  77. get
  78. {
  79. return (null == this.subExpr) ? 0 : this.subExpr.Count;
  80. }
  81. }
  82. internal XPathExprList SubExpr
  83. {
  84. get
  85. {
  86. if (null == this.subExpr)
  87. {
  88. this.subExpr = new XPathExprList();
  89. }
  90. return this.subExpr;
  91. }
  92. }
  93. internal XPathExprType Type
  94. {
  95. get
  96. {
  97. return this.type;
  98. }
  99. }
  100. internal bool TypecastRequired
  101. {
  102. get
  103. {
  104. return this.castRequired;
  105. }
  106. set
  107. {
  108. this.castRequired = value;
  109. }
  110. }
  111. internal void Add(XPathExpr expr)
  112. {
  113. Fx.Assert(null != expr, "");
  114. this.SubExpr.Add(expr);
  115. }
  116. internal void AddBooleanExpression(XPathExprType boolExprType, XPathExpr expr)
  117. {
  118. Fx.Assert(boolExprType == this.type, "");
  119. // An boolean sub0expression that is of the same type as its container should be merged and flattened
  120. // into its parent
  121. if (boolExprType == expr.Type)
  122. {
  123. XPathExprList subExprList = expr.SubExpr;
  124. for (int i = 0; i < subExprList.Count; ++i)
  125. {
  126. this.AddBooleanExpression(boolExprType, subExprList[i]);
  127. }
  128. }
  129. else
  130. {
  131. this.Add(expr);
  132. }
  133. }
  134. }
  135. internal class XPathExprList
  136. {
  137. ArrayList list;
  138. internal XPathExprList()
  139. {
  140. this.list = new ArrayList(2);
  141. }
  142. internal int Count
  143. {
  144. get
  145. {
  146. return this.list.Count;
  147. }
  148. }
  149. internal XPathExpr this[int index]
  150. {
  151. get
  152. {
  153. return (XPathExpr)this.list[index];
  154. }
  155. }
  156. internal void Add(XPathExpr expr)
  157. {
  158. Fx.Assert(null != expr, "");
  159. this.list.Add(expr);
  160. }
  161. }
  162. internal class XPathConjunctExpr : XPathExpr
  163. {
  164. internal XPathConjunctExpr(XPathExprType type, ValueDataType returnType, XPathExpr left, XPathExpr right)
  165. : base(type, returnType)
  166. {
  167. if (null == left || null == right)
  168. {
  169. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.InvalidExpression));
  170. }
  171. this.SubExpr.Add(left);
  172. this.SubExpr.Add(right);
  173. }
  174. internal XPathExpr Left
  175. {
  176. get
  177. {
  178. return this.SubExpr[0];
  179. }
  180. }
  181. internal XPathExpr Right
  182. {
  183. get
  184. {
  185. return this.SubExpr[1];
  186. }
  187. }
  188. }
  189. internal class XPathRelationExpr : XPathConjunctExpr
  190. {
  191. RelationOperator op;
  192. internal XPathRelationExpr(RelationOperator op, XPathExpr left, XPathExpr right)
  193. : base(XPathExprType.Relational, ValueDataType.Boolean, left, right)
  194. {
  195. this.op = op;
  196. }
  197. internal RelationOperator Op
  198. {
  199. get
  200. {
  201. return this.op;
  202. }
  203. set
  204. {
  205. this.op = value;
  206. }
  207. }
  208. }
  209. internal class XPathMathExpr : XPathConjunctExpr
  210. {
  211. MathOperator op;
  212. internal XPathMathExpr(MathOperator op, XPathExpr left, XPathExpr right)
  213. : base(XPathExprType.Math, ValueDataType.Double, left, right)
  214. {
  215. this.op = op;
  216. }
  217. internal MathOperator Op
  218. {
  219. get
  220. {
  221. return this.op;
  222. }
  223. }
  224. }
  225. internal class XPathFunctionExpr : XPathExpr
  226. {
  227. QueryFunction function;
  228. internal XPathFunctionExpr(QueryFunction function, XPathExprList subExpr)
  229. : base(XPathExprType.Function, function.ReturnType, subExpr)
  230. {
  231. Fx.Assert(null != function, "");
  232. this.function = function;
  233. }
  234. internal QueryFunction Function
  235. {
  236. get
  237. {
  238. return this.function;
  239. }
  240. }
  241. }
  242. internal class XPathXsltFunctionExpr : XPathExpr
  243. {
  244. XsltContext context;
  245. IXsltContextFunction function;
  246. internal XPathXsltFunctionExpr(XsltContext context, IXsltContextFunction function, XPathExprList subExpr)
  247. : base(XPathExprType.XsltFunction, ConvertTypeFromXslt(function.ReturnType), subExpr)
  248. {
  249. this.function = function;
  250. this.context = context;
  251. }
  252. internal XsltContext Context
  253. {
  254. get
  255. {
  256. return this.context;
  257. }
  258. }
  259. internal IXsltContextFunction Function
  260. {
  261. get
  262. {
  263. return this.function;
  264. }
  265. }
  266. internal static XPathResultType ConvertTypeToXslt(ValueDataType type)
  267. {
  268. switch (type)
  269. {
  270. case ValueDataType.Boolean:
  271. return XPathResultType.Boolean;
  272. case ValueDataType.Double:
  273. return XPathResultType.Number;
  274. case ValueDataType.Sequence:
  275. return XPathResultType.NodeSet;
  276. case ValueDataType.String:
  277. return XPathResultType.String;
  278. default:
  279. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.InvalidTypeConversion));
  280. }
  281. }
  282. internal static ValueDataType ConvertTypeFromXslt(XPathResultType type)
  283. {
  284. switch (type)
  285. {
  286. case XPathResultType.Boolean:
  287. return ValueDataType.Boolean;
  288. case XPathResultType.Number:
  289. return ValueDataType.Double;
  290. case XPathResultType.NodeSet:
  291. return ValueDataType.Sequence;
  292. case XPathResultType.String:
  293. return ValueDataType.String;
  294. default:
  295. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.InvalidTypeConversion));
  296. }
  297. }
  298. }
  299. internal class XPathXsltVariableExpr : XPathExpr
  300. {
  301. XsltContext context;
  302. IXsltContextVariable variable;
  303. internal XPathXsltVariableExpr(XsltContext context, IXsltContextVariable variable)
  304. : base(XPathExprType.XsltVariable, XPathXsltFunctionExpr.ConvertTypeFromXslt(variable.VariableType))
  305. {
  306. Fx.Assert(null != variable, "");
  307. this.variable = variable;
  308. this.context = context;
  309. }
  310. internal XsltContext Context
  311. {
  312. get
  313. {
  314. return this.context;
  315. }
  316. }
  317. internal IXsltContextVariable Variable
  318. {
  319. get
  320. {
  321. return this.variable;
  322. }
  323. }
  324. }
  325. internal class XPathStepExpr : XPathExpr
  326. {
  327. NodeSelectCriteria selectDesc;
  328. internal XPathStepExpr(NodeSelectCriteria desc)
  329. : this(desc, null)
  330. {
  331. }
  332. internal XPathStepExpr(NodeSelectCriteria desc, XPathExprList predicates)
  333. : base(XPathExprType.PathStep, ValueDataType.Sequence, predicates)
  334. {
  335. Fx.Assert(null != desc, "");
  336. this.selectDesc = desc;
  337. }
  338. internal NodeSelectCriteria SelectDesc
  339. {
  340. get
  341. {
  342. return this.selectDesc;
  343. }
  344. }
  345. }
  346. internal abstract class XPathLiteralExpr : XPathExpr
  347. {
  348. internal XPathLiteralExpr(XPathExprType type, ValueDataType returnType)
  349. : base(type, returnType)
  350. {
  351. }
  352. internal override bool IsLiteral
  353. {
  354. get
  355. {
  356. return true;
  357. }
  358. }
  359. internal abstract object Literal
  360. {
  361. get;
  362. }
  363. }
  364. internal class XPathStringExpr : XPathLiteralExpr
  365. {
  366. string literal;
  367. internal XPathStringExpr(string literal)
  368. : base(XPathExprType.String, ValueDataType.String)
  369. {
  370. this.literal = literal;
  371. }
  372. internal override object Literal
  373. {
  374. get
  375. {
  376. return this.literal;
  377. }
  378. }
  379. internal string String
  380. {
  381. get
  382. {
  383. return this.literal;
  384. }
  385. }
  386. }
  387. internal class XPathNumberExpr : XPathLiteralExpr
  388. {
  389. double literal;
  390. internal XPathNumberExpr(double literal)
  391. : base(XPathExprType.Number, ValueDataType.Double)
  392. {
  393. this.literal = literal;
  394. }
  395. internal override object Literal
  396. {
  397. get
  398. {
  399. return this.literal;
  400. }
  401. }
  402. internal double Number
  403. {
  404. get
  405. {
  406. return this.literal;
  407. }
  408. }
  409. }
  410. }