XPath2Expression.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155
  1. //
  2. // XPath2Expression.cs - abstract syntax tree for XPath 2.0
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. //
  8. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. #if NET_2_0
  30. using System;
  31. using System.Collections;
  32. using System.Globalization;
  33. using System.Xml;
  34. using System.Xml.Query;
  35. using System.Xml.Schema;
  36. using System.Xml.XPath;
  37. using Mono.Xml.XQuery;
  38. namespace Mono.Xml.XPath2
  39. {
  40. public class ExprSequence : CollectionBase
  41. {
  42. public ExprSequence ()
  43. {
  44. }
  45. public void Add (ExprSingle expr)
  46. {
  47. List.Add (expr);
  48. }
  49. public void AddRange (ICollection items)
  50. {
  51. if (items != null)
  52. foreach (ExprSingle e in items)
  53. List.Add (e);
  54. }
  55. public void Insert (int pos, ExprSingle expr)
  56. {
  57. List.Insert (pos, expr);
  58. }
  59. public ExprSingle this [int i] {
  60. get { return List [i] as ExprSingle; }
  61. set { List [i] = value; }
  62. }
  63. internal void CheckReference (XQueryASTCompiler compiler)
  64. {
  65. foreach (ExprSingle expr in List)
  66. expr.CheckReference (compiler);
  67. }
  68. }
  69. public abstract class ExprSingle
  70. {
  71. internal abstract void CheckReference (XQueryASTCompiler compiler);
  72. #region CompileAndEvaluate
  73. internal static readonly XPathAtomicValue AtomicTrue = new XPathAtomicValue (true, XmlSchemaSimpleType.XsBoolean);
  74. internal static readonly XPathAtomicValue AtomicFalse = new XPathAtomicValue (false, XmlSchemaSimpleType.XsBoolean);
  75. XQueryStaticContext ctx;
  76. internal ExprSingle Compile (XQueryASTCompiler compiler)
  77. {
  78. this.ctx = ctx;
  79. return CompileCore (compiler);
  80. }
  81. // If internal&&protected is available in C#, it is the best signature.
  82. internal abstract ExprSingle CompileCore (XQueryASTCompiler compiler);
  83. internal XQueryStaticContext Context {
  84. get { return ctx; }
  85. }
  86. public abstract SequenceType StaticType { get; }
  87. /** <summary>
  88. This is the core part of ExprSingle. It is
  89. generally used to evaluate expression and returns
  90. XPathItem sequence (iterator). The result is unordered
  91. */
  92. public abstract XPathSequence Evaluate (XPathSequence iter);
  93. public virtual XPathSequence EvaluateOrdered (XPathSequence iter)
  94. {
  95. if (RequireSorting) {
  96. ArrayList al = new ArrayList ();
  97. foreach (XPathItem item in Evaluate (iter))
  98. al.Add (item);
  99. return new ListIterator (iter, al);
  100. }
  101. else
  102. return Evaluate (iter);
  103. }
  104. public virtual void Serialize (XPathSequence iter)
  105. {
  106. XmlWriter w = iter.Context.Writer;
  107. XPathSequence result = Evaluate (iter);
  108. foreach (XPathItem item in result)
  109. WriteXPathItem (item, w);
  110. }
  111. private void WriteXPathItem (XPathItem item, XmlWriter w)
  112. {
  113. if (item.IsNode) {
  114. XPathNavigator nav = item as XPathNavigator;
  115. nav.WriteSubtree (w);
  116. } else
  117. w.WriteValue (item.Value);
  118. }
  119. // get EBV
  120. public virtual bool EvaluateAsBoolean (XPathSequence iter)
  121. {
  122. XPathAtomicValue v = Atomize (Evaluate (iter));
  123. return v != null ? v.ValueAsBoolean : false;
  124. }
  125. public virtual int EvaluateAsInt (XPathSequence iter)
  126. {
  127. XPathAtomicValue v = Atomize (Evaluate (iter));
  128. return v != null ? v.ValueAsInt32 : 0;
  129. }
  130. public virtual string EvaluateAsString (XPathSequence iter)
  131. {
  132. XPathAtomicValue v = Atomize (Evaluate (iter));
  133. return v != null ? v.Value : String.Empty;
  134. }
  135. // FIXME: What if iter contains list value?
  136. public static XPathAtomicValue Atomize (XPathSequence iter)
  137. {
  138. if (!iter.MoveNext ())
  139. return null;
  140. XPathNavigator nav = iter.Current as XPathNavigator;
  141. if (nav != null)
  142. return new XPathAtomicValue (nav.TypedValue, nav.SchemaInfo.SchemaType);
  143. else
  144. return (XPathAtomicValue) iter.Current;
  145. }
  146. public virtual XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  147. {
  148. return Atomize (Evaluate (iter));
  149. }
  150. public virtual bool RequireSorting {
  151. get { return false; }
  152. }
  153. #endregion
  154. }
  155. // FLWORExpr
  156. internal class FLWORExpr : ExprSingle
  157. {
  158. public FLWORExpr (ForLetClauseCollection forlet, ExprSequence whereClause, OrderSpecList orderBy, ExprSingle ret)
  159. {
  160. this.fl = forlet;
  161. this.whereClause = whereClause;
  162. this.orderBy = orderBy;
  163. this.ret = ret;
  164. }
  165. ForLetClauseCollection fl;
  166. ExprSequence whereClause;
  167. OrderSpecList orderBy;
  168. ExprSingle ret;
  169. public ForLetClauseCollection ForLetClauses {
  170. get { return fl; }
  171. }
  172. public ExprSequence WhereClause {
  173. get { return whereClause; }
  174. }
  175. public OrderSpecList OrderBy {
  176. get { return orderBy; }
  177. }
  178. public ExprSingle ReturnExpr {
  179. get { return ret; }
  180. set { ret = value; }
  181. }
  182. // ExprSingle Overrides
  183. internal override void CheckReference (XQueryASTCompiler compiler)
  184. {
  185. foreach (ForLetClause flc in fl)
  186. foreach (ForLetSingleBody single in flc)
  187. single.CheckReference (compiler);
  188. if (whereClause != null)
  189. whereClause.CheckReference (compiler);
  190. if (orderBy != null)
  191. foreach (OrderSpec os in orderBy)
  192. os.Expression.CheckReference (compiler);
  193. ret.CheckReference (compiler);
  194. }
  195. #region CompileAndEvaluate
  196. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  197. {
  198. foreach (ForLetClause flc in ForLetClauses) {
  199. foreach (ForLetSingleBody flsb in flc) {
  200. flsb.Expression = flsb.Expression.Compile (compiler);
  201. if (flsb.ReturnType != null)
  202. compiler.CheckType (flsb.Expression, flsb.ReturnType);
  203. }
  204. }
  205. if (WhereClause != null)
  206. for (int i = 0; i < WhereClause.Count; i++)
  207. WhereClause [i] = WhereClause [i].Compile (compiler);
  208. if (OrderBy != null)
  209. foreach (OrderSpec os in OrderBy)
  210. os.Expression = os.Expression.Compile (compiler);
  211. ReturnExpr = ReturnExpr.Compile (compiler);
  212. return this;
  213. }
  214. public override SequenceType StaticType {
  215. get { return ReturnExpr.StaticType; }
  216. }
  217. public override XPathSequence Evaluate (XPathSequence iter)
  218. {
  219. return new FLWORIterator (iter, this);
  220. }
  221. #endregion
  222. }
  223. internal class ForLetClauseCollection : CollectionBase
  224. {
  225. public void Add (ForLetClause clause)
  226. {
  227. List.Add (clause);
  228. }
  229. public void Insert (int pos, ForLetClause clause)
  230. {
  231. List.Insert (pos, clause);
  232. }
  233. public ForLetClause this [int i] {
  234. get { return (ForLetClause) List [i]; }
  235. }
  236. }
  237. internal class OrderSpecList : CollectionBase
  238. {
  239. bool isStable;
  240. public OrderSpecList ()
  241. {
  242. }
  243. public bool IsStable {
  244. get { return isStable; }
  245. set { isStable = value; }
  246. }
  247. public void Insert (int pos, OrderSpec os)
  248. {
  249. List.Insert (pos, os);
  250. }
  251. public void Add (OrderSpec spec)
  252. {
  253. List.Add (spec);
  254. }
  255. public OrderSpec this [int i] {
  256. get { return (OrderSpec) List [i]; }
  257. }
  258. }
  259. internal class OrderSpec
  260. {
  261. public OrderSpec (ExprSingle expr, OrderModifier modifier)
  262. {
  263. this.expr = expr;
  264. this.mod = modifier;
  265. }
  266. ExprSingle expr;
  267. OrderModifier mod;
  268. public ExprSingle Expression {
  269. get {return expr; }
  270. set { expr = value; }
  271. }
  272. public OrderModifier Modifier {
  273. get { return mod; }
  274. set { mod = value; }
  275. }
  276. }
  277. internal class OrderModifier
  278. {
  279. public OrderModifier (XmlSortOrder order, XmlSortOrder emptyOrder, string collation)
  280. {
  281. this.sortOrder = sortOrder;
  282. this.emptyOrder = emptyOrder;
  283. if (collation != null)
  284. this.coll = new CultureInfo (collation);
  285. }
  286. XmlSortOrder sortOrder;
  287. XmlSortOrder emptyOrder;
  288. CultureInfo coll;
  289. public XmlSortOrder SortOrder {
  290. get { return sortOrder; }
  291. }
  292. public XmlSortOrder EmptyOrder {
  293. get { return emptyOrder; }
  294. }
  295. public CultureInfo Collation {
  296. get { return coll; }
  297. }
  298. }
  299. internal class ForLetClause : CollectionBase
  300. {
  301. public ForLetSingleBody this [int i] {
  302. get { return (ForLetSingleBody) List [i]; }
  303. }
  304. }
  305. internal class ForClause : ForLetClause
  306. {
  307. public ForClause ()
  308. {
  309. }
  310. public void Insert (int pos, ForSingleBody body)
  311. {
  312. List.Insert (pos, body);
  313. }
  314. public void Add (ForSingleBody body)
  315. {
  316. List.Add (body);
  317. }
  318. }
  319. internal class LetClause : ForLetClause
  320. {
  321. public LetClause ()
  322. {
  323. }
  324. public void Insert (int pos, LetSingleBody body)
  325. {
  326. List.Insert (pos, body);
  327. }
  328. public void Add (LetSingleBody body)
  329. {
  330. List.Add (body);
  331. }
  332. }
  333. internal abstract class ForLetSingleBody
  334. {
  335. XmlQualifiedName varName;
  336. SequenceType type;
  337. ExprSingle expr;
  338. public ForLetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
  339. {
  340. this.varName = varName;
  341. this.type = type;
  342. this.expr = expr;
  343. }
  344. public XmlQualifiedName VarName {
  345. get { return varName; }
  346. }
  347. public SequenceType ReturnType {
  348. get { return type; }
  349. }
  350. public ExprSingle Expression {
  351. get { return expr; }
  352. set { expr = value; }
  353. }
  354. internal void CheckReference (XQueryASTCompiler compiler)
  355. {
  356. if (type != null)
  357. compiler.CheckSchemaType (type);
  358. expr.CheckReference (compiler);
  359. }
  360. }
  361. internal class ForSingleBody : ForLetSingleBody
  362. {
  363. public ForSingleBody (XmlQualifiedName varName, SequenceType type, XmlQualifiedName positionalVar, ExprSingle expr)
  364. : base (varName, type, expr)
  365. {
  366. this.positionalVar = positionalVar;
  367. }
  368. XmlQualifiedName positionalVar;
  369. public XmlQualifiedName PositionalVar {
  370. get { return positionalVar; }
  371. }
  372. }
  373. internal class LetSingleBody : ForLetSingleBody
  374. {
  375. public LetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
  376. : base (varName, type, expr)
  377. {
  378. }
  379. }
  380. // QuantifiedExpr
  381. internal class QuantifiedExpr : ExprSingle
  382. {
  383. QuantifiedExprBodyList body;
  384. ExprSingle satisfies;
  385. bool every;
  386. public QuantifiedExpr (bool every, QuantifiedExprBodyList body, ExprSingle satisfies)
  387. {
  388. this.every = every;
  389. this.body = body;
  390. this.satisfies = satisfies;
  391. }
  392. public bool Every {
  393. get { return every; }
  394. }
  395. public QuantifiedExprBodyList BodyList {
  396. get { return body; }
  397. }
  398. public ExprSingle Satisfies {
  399. get { return satisfies; }
  400. set { satisfies = value; }
  401. }
  402. internal override void CheckReference (XQueryASTCompiler compiler)
  403. {
  404. foreach (QuantifiedExprBody one in body) {
  405. if (one.Type != null)
  406. compiler.CheckSchemaType (one.Type);
  407. one.Expression.CheckReference (compiler);
  408. }
  409. Satisfies.CheckReference (compiler);
  410. }
  411. #region CompileAndEvaluate
  412. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  413. {
  414. Satisfies = Satisfies.Compile (compiler);
  415. for (int i = 0; i < BodyList.Count; i++) {
  416. BodyList [i].Expression = BodyList [i].Expression.Compile (compiler);
  417. if (BodyList [i].Type != null)
  418. compiler.CheckType (BodyList [i].Expression, BodyList [i].Type);
  419. }
  420. return this;
  421. }
  422. public override SequenceType StaticType {
  423. get { return SequenceType.Boolean; }
  424. }
  425. public override XPathSequence Evaluate (XPathSequence iter)
  426. {
  427. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
  428. }
  429. public override bool EvaluateAsBoolean (XPathSequence iter)
  430. {
  431. foreach (QuantifiedExprBody qb in BodyList) {
  432. XPathSequence seq = qb.Expression.Evaluate (iter);
  433. // FIXME: consider qb.Type
  434. // if (!qb.Type.IsValid (seq))
  435. // throw new XmlQueryException ("Quantified expression resulted in type promotion error.");
  436. iter.Context.PushVariable (qb.VarName, seq);
  437. }
  438. bool result = every;
  439. foreach (XPathItem item in iter) {
  440. if (satisfies.EvaluateAsBoolean (new SingleItemIterator (item, iter))) {
  441. if (!every) {
  442. result = true;
  443. break;
  444. }
  445. }
  446. else if (every) {
  447. result = false;
  448. break;
  449. }
  450. }
  451. for (int i = 0; i < BodyList.Count; i++)
  452. iter.Context.PopVariable ();
  453. return result;
  454. }
  455. #endregion
  456. }
  457. internal class QuantifiedExprBodyList : CollectionBase
  458. {
  459. public QuantifiedExprBodyList ()
  460. {
  461. }
  462. public void Add (QuantifiedExprBody body)
  463. {
  464. List.Add (body);
  465. }
  466. public void Insert (int pos, QuantifiedExprBody body)
  467. {
  468. List.Insert (pos, body);
  469. }
  470. public QuantifiedExprBody this [int i] {
  471. get { return (QuantifiedExprBody) List [i]; }
  472. }
  473. }
  474. internal class QuantifiedExprBody
  475. {
  476. private XmlQualifiedName varName;
  477. private SequenceType type;
  478. private ExprSingle expr;
  479. public QuantifiedExprBody (XmlQualifiedName varName,
  480. SequenceType type, ExprSingle expr)
  481. {
  482. this.varName = varName;
  483. this.type = type ;
  484. this.expr = expr;
  485. }
  486. public XmlQualifiedName VarName {
  487. get { return varName; }
  488. }
  489. public SequenceType Type {
  490. get { return type; }
  491. }
  492. public ExprSingle Expression {
  493. get { return expr; }
  494. set { expr = value; }
  495. }
  496. }
  497. // TypeswitchExpr
  498. internal class TypeswitchExpr : ExprSingle
  499. {
  500. ExprSequence switchExpr;
  501. CaseClauseList caseList;
  502. XmlQualifiedName defaultVarName;
  503. ExprSingle defaultReturn;
  504. public TypeswitchExpr (ExprSequence switchExpr, CaseClauseList caseList, XmlQualifiedName defaultVarName, ExprSingle defaultReturn)
  505. {
  506. }
  507. public ExprSequence SwitchExpr {
  508. get { return switchExpr; }
  509. }
  510. public CaseClauseList Cases {
  511. get { return caseList; }
  512. }
  513. public XmlQualifiedName DefaultVarName {
  514. get { return defaultVarName; }
  515. }
  516. public ExprSingle DefaultReturn {
  517. get { return defaultReturn; }
  518. set { defaultReturn = value; }
  519. }
  520. internal override void CheckReference (XQueryASTCompiler compiler)
  521. {
  522. switchExpr.CheckReference (compiler);
  523. foreach (CaseClause cc in caseList) {
  524. compiler.CheckSchemaType (cc.Type);
  525. cc.Expr.CheckReference (compiler);
  526. }
  527. defaultReturn.CheckReference (compiler);
  528. }
  529. #region CompileAndEvaluate
  530. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  531. {
  532. for (int i = 0; i < SwitchExpr.Count; i++)
  533. SwitchExpr [i] = SwitchExpr [i].Compile (compiler);
  534. foreach (CaseClause cc in Cases)
  535. cc.Expr = cc.Expr.Compile (compiler);
  536. DefaultReturn = DefaultReturn.Compile (compiler);
  537. return this;
  538. }
  539. // FIXME: it can be optimized by checking all case clauses.
  540. public override SequenceType StaticType {
  541. get { return SequenceType.AnyType; }
  542. }
  543. public override XPathSequence Evaluate (XPathSequence iter)
  544. {
  545. // FIXME: should move to iterator?
  546. XPathSequence cond = new ExprSequenceIterator (iter, SwitchExpr);
  547. XPathSequence ret = null;
  548. foreach (CaseClause ccc in Cases) {
  549. if (ccc.Type.Matches (cond)) {
  550. if (ccc.VarName != XmlQualifiedName.Empty)
  551. iter.Context.PushVariable (ccc.VarName, cond);
  552. ret = ccc.Expr.Evaluate (iter);
  553. // FIXME: The design should make sure that in-scope variables are held on actual iteration.
  554. if (ccc.VarName != XmlQualifiedName.Empty)
  555. iter.Context.PopVariable ();
  556. return ret;
  557. }
  558. }
  559. if (DefaultVarName != XmlQualifiedName.Empty)
  560. iter.Context.PushVariable (DefaultVarName, cond);
  561. ret = DefaultReturn.Evaluate (iter);
  562. if (DefaultVarName != XmlQualifiedName.Empty)
  563. iter.Context.PopVariable ();
  564. return ret;
  565. }
  566. #endregion
  567. }
  568. internal class CaseClauseList : CollectionBase
  569. {
  570. public void Insert (int pos, CaseClause cc)
  571. {
  572. List.Insert (pos, cc);
  573. }
  574. public void Add (CaseClause cc)
  575. {
  576. List.Add (cc);
  577. }
  578. public CaseClause this [int i] {
  579. get { return (CaseClause) List [i]; }
  580. }
  581. }
  582. internal class CaseClause
  583. {
  584. public CaseClause (SequenceType type, ExprSingle expr, XmlQualifiedName varName)
  585. {
  586. this.type = type;
  587. this.expr = expr;
  588. this.varName = varName;
  589. }
  590. SequenceType type;
  591. ExprSingle expr;
  592. XmlQualifiedName varName;
  593. public SequenceType Type {
  594. get { return type; }
  595. }
  596. public ExprSingle Expr {
  597. get { return expr; }
  598. set { expr = value; }
  599. }
  600. public XmlQualifiedName VarName {
  601. get { return varName; }
  602. set { varName = value; }
  603. }
  604. }
  605. // IfExpr
  606. internal class IfExpr : ExprSingle
  607. {
  608. public IfExpr (ExprSequence condition, ExprSingle trueExpr, ExprSingle falseExpr)
  609. {
  610. this.condition = condition;
  611. this.trueExpr = trueExpr;
  612. this.falseExpr = falseExpr;
  613. }
  614. ExprSequence condition;
  615. ExprSingle trueExpr;
  616. ExprSingle falseExpr;
  617. public ExprSequence Condition {
  618. get { return condition; }
  619. set { condition = value; }
  620. }
  621. public ExprSingle TrueExpr {
  622. get { return trueExpr; }
  623. set { trueExpr = value; }
  624. }
  625. public ExprSingle FalseExpr {
  626. get { return falseExpr; }
  627. set { falseExpr = value; }
  628. }
  629. internal override void CheckReference (XQueryASTCompiler compiler)
  630. {
  631. condition.CheckReference (compiler);
  632. trueExpr.CheckReference (compiler);
  633. falseExpr.CheckReference (compiler);
  634. }
  635. #region CompileAndEvaluate
  636. SequenceType computedReturnType;
  637. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  638. {
  639. for (int i = 0; i < Condition.Count; i++)
  640. Condition [i] = Condition [i].Compile (compiler);
  641. // FIXME: check if condition is constant, and returns trueExpr or falseExpr
  642. TrueExpr = TrueExpr.Compile (compiler);
  643. FalseExpr = FalseExpr.Compile (compiler);
  644. return this;
  645. }
  646. public override SequenceType StaticType {
  647. get {
  648. if (Context == null)
  649. return SequenceType.AnyType;
  650. if (computedReturnType == null)
  651. computedReturnType = SequenceType.ComputeCommonBase (TrueExpr.StaticType, FalseExpr.StaticType);
  652. return computedReturnType;
  653. }
  654. }
  655. public override XPathSequence Evaluate (XPathSequence iter)
  656. {
  657. foreach (ExprSingle expr in Condition) {
  658. if (expr.EvaluateAsBoolean (iter))
  659. return TrueExpr.Evaluate (iter);
  660. }
  661. return FalseExpr.Evaluate (iter);
  662. }
  663. #endregion
  664. }
  665. // logical expr
  666. internal abstract class BinaryOperationExpr : ExprSingle
  667. {
  668. protected BinaryOperationExpr (ExprSingle left, ExprSingle right)
  669. {
  670. this.left = left;
  671. this.right = right;
  672. }
  673. ExprSingle left, right;
  674. public ExprSingle Left {
  675. get { return left; }
  676. set { left = value; }
  677. }
  678. public ExprSingle Right{
  679. get { return right; }
  680. set { right = value; }
  681. }
  682. internal override void CheckReference (XQueryASTCompiler compiler)
  683. {
  684. left.CheckReference (compiler);
  685. right.CheckReference (compiler);
  686. }
  687. #region CompileAndEvaluate
  688. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  689. {
  690. Left = Left.Compile (compiler);
  691. Right = Right.Compile (compiler);
  692. return this;
  693. }
  694. #endregion
  695. }
  696. internal class OrExpr : BinaryOperationExpr
  697. {
  698. public OrExpr (ExprSingle left, ExprSingle right)
  699. : base (left, right)
  700. {
  701. }
  702. #region CompileAndEvaluate
  703. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  704. {
  705. base.CompileCore (compiler);
  706. // FIXME: check constant value and return true or false
  707. return this;
  708. }
  709. public override SequenceType StaticType {
  710. get { return SequenceType.Boolean; }
  711. }
  712. public override bool EvaluateAsBoolean (XPathSequence iter)
  713. {
  714. return Left.EvaluateAsBoolean (iter) || Right.EvaluateAsBoolean (iter);
  715. }
  716. public override XPathSequence Evaluate (XPathSequence iter)
  717. {
  718. return new SingleItemIterator (EvaluateAsBoolean (iter) ?AtomicTrue : AtomicFalse, iter);
  719. }
  720. /*
  721. - compiler -
  722. return leftExprBool (context) || rightExprBool (context);
  723. */
  724. #endregion
  725. }
  726. internal class AndExpr : BinaryOperationExpr
  727. {
  728. public AndExpr (ExprSingle left, ExprSingle right)
  729. : base (left, right)
  730. {
  731. }
  732. #region CompileAndEvaluate
  733. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  734. {
  735. base.CompileCore (compiler);
  736. // FIXME: check constant value and return true or false
  737. return this;
  738. }
  739. public override SequenceType StaticType {
  740. get { return SequenceType.Boolean; }
  741. }
  742. public override bool EvaluateAsBoolean (XPathSequence iter)
  743. {
  744. return Left.EvaluateAsBoolean (iter) && Right.EvaluateAsBoolean (iter);
  745. }
  746. public override XPathSequence Evaluate (XPathSequence iter)
  747. {
  748. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
  749. }
  750. /*
  751. - compiler -
  752. return leftExprBool (context) && rightExprBool (context);
  753. */
  754. #endregion
  755. }
  756. // TypeOperation expr
  757. internal abstract class TypeOperationExpr : ExprSingle
  758. {
  759. protected TypeOperationExpr (ExprSingle expr, SequenceType type)
  760. {
  761. this.expr = expr;
  762. this.type = type;
  763. }
  764. ExprSingle expr;
  765. SequenceType type;
  766. public ExprSingle Expr {
  767. get { return expr; }
  768. set { expr = value; }
  769. }
  770. public SequenceType TargetType {
  771. get { return type; }
  772. }
  773. internal override void CheckReference (XQueryASTCompiler compiler)
  774. {
  775. expr.CheckReference (compiler);
  776. compiler.CheckSchemaType (type);
  777. }
  778. }
  779. internal abstract class AtomicTypeOperationExpr : ExprSingle
  780. {
  781. protected AtomicTypeOperationExpr (ExprSingle expr, XmlTypeCode type, bool optional)
  782. {
  783. this.expr = expr;
  784. // this.typeCode = type;
  785. // this.optional = optional;
  786. this.targetType = SequenceType.Create (type, optional ? Occurence.Optional : Occurence.One);
  787. }
  788. ExprSingle expr;
  789. // XmlTypeCode typeCode;
  790. // bool optional;
  791. SequenceType targetType;
  792. internal ExprSingle Expr {
  793. get { return expr; }
  794. set { expr = value; }
  795. }
  796. /*
  797. public XmlTypeCode TypeCode {
  798. get { return typeCode; }
  799. }
  800. public bool Optional {
  801. get { return optional; }
  802. }
  803. */
  804. internal SequenceType TargetType {
  805. get { return targetType; }
  806. }
  807. internal override void CheckReference (XQueryASTCompiler compiler)
  808. {
  809. expr.CheckReference (compiler);
  810. }
  811. }
  812. internal class InstanceOfExpr : TypeOperationExpr
  813. {
  814. public InstanceOfExpr (ExprSingle expr, SequenceType type)
  815. : base (expr, type)
  816. {
  817. }
  818. #region CompileAndEvaluate
  819. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  820. {
  821. Expr = Expr.Compile (compiler);
  822. // FIXME: check return type and if it never matches then return false
  823. return this;
  824. }
  825. public override SequenceType StaticType {
  826. get { return SequenceType.Boolean; }
  827. }
  828. public override bool EvaluateAsBoolean (XPathSequence iter)
  829. {
  830. bool occured = false;
  831. bool onlyOnce = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.Optional);
  832. bool required = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.OneOrMore);
  833. foreach (XPathItem item in iter) {
  834. if (occured && onlyOnce)
  835. return false;
  836. if (!TargetType.IsInstance (item))
  837. return false;
  838. }
  839. return occured || !required;
  840. }
  841. public override XPathSequence Evaluate (XPathSequence iter)
  842. {
  843. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
  844. }
  845. #endregion
  846. }
  847. internal class TreatExpr : TypeOperationExpr
  848. {
  849. public TreatExpr (ExprSingle expr, SequenceType type)
  850. : base (expr, type)
  851. {
  852. }
  853. #region CompileAndEvaluate
  854. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  855. {
  856. Expr = Expr.Compile (compiler);
  857. // FIXME: check return type and if it never matches then return false
  858. return this;
  859. }
  860. public override SequenceType StaticType {
  861. get { return SequenceType.AnyType; }
  862. }
  863. public override XPathSequence Evaluate (XPathSequence iter)
  864. {
  865. if (TargetType.CanConvert (iter))
  866. return iter;
  867. else
  868. throw new XmlQueryException (String.Format ("Cannot treat as {1}", TargetType));
  869. }
  870. #endregion
  871. }
  872. internal class CastableExpr : AtomicTypeOperationExpr
  873. {
  874. public CastableExpr (ExprSingle expr, XmlTypeCode atomicType, bool optional)
  875. : base (expr, atomicType, optional)
  876. {
  877. }
  878. #region CompileAndEvaluate
  879. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  880. {
  881. Expr = Expr.Compile (compiler);
  882. // FIXME: check return type and if it never matches then return boolean
  883. return this;
  884. }
  885. public override SequenceType StaticType {
  886. get { return SequenceType.Boolean; }
  887. }
  888. public override XPathSequence Evaluate (XPathSequence iter)
  889. {
  890. return new SingleItemIterator (new XPathAtomicValue (EvaluateAsBoolean (iter), XmlSchemaSimpleType.XsBoolean), iter);
  891. }
  892. public override bool EvaluateAsBoolean (XPathSequence iter)
  893. {
  894. bool occured = false;
  895. bool onlyOnce = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.Optional);
  896. bool required = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.OneOrMore);
  897. foreach (XPathItem item in iter) {
  898. if (occured && onlyOnce)
  899. return false;
  900. if (!TargetType.CanConvert (item))
  901. return false;
  902. }
  903. return occured || !required;
  904. }
  905. #endregion
  906. }
  907. internal class CastExpr : AtomicTypeOperationExpr
  908. {
  909. public CastExpr (ExprSingle expr, XmlTypeCode atomicType, bool optional)
  910. : base (expr, atomicType, optional)
  911. {
  912. }
  913. #region CompileAndEvaluate
  914. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  915. {
  916. Expr = Expr.Compile (compiler);
  917. // FIXME: check return type and if it never matches then return boolean
  918. return this;
  919. }
  920. public override SequenceType StaticType {
  921. get { return TargetType; }
  922. }
  923. public override XPathSequence Evaluate (XPathSequence iter)
  924. {
  925. if (TargetType.CanConvert (iter))
  926. return new ConvertingIterator (iter, TargetType);
  927. else
  928. throw new XmlQueryException (String.Format ("Cannot cast as {1}", TargetType));
  929. }
  930. #endregion
  931. }
  932. // ComparisonExpr
  933. internal class ComparisonExpr : BinaryOperationExpr
  934. {
  935. public ComparisonExpr (ExprSingle left, ExprSingle right, ComparisonOperator oper)
  936. : base (left, right)
  937. {
  938. }
  939. #region CompileAndEvaluate
  940. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  941. {
  942. Left = Left.Compile (compiler);
  943. Right = Right.Compile (compiler);
  944. // FIXME: check return type and if it never matches then return boolean
  945. return this;
  946. }
  947. public override SequenceType StaticType {
  948. get { return SequenceType.Boolean; }
  949. }
  950. public override bool EvaluateAsBoolean (XPathSequence iter)
  951. {
  952. throw new NotImplementedException ();
  953. }
  954. public override XPathSequence Evaluate (XPathSequence iter)
  955. {
  956. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter);
  957. }
  958. #endregion
  959. }
  960. public enum ComparisonOperator {
  961. ValueEQ,
  962. ValueNE,
  963. ValueLT,
  964. ValueLE,
  965. ValueGT,
  966. ValueGE,
  967. GeneralEQ,
  968. GeneralNE,
  969. GeneralLT,
  970. GeneralLE,
  971. GeneralGT,
  972. GeneralGE,
  973. NodeIs,
  974. NodeFWD,
  975. NodeBWD
  976. }
  977. // Range
  978. internal class RangeExpr : BinaryOperationExpr
  979. {
  980. public RangeExpr (ExprSingle left, ExprSingle right)
  981. : base (left, right)
  982. {
  983. }
  984. #region CompileAndEvaluate
  985. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  986. {
  987. Left = Left.Compile (compiler);
  988. Right = Right.Compile (compiler);
  989. return this;
  990. }
  991. public override SequenceType StaticType {
  992. get { return SequenceType.IntegerList; }
  993. }
  994. public override XPathSequence Evaluate (XPathSequence iter)
  995. {
  996. int start = Left.EvaluateAsInt (iter);
  997. int end = Right.EvaluateAsInt (iter);
  998. return new IntegerRangeIterator (iter, start, end);
  999. }
  1000. public override void Serialize (XPathSequence iter)
  1001. {
  1002. int start = Left.EvaluateAsInt (iter);
  1003. int end = Right.EvaluateAsInt (iter);
  1004. for (int i = start; i <= end; i++) {
  1005. iter.Context.Writer.WriteValue (i);
  1006. if (i < end)
  1007. iter.Context.Writer.WriteWhitespace (" ");
  1008. }
  1009. }
  1010. #endregion
  1011. }
  1012. // arithmetic operation expr
  1013. public enum ArithmeticOperator {
  1014. Plus,
  1015. Minus,
  1016. Mul,
  1017. Div,
  1018. IDiv,
  1019. IMod
  1020. }
  1021. internal class ArithmeticOperationExpr : BinaryOperationExpr
  1022. {
  1023. public ArithmeticOperationExpr (ExprSingle left, ExprSingle right, ArithmeticOperator oper)
  1024. : base (left, right)
  1025. {
  1026. }
  1027. #region CompileAndEvaluate
  1028. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1029. {
  1030. Left = Left.Compile (compiler);
  1031. Right = Right.Compile (compiler);
  1032. return this;
  1033. }
  1034. // FIXME: It can be optimized by comparing l/r value types.
  1035. public override SequenceType StaticType {
  1036. get { return SequenceType.AnyType; }
  1037. }
  1038. public override XPathSequence Evaluate (XPathSequence iter)
  1039. {
  1040. XPathAtomicValue lvalue = Left.EvaluateAsAtomic (iter);
  1041. XPathAtomicValue rvalue = Right.EvaluateAsAtomic (iter);
  1042. throw new NotImplementedException ();
  1043. }
  1044. #endregion
  1045. }
  1046. internal class MinusExpr : ExprSingle
  1047. {
  1048. public MinusExpr (ExprSingle expr)
  1049. {
  1050. this.expr = expr;
  1051. }
  1052. ExprSingle expr;
  1053. public ExprSingle Expr {
  1054. get { return expr; }
  1055. set { expr = value; }
  1056. }
  1057. internal override void CheckReference (XQueryASTCompiler compiler)
  1058. {
  1059. expr.CheckReference (compiler);
  1060. }
  1061. #region CompileAndEvaluate
  1062. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1063. {
  1064. Expr = Expr.Compile (compiler);
  1065. return this;
  1066. }
  1067. public override SequenceType StaticType {
  1068. get { return Expr.StaticType; }
  1069. }
  1070. public override XPathSequence Evaluate (XPathSequence iter)
  1071. {
  1072. throw new NotImplementedException ();
  1073. }
  1074. #endregion
  1075. }
  1076. // aggregation expr
  1077. public enum AggregationType {
  1078. Union,
  1079. Intersect,
  1080. Except
  1081. }
  1082. internal class GroupExpr : BinaryOperationExpr
  1083. {
  1084. public GroupExpr (ExprSingle left, ExprSingle right, AggregationType aggrType)
  1085. : base (left, right)
  1086. {
  1087. this.aggrType = aggrType;
  1088. }
  1089. AggregationType aggrType;
  1090. public AggregationType AggregationType {
  1091. get { return aggrType; }
  1092. }
  1093. #region CompileAndEvaluate
  1094. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1095. {
  1096. Left = Left.Compile (compiler);
  1097. Right = Right.Compile (compiler);
  1098. return this;
  1099. }
  1100. // FIXME: It can be optimized by comparing l/r value types.
  1101. public override SequenceType StaticType {
  1102. get { return SequenceType.AnyType; }
  1103. }
  1104. // only applicable against node-sets
  1105. public override XPathSequence Evaluate (XPathSequence iter)
  1106. {
  1107. XPathSequence lvalue = Left.EvaluateOrdered (iter);
  1108. XPathSequence rvalue = Right.EvaluateOrdered (iter);
  1109. /*
  1110. TBD (yield earlier node, skipping one of the same nodes)
  1111. - or -
  1112. TBD (yield earlier node, skipping non-intersection nodes)
  1113. - or -
  1114. TBD (yield earlier node, skipping both of the same nodes)
  1115. */
  1116. throw new NotImplementedException ();
  1117. }
  1118. #endregion
  1119. }
  1120. // validate expr
  1121. internal class ValidateExpr : ExprSingle
  1122. {
  1123. XmlSchemaContentProcessing schemaMode;
  1124. ExprSequence expr;
  1125. public ValidateExpr (XmlSchemaContentProcessing schemaMode, ExprSequence expr)
  1126. {
  1127. this.schemaMode = schemaMode;
  1128. this.expr = expr;
  1129. }
  1130. public ExprSequence Expr {
  1131. get { return expr; }
  1132. }
  1133. public XmlSchemaContentProcessing SchemaMode {
  1134. get { return schemaMode; }
  1135. }
  1136. internal override void CheckReference (XQueryASTCompiler compiler)
  1137. {
  1138. expr.CheckReference (compiler);
  1139. }
  1140. #region CompileAndEvaluate
  1141. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1142. {
  1143. for (int i = 0; i < expr.Count; i++)
  1144. expr [i] = expr [i].Compile (compiler);
  1145. return this;
  1146. }
  1147. public override SequenceType StaticType {
  1148. get { return SequenceType.AnyType; }
  1149. }
  1150. public override XPathSequence Evaluate (XPathSequence iter)
  1151. {
  1152. // TBD (see 3.13).
  1153. throw new NotImplementedException ();
  1154. }
  1155. #endregion
  1156. }
  1157. // Path expr
  1158. internal abstract class PathExpr : ExprSingle
  1159. {
  1160. }
  1161. // '/'
  1162. internal class PathRootExpr : PathExpr
  1163. {
  1164. public PathRootExpr ()
  1165. {
  1166. }
  1167. internal override void CheckReference (XQueryASTCompiler compiler)
  1168. {
  1169. }
  1170. #region CompileAndEvaluate
  1171. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1172. {
  1173. return this;
  1174. }
  1175. public override SequenceType StaticType {
  1176. get { return SequenceType.Document; }
  1177. }
  1178. public override XPathSequence Evaluate (XPathSequence iter)
  1179. {
  1180. if (iter.MoveNext ())
  1181. return new XPathEmptySequence (iter);
  1182. XPathNavigator nav = iter.Current as XPathNavigator;
  1183. if (nav == null)
  1184. return new XPathEmptySequence (iter);
  1185. nav = nav.Clone ();
  1186. nav.MoveToRoot ();
  1187. return new SingleItemIterator (nav, iter);
  1188. }
  1189. #endregion
  1190. }
  1191. // 'foo/bar'
  1192. internal class PathChildExpr : PathExpr
  1193. {
  1194. ExprSingle left;
  1195. ExprSingle next;
  1196. public PathChildExpr (ExprSingle left, ExprSingle next)
  1197. {
  1198. this.left = left;
  1199. this.next = next;
  1200. }
  1201. public ExprSingle Left {
  1202. get { return left; }
  1203. set { left = value; }
  1204. }
  1205. public ExprSingle Next {
  1206. get { return next; }
  1207. set { next = value; }
  1208. }
  1209. internal override void CheckReference (XQueryASTCompiler compiler)
  1210. {
  1211. left.CheckReference (compiler);
  1212. next.CheckReference (compiler);
  1213. }
  1214. #region CompileAndEvaluate
  1215. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1216. {
  1217. Left = Left.Compile (compiler);
  1218. Next = Next.Compile (compiler);
  1219. return this;
  1220. }
  1221. // FIXME: It can be optimized by comparing l/r value types.
  1222. public override SequenceType StaticType {
  1223. get { return SequenceType.Node; }
  1224. }
  1225. public override XPathSequence Evaluate (XPathSequence iter)
  1226. {
  1227. return new ChildPathIterator (iter, this);
  1228. }
  1229. #endregion
  1230. }
  1231. // 'foo//bar'
  1232. internal class PathDescendantExpr : PathExpr
  1233. {
  1234. ExprSingle left;
  1235. ExprSingle descendant;
  1236. public PathDescendantExpr (ExprSingle left, ExprSingle descendant)
  1237. {
  1238. this.left = left;
  1239. this.descendant = descendant;
  1240. }
  1241. public ExprSingle Left {
  1242. get { return left; }
  1243. set { left = value; }
  1244. }
  1245. public ExprSingle Descendant {
  1246. get { return descendant; }
  1247. set { descendant = value; }
  1248. }
  1249. internal override void CheckReference (XQueryASTCompiler compiler)
  1250. {
  1251. left.CheckReference (compiler);
  1252. descendant.CheckReference (compiler);
  1253. }
  1254. #region CompileAndEvaluate
  1255. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1256. {
  1257. Left = Left.Compile (compiler);
  1258. Descendant = Descendant.Compile (compiler);
  1259. return this;
  1260. }
  1261. // FIXME: It can be optimized by comparing l/r value types.
  1262. public override SequenceType StaticType {
  1263. get { return SequenceType.Node; }
  1264. }
  1265. public override XPathSequence Evaluate (XPathSequence iter)
  1266. {
  1267. return new DescendantPathIterator (iter, this);
  1268. }
  1269. #endregion
  1270. }
  1271. internal class AxisStepExpr : PathExpr
  1272. {
  1273. static AxisStepExpr parentStep;
  1274. static AxisStepExpr ()
  1275. {
  1276. parentStep = new AxisStepExpr (XPathAxis.Parent, null);
  1277. }
  1278. public static AxisStepExpr ParentStep {
  1279. get { return parentStep; }
  1280. }
  1281. public AxisStepExpr (XPathAxis axis, XPath2NodeTest test)
  1282. {
  1283. this.axis = axis;
  1284. if (test == null)
  1285. nameTest = XmlQualifiedName.Empty;
  1286. else {
  1287. if (test.NameTest != null)
  1288. this.nameTest = test.NameTest;
  1289. else
  1290. this.kindTest = test.KindTest;
  1291. }
  1292. }
  1293. XPathAxis axis;
  1294. XmlQualifiedName nameTest;
  1295. KindTest kindTest;
  1296. public XPathAxis Axis {
  1297. get { return axis; }
  1298. }
  1299. public XmlQualifiedName NameTest {
  1300. get { return nameTest; }
  1301. set { nameTest = value; }
  1302. }
  1303. public KindTest KindTest {
  1304. get { return kindTest; }
  1305. set { kindTest = value; }
  1306. }
  1307. internal override void CheckReference (XQueryASTCompiler compiler)
  1308. {
  1309. if (KindTest != null)
  1310. KindTest.CheckReference (compiler);
  1311. }
  1312. #region CompileAndEvaluate
  1313. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1314. {
  1315. if (KindTest != null)
  1316. KindTest.Compile (compiler);
  1317. return this;
  1318. }
  1319. public override SequenceType StaticType {
  1320. get {
  1321. switch (Axis.AxisType) {
  1322. case XPathAxisType.Attribute:
  1323. return SequenceType.Attribute;
  1324. case XPathAxisType.Namespace:
  1325. return SequenceType.Namespace;
  1326. }
  1327. // FIXME: we can more filtering by KindTest
  1328. return SequenceType.Node;
  1329. }
  1330. }
  1331. public override XPathSequence Evaluate (XPathSequence iter)
  1332. {
  1333. // FIXME: provide more classes than just one iterator
  1334. return new AxisIterator (iter, this);
  1335. }
  1336. #endregion
  1337. }
  1338. internal class FilterStepExpr : PathExpr
  1339. {
  1340. public FilterStepExpr (ExprSingle expr, PredicateList predicates)
  1341. {
  1342. this.expr = expr;
  1343. this.predicates = predicates;
  1344. }
  1345. ExprSingle expr;
  1346. PredicateList predicates;
  1347. public ExprSingle Expr {
  1348. get { return expr; }
  1349. set { expr = value; }
  1350. }
  1351. public PredicateList Predicates {
  1352. get { return predicates; }
  1353. }
  1354. internal override void CheckReference (XQueryASTCompiler compiler)
  1355. {
  1356. expr.CheckReference (compiler);
  1357. foreach (ExprSequence seq in predicates)
  1358. seq.CheckReference (compiler);
  1359. }
  1360. #region CompileAndEvaluate
  1361. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1362. {
  1363. Expr = Expr.Compile (compiler);
  1364. foreach (ExprSequence seq in Predicates)
  1365. for (int i = 0; i < seq.Count; i++)
  1366. seq [i] = seq [i].Compile (compiler);
  1367. return this;
  1368. }
  1369. public override SequenceType StaticType {
  1370. get { return Expr.StaticType; }
  1371. }
  1372. public override XPathSequence Evaluate (XPathSequence iter)
  1373. {
  1374. return new FilteredIterator (iter, this);
  1375. }
  1376. #endregion
  1377. }
  1378. // predicates == exprsequence list == list of list of exprsingle
  1379. internal class PredicateList : CollectionBase
  1380. {
  1381. public void Add (ExprSequence expr)
  1382. {
  1383. List.Add (expr);
  1384. }
  1385. public void Insert (int pos, ExprSequence expr)
  1386. {
  1387. List.Insert (pos, expr);
  1388. }
  1389. public ExprSequence this [int i] {
  1390. get { return (ExprSequence) List [i]; }
  1391. }
  1392. }
  1393. internal class XPath2NodeTest
  1394. {
  1395. public XPath2NodeTest (XmlQualifiedName nameTest)
  1396. {
  1397. this.NameTest = nameTest;
  1398. }
  1399. public XPath2NodeTest (KindTest kindTest)
  1400. {
  1401. this.KindTest = kindTest;
  1402. }
  1403. public XmlQualifiedName NameTest;
  1404. public KindTest KindTest;
  1405. }
  1406. internal class EnclosedExpr : ExprSingle
  1407. {
  1408. ExprSequence expr;
  1409. public EnclosedExpr (ExprSequence expr)
  1410. {
  1411. this.expr = expr;
  1412. }
  1413. public ExprSequence Expr {
  1414. get { return expr; }
  1415. }
  1416. internal override void CheckReference (XQueryASTCompiler compiler)
  1417. {
  1418. expr.CheckReference (compiler);
  1419. }
  1420. #region CompileAndEvaluate
  1421. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1422. {
  1423. if (Expr.Count == 0)
  1424. return Expr [0].Compile (compiler);
  1425. for (int i = 0; i < Expr.Count; i++)
  1426. Expr [i] = Expr [i].Compile (compiler);
  1427. return this;
  1428. }
  1429. // FIXME: can be optimized by checking all items in Expr
  1430. public override SequenceType StaticType {
  1431. get { return SequenceType.AnyType; }
  1432. }
  1433. public override XPathSequence Evaluate (XPathSequence iter)
  1434. {
  1435. return new ExprSequenceIterator (iter, Expr);
  1436. }
  1437. #endregion
  1438. }
  1439. // PrimaryExpr
  1440. internal abstract class PrimaryExpr : ExprSingle
  1441. {
  1442. internal override void CheckReference (XQueryASTCompiler compiler)
  1443. {
  1444. }
  1445. #region CompileAndEvaluate
  1446. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1447. {
  1448. return this;
  1449. }
  1450. public override XPathSequence Evaluate (XPathSequence iter)
  1451. {
  1452. return new SingleItemIterator (EvaluateAsAtomic (iter), iter);
  1453. }
  1454. #endregion
  1455. }
  1456. internal class StringLiteralExpr : PrimaryExpr
  1457. {
  1458. string literal;
  1459. public StringLiteralExpr (string literal)
  1460. {
  1461. this.literal = literal;
  1462. }
  1463. public string Literal {
  1464. get { return literal; }
  1465. }
  1466. #region CompileAndEvaluate
  1467. XmlSchemaSimpleType stringType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("string", XmlSchema.Namespace));
  1468. public override SequenceType StaticType {
  1469. get { return SequenceType.AtomicString; }
  1470. }
  1471. public override string EvaluateAsString (XPathSequence iter)
  1472. {
  1473. return Literal;
  1474. }
  1475. public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  1476. {
  1477. return new XPathAtomicValue (Literal, stringType);
  1478. }
  1479. #endregion
  1480. }
  1481. internal class DecimalLiteralExpr : PrimaryExpr
  1482. {
  1483. decimal value;
  1484. public DecimalLiteralExpr (decimal value)
  1485. {
  1486. this.value = value;
  1487. }
  1488. public decimal Value {
  1489. get { return value; }
  1490. }
  1491. #region CompileAndEvaluate
  1492. XmlSchemaSimpleType decimalType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("decimal", XmlSchema.Namespace));
  1493. public override SequenceType StaticType {
  1494. get { return SequenceType.Decimal; }
  1495. }
  1496. public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  1497. {
  1498. return new XPathAtomicValue (Value, decimalType);
  1499. }
  1500. #endregion
  1501. }
  1502. internal class DoubleLiteralExpr : PrimaryExpr
  1503. {
  1504. double value;
  1505. public DoubleLiteralExpr (double value)
  1506. {
  1507. this.value = value;
  1508. }
  1509. public double Value {
  1510. get { return value; }
  1511. }
  1512. #region CompileAndEvaluate
  1513. XmlSchemaSimpleType doubleType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("double", XmlSchema.Namespace));
  1514. public override SequenceType StaticType {
  1515. get { return SequenceType.Double; }
  1516. }
  1517. public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  1518. {
  1519. return new XPathAtomicValue (Value, doubleType);
  1520. }
  1521. #endregion
  1522. }
  1523. internal class VariableReferenceExpr : PrimaryExpr
  1524. {
  1525. XmlQualifiedName varName;
  1526. public VariableReferenceExpr (XmlQualifiedName varName)
  1527. {
  1528. this.varName = varName;
  1529. }
  1530. public XmlQualifiedName VariableName {
  1531. get { return varName; }
  1532. }
  1533. // FIXME: variable name must be stacked in any area
  1534. // whereever variables are defined.
  1535. internal override void CheckReference (XQueryASTCompiler compiler)
  1536. {
  1537. compiler.CheckVariableName (varName);
  1538. }
  1539. #region CompileAndEvaluate
  1540. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1541. {
  1542. // FIXME: try to resolve static context variable and return the actual value expression
  1543. return this;
  1544. }
  1545. public override SequenceType StaticType {
  1546. get { return SequenceType.AnyType; }
  1547. }
  1548. public override XPathSequence Evaluate (XPathSequence iter)
  1549. {
  1550. XPathSequence variable = iter.Context.ResolveVariable (VariableName, iter);
  1551. // FIXME: if Evaluate() accepts XPathSequence, then XPathSequence must be public class (to make IXPath2Variable public).
  1552. return variable;
  1553. }
  1554. #endregion
  1555. }
  1556. internal class ParenthesizedExpr : PrimaryExpr
  1557. {
  1558. ExprSequence expr;
  1559. public ParenthesizedExpr (ExprSequence expr)
  1560. {
  1561. this.expr = expr;
  1562. }
  1563. ExprSequence Expr {
  1564. get { return expr; }
  1565. }
  1566. #region CompileAndEvaluate
  1567. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1568. {
  1569. if (Expr.Count == 1)
  1570. return Expr [0].Compile (compiler);
  1571. for (int i = 0; i < Expr.Count; i++)
  1572. Expr [i] = Expr [i].Compile (compiler);
  1573. return this;
  1574. }
  1575. // FIXME: can be optimized by checking all items in Expr
  1576. public override SequenceType StaticType {
  1577. get { return SequenceType.AnyType; }
  1578. }
  1579. public override XPathSequence Evaluate (XPathSequence iter)
  1580. {
  1581. return new ExprSequenceIterator (iter, Expr);
  1582. }
  1583. #endregion
  1584. }
  1585. // "."
  1586. internal class ContextItemExpr : PrimaryExpr
  1587. {
  1588. public ContextItemExpr ()
  1589. {
  1590. }
  1591. #region CompileAndEvaluate
  1592. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1593. {
  1594. return this;
  1595. }
  1596. public override SequenceType StaticType {
  1597. get { return SequenceType.AnyType; }
  1598. }
  1599. public override XPathSequence Evaluate (XPathSequence iter)
  1600. {
  1601. return new SingleItemIterator (iter.Context.CurrentItem, iter);
  1602. }
  1603. #endregion
  1604. }
  1605. internal abstract class FunctionCallExprBase : PrimaryExpr
  1606. {
  1607. XmlQualifiedName name;
  1608. ExprSequence args;
  1609. public FunctionCallExprBase (XmlQualifiedName name, ExprSequence args)
  1610. {
  1611. if (args == null)
  1612. throw new ArgumentNullException (String.Format ("Function argument expressions for {0} is null.", name));
  1613. this.name = name;
  1614. this.args = args;
  1615. }
  1616. public XmlQualifiedName Name {
  1617. get { return name; }
  1618. }
  1619. public ExprSequence Args {
  1620. get { return args; }
  1621. }
  1622. internal override void CheckReference (XQueryASTCompiler compiler)
  1623. {
  1624. compiler.CheckFunctionName (name);
  1625. }
  1626. #region CompileAndEvaluate
  1627. /*
  1628. internal static FunctionCallExpr Create (
  1629. XmlQualifiedName name,
  1630. ExprSingle [] args,
  1631. XQueryStaticContext ctx)
  1632. {
  1633. switch (name.Namespace) {
  1634. case XQueryFunction.Namespace:
  1635. switch (name.Name) {
  1636. case "node-name":
  1637. return new FnNodeNameCall (ctx, args);
  1638. case "nilled":
  1639. return new FnNilledCall (ctx, args);
  1640. case "string":
  1641. return new FnStringCall (ctx, args);
  1642. case "data":
  1643. return new FnDataCall (ctx, args);
  1644. case "base-uri":
  1645. return new FnBaseUriCall (ctx, args);
  1646. case "document-uri":
  1647. return new FnDocumentUriCall (ctx, args);
  1648. case "error":
  1649. return new FnErrorCall (ctx, args);
  1650. case "trace":
  1651. return new FnTraceCall (ctx, args);
  1652. case "abs":
  1653. return new FnAbsCall (ctx, args);
  1654. case "ceiling":
  1655. return new FnCeilingCall (ctx, args);
  1656. case "floor":
  1657. return new FnFloorCall (ctx, args);
  1658. case "round":
  1659. return new FnRoundCall (ctx, args);
  1660. case "round-half-to-even":
  1661. return new FnRoundHalfToEvenCall (ctx, args);
  1662. case "codepoints-to-string":
  1663. return new FnCodepointsToStringCall (ctx, args);
  1664. case "string-to-codepoints":
  1665. return new FnStringCallToCodepointsCall (ctx, args);
  1666. }
  1667. goto default;
  1668. case XmlSchema.XdtNamespace:
  1669. case XmlSchema.Namespace:
  1670. XmlSchemaType type = XmlSchemaType.GetBuiltInSimpleType (name);
  1671. if (type != null)
  1672. return new AtomicConstructorCall (ctx, SequenceType.Create (type, Occurence.One), args);
  1673. type = XmlSchemaType.GetBuiltInComplexType (name);
  1674. if (type == null)
  1675. goto default;
  1676. return null;
  1677. default:
  1678. XQueryFunction func = ctx.CompileContext.InEffectFunctions [name];
  1679. if (func != null)
  1680. return new CustomFunctionCallExpression (ctx, args, func);
  1681. return null;
  1682. }
  1683. }
  1684. */
  1685. internal void CheckArguments (XQueryASTCompiler compiler)
  1686. {
  1687. if (args.Count < MinArgs || args.Count > MaxArgs)
  1688. // FIXME: add more info
  1689. throw new XmlQueryCompileException (String.Format ("{0} is invalid for the number of {1} function argument. MinArgs = {2}, MaxArgs = {3}.", args.Count, name, MinArgs, MaxArgs));
  1690. }
  1691. public abstract int MinArgs { get; }
  1692. public abstract int MaxArgs { get; }
  1693. #endregion
  1694. }
  1695. // This class is used only in AST
  1696. internal class FunctionCallExpr : FunctionCallExprBase
  1697. {
  1698. public FunctionCallExpr (XmlQualifiedName name, ExprSequence args)
  1699. : base (name, args)
  1700. {
  1701. }
  1702. #region CompileAndEvaluate
  1703. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1704. {
  1705. // resolve function
  1706. return new CustomFunctionCallExpr (Args, compiler.ResolveFunction (Name)).Compile (compiler);
  1707. }
  1708. public override XPathSequence Evaluate (XPathSequence iter)
  1709. {
  1710. throw new InvalidOperationException ("XQuery internal error. Should not happen.");
  1711. }
  1712. public SequenceType StaticType {
  1713. get { throw new InvalidOperationException ("XQuery internal error. Should not happen."); }
  1714. }
  1715. public override int MinArgs {
  1716. get { throw new InvalidOperationException ("XQuery internal error. Should not happen."); }
  1717. }
  1718. public override int MaxArgs {
  1719. get { throw new InvalidOperationException ("XQuery internal error. Should not happen."); }
  1720. }
  1721. #endregion
  1722. }
  1723. #region CompileAndEvaluate
  1724. // It is instantiated per function call expression.
  1725. // (e.g. the example below contains 3 FunctionCallExpression instances:
  1726. // "replace(node-name (node-before(/*)), 'foo', node-name($var))"
  1727. internal class CustomFunctionCallExpr : FunctionCallExprBase
  1728. {
  1729. public CustomFunctionCallExpr (ExprSequence args, XQueryFunction function)
  1730. : base (function.Name, args)
  1731. {
  1732. this.function = function;
  1733. }
  1734. XQueryFunction function;
  1735. public XQueryFunction Function {
  1736. get { return function; }
  1737. }
  1738. public override int MinArgs {
  1739. get { return function.MinArgs; }
  1740. }
  1741. public override int MaxArgs {
  1742. get { return function.MaxArgs; }
  1743. }
  1744. public override SequenceType StaticType {
  1745. get { return function.ReturnType; }
  1746. }
  1747. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1748. {
  1749. CheckArguments (compiler);
  1750. return this;
  1751. }
  1752. public override XPathSequence Evaluate (XPathSequence iter)
  1753. {
  1754. return Function.Evaluate (iter, Args);
  1755. }
  1756. // FIXME: add all overrides that delegates to XQueryFunction
  1757. }
  1758. #endregion
  1759. // Ordered / Unordered
  1760. internal class OrderSpecifiedExpr : ExprSingle
  1761. {
  1762. bool ordered;
  1763. ExprSequence expr;
  1764. public OrderSpecifiedExpr (ExprSequence expr, bool ordered)
  1765. {
  1766. this.ordered = ordered;
  1767. this.expr = expr;
  1768. }
  1769. public ExprSequence Expr {
  1770. get { return expr; }
  1771. }
  1772. public bool Ordered {
  1773. get { return ordered; }
  1774. }
  1775. internal override void CheckReference (XQueryASTCompiler compiler)
  1776. {
  1777. expr.CheckReference (compiler);
  1778. }
  1779. #region CompileAndEvaluate
  1780. public override SequenceType StaticType {
  1781. // FIXME: could be optimized by checking all the expressions
  1782. get { return SequenceType.AnyType; }
  1783. }
  1784. public override bool RequireSorting {
  1785. get { return Ordered; }
  1786. }
  1787. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1788. {
  1789. for (int i = 0; i < Expr.Count; i++)
  1790. Expr [i] = Expr [i].Compile (compiler);
  1791. return this;
  1792. }
  1793. public override XPathSequence Evaluate (XPathSequence iter)
  1794. {
  1795. throw new NotImplementedException ();
  1796. }
  1797. #endregion
  1798. }
  1799. }
  1800. #endif