XPath2Expression.cs 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424
  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. bool initial = true;
  109. foreach (XPathItem item in result) {
  110. if (initial)
  111. initial = false;
  112. else
  113. w.WriteWhitespace (" ");
  114. WriteXPathItem (item, w);
  115. }
  116. }
  117. private void WriteXPathItem (XPathItem item, XmlWriter w)
  118. {
  119. if (item.IsNode) {
  120. XPathNavigator nav = item as XPathNavigator;
  121. if (w.WriteState != WriteState.Start && nav.NodeType == XPathNodeType.Root)
  122. throw new XmlQueryException ("Current output can not accept root node.");
  123. w.WriteNode (nav, false);
  124. } else
  125. w.WriteString (item.Value);
  126. }
  127. // get EBV (fn:boolean())
  128. public virtual bool EvaluateAsBoolean (XPathSequence iter)
  129. {
  130. XPathSequence result = Evaluate (iter);
  131. if (!result.MoveNext ())
  132. return false;
  133. XPathItem v = result.Current;
  134. if (v is XPathNavigator)
  135. return true;
  136. if (result.MoveNext ())
  137. return true;
  138. switch (v.XmlType.TypeCode) {
  139. case XmlTypeCode.Boolean:
  140. return v.ValueAsBoolean;
  141. case XmlTypeCode.String:
  142. case XmlTypeCode.UntypedAtomic:
  143. return v.Value != String.Empty;
  144. case XmlTypeCode.Float:
  145. return v.ValueAsSingle != Single.NaN && v.ValueAsSingle != 0.0;
  146. case XmlTypeCode.Double:
  147. return v.ValueAsDouble != Double.NaN && v.ValueAsSingle != 0.0;
  148. case XmlTypeCode.Decimal:
  149. return v.ValueAsDecimal != 0;
  150. case XmlTypeCode.Integer:
  151. case XmlTypeCode.NonPositiveInteger:
  152. case XmlTypeCode.NegativeInteger:
  153. case XmlTypeCode.Long:
  154. case XmlTypeCode.Int:
  155. case XmlTypeCode.Short:
  156. case XmlTypeCode.Byte:
  157. case XmlTypeCode.UnsignedInt:
  158. case XmlTypeCode.UnsignedShort:
  159. case XmlTypeCode.UnsignedByte:
  160. return v.ValueAsInt64 != 0;
  161. case XmlTypeCode.NonNegativeInteger:
  162. case XmlTypeCode.UnsignedLong:
  163. case XmlTypeCode.PositiveInteger:
  164. return (ulong) (v.ValueAs (typeof (ulong))) != 0;
  165. }
  166. // otherwise, return true
  167. return true;
  168. }
  169. public virtual int EvaluateAsInt (XPathSequence iter)
  170. {
  171. XPathAtomicValue v = Atomize (Evaluate (iter));
  172. return v != null ? v.ValueAsInt32 : 0;
  173. }
  174. public virtual string EvaluateAsString (XPathSequence iter)
  175. {
  176. XPathAtomicValue v = Atomize (Evaluate (iter));
  177. return v != null ? v.Value : String.Empty;
  178. }
  179. public static XPathAtomicValue Atomize (XPathItem item)
  180. {
  181. XPathNavigator nav = item as XPathNavigator;
  182. if (nav != null) {
  183. if (nav.SchemaInfo != null)
  184. return new XPathAtomicValue (nav.TypedValue, nav.SchemaInfo.SchemaType);
  185. else
  186. return new XPathAtomicValue (nav.Value, XmlSchemaSimpleType.XdtUntypedAtomic);
  187. }
  188. else
  189. return (XPathAtomicValue) item;
  190. }
  191. // FIXME: What if iter contains list value?
  192. public static XPathAtomicValue Atomize (XPathSequence iter)
  193. {
  194. if (!iter.MoveNext ())
  195. return null;
  196. XPathNavigator nav = iter.Current as XPathNavigator;
  197. if (nav != null) {
  198. // FIXME: is it really always untypedAtomic?
  199. // It might be complex content.
  200. XmlSchemaType type = nav.SchemaInfo == null ? XmlSchemaSimpleType.XdtUntypedAtomic : nav.SchemaInfo.SchemaType;
  201. return new XPathAtomicValue (nav.TypedValue, type);
  202. }
  203. else
  204. return (XPathAtomicValue) iter.Current;
  205. }
  206. public virtual XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  207. {
  208. return Atomize (Evaluate (iter));
  209. }
  210. public virtual bool RequireSorting {
  211. get { return false; }
  212. }
  213. #endregion
  214. }
  215. // FLWORExpr
  216. internal class FLWORExpr : ExprSingle
  217. {
  218. public FLWORExpr (ForLetClauseCollection forlet, ExprSequence whereClause, OrderSpecList orderBy, ExprSingle ret)
  219. {
  220. this.fl = forlet;
  221. if (whereClause != null)
  222. this.whereClause = new ParenthesizedExpr (whereClause);
  223. this.orderBy = orderBy;
  224. this.ret = ret;
  225. }
  226. ForLetClauseCollection fl;
  227. ExprSingle whereClause;
  228. OrderSpecList orderBy;
  229. ExprSingle ret;
  230. public ForLetClauseCollection ForLetClauses {
  231. get { return fl; }
  232. }
  233. public ExprSingle WhereClause {
  234. get { return whereClause; }
  235. }
  236. public OrderSpecList OrderBy {
  237. get { return orderBy; }
  238. }
  239. public ExprSingle ReturnExpr {
  240. get { return ret; }
  241. set { ret = value; }
  242. }
  243. // ExprSingle Overrides
  244. internal override void CheckReference (XQueryASTCompiler compiler)
  245. {
  246. foreach (ForLetClause flc in fl)
  247. foreach (ForLetSingleBody single in flc)
  248. single.CheckReference (compiler);
  249. if (whereClause != null)
  250. whereClause.CheckReference (compiler);
  251. if (orderBy != null)
  252. foreach (OrderSpec os in orderBy)
  253. os.Expression.CheckReference (compiler);
  254. ret.CheckReference (compiler);
  255. }
  256. #region CompileAndEvaluate
  257. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  258. {
  259. foreach (ForLetClause flc in ForLetClauses) {
  260. foreach (ForLetSingleBody flsb in flc) {
  261. flsb.Expression = flsb.Expression.Compile (compiler);
  262. if (flsb.ReturnType != null)
  263. compiler.CheckType (flsb.Expression, flsb.ReturnType);
  264. }
  265. }
  266. if (WhereClause != null)
  267. whereClause = whereClause.Compile (compiler);
  268. if (OrderBy != null)
  269. foreach (OrderSpec os in OrderBy)
  270. os.Expression = os.Expression.Compile (compiler);
  271. ReturnExpr = ReturnExpr.Compile (compiler);
  272. return this;
  273. }
  274. public override SequenceType StaticType {
  275. get { return ReturnExpr.StaticType; }
  276. }
  277. public override XPathSequence Evaluate (XPathSequence iter)
  278. {
  279. return new FLWORIterator (iter, this);
  280. }
  281. #endregion
  282. }
  283. internal class ForLetClauseCollection : CollectionBase
  284. {
  285. public void Add (ForLetClause clause)
  286. {
  287. List.Add (clause);
  288. }
  289. public void Insert (int pos, ForLetClause clause)
  290. {
  291. List.Insert (pos, clause);
  292. }
  293. public ForLetClause this [int i] {
  294. get { return (ForLetClause) List [i]; }
  295. }
  296. }
  297. internal class OrderSpecList : CollectionBase
  298. {
  299. bool isStable;
  300. public OrderSpecList ()
  301. {
  302. }
  303. public bool IsStable {
  304. get { return isStable; }
  305. set { isStable = value; }
  306. }
  307. public void Insert (int pos, OrderSpec os)
  308. {
  309. List.Insert (pos, os);
  310. }
  311. public void Add (OrderSpec spec)
  312. {
  313. List.Add (spec);
  314. }
  315. public OrderSpec this [int i] {
  316. get { return (OrderSpec) List [i]; }
  317. }
  318. }
  319. internal class OrderSpec
  320. {
  321. public OrderSpec (ExprSingle expr, OrderModifier modifier)
  322. {
  323. this.expr = expr;
  324. this.mod = modifier;
  325. }
  326. ExprSingle expr;
  327. OrderModifier mod;
  328. public ExprSingle Expression {
  329. get {return expr; }
  330. set { expr = value; }
  331. }
  332. public OrderModifier Modifier {
  333. get { return mod; }
  334. set { mod = value; }
  335. }
  336. }
  337. internal class OrderModifier
  338. {
  339. public OrderModifier (XmlSortOrder order, XmlSortOrder emptyOrder, string collation)
  340. {
  341. this.sortOrder = sortOrder;
  342. this.emptyOrder = emptyOrder;
  343. if (collation != null)
  344. this.coll = new CultureInfo (collation);
  345. }
  346. XmlSortOrder sortOrder;
  347. XmlSortOrder emptyOrder;
  348. CultureInfo coll;
  349. public XmlSortOrder SortOrder {
  350. get { return sortOrder; }
  351. }
  352. public XmlSortOrder EmptyOrder {
  353. get { return emptyOrder; }
  354. }
  355. public CultureInfo Collation {
  356. get { return coll; }
  357. }
  358. }
  359. internal class ForLetClause : CollectionBase
  360. {
  361. public ForLetSingleBody this [int i] {
  362. get { return (ForLetSingleBody) List [i]; }
  363. }
  364. }
  365. internal class ForClause : ForLetClause
  366. {
  367. public ForClause ()
  368. {
  369. }
  370. public void Insert (int pos, ForSingleBody body)
  371. {
  372. List.Insert (pos, body);
  373. }
  374. public void Add (ForSingleBody body)
  375. {
  376. List.Add (body);
  377. }
  378. }
  379. internal class LetClause : ForLetClause
  380. {
  381. public LetClause ()
  382. {
  383. }
  384. public void Insert (int pos, LetSingleBody body)
  385. {
  386. List.Insert (pos, body);
  387. }
  388. public void Add (LetSingleBody body)
  389. {
  390. List.Add (body);
  391. }
  392. }
  393. internal abstract class ForLetSingleBody
  394. {
  395. XmlQualifiedName varName;
  396. SequenceType type;
  397. ExprSingle expr;
  398. public ForLetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
  399. {
  400. this.varName = varName;
  401. this.type = type;
  402. this.expr = expr;
  403. }
  404. public XmlQualifiedName VarName {
  405. get { return varName; }
  406. }
  407. public SequenceType ReturnType {
  408. get { return type; }
  409. }
  410. public ExprSingle Expression {
  411. get { return expr; }
  412. set { expr = value; }
  413. }
  414. internal void CheckReference (XQueryASTCompiler compiler)
  415. {
  416. if (type != null)
  417. compiler.CheckSchemaType (type);
  418. expr.CheckReference (compiler);
  419. }
  420. }
  421. internal class ForSingleBody : ForLetSingleBody
  422. {
  423. public ForSingleBody (XmlQualifiedName varName, SequenceType type, XmlQualifiedName positionalVar, ExprSingle expr)
  424. : base (varName, type, expr)
  425. {
  426. this.positionalVar = positionalVar;
  427. }
  428. XmlQualifiedName positionalVar;
  429. public XmlQualifiedName PositionalVar {
  430. get { return positionalVar; }
  431. }
  432. }
  433. internal class LetSingleBody : ForLetSingleBody
  434. {
  435. public LetSingleBody (XmlQualifiedName varName, SequenceType type, ExprSingle expr)
  436. : base (varName, type, expr)
  437. {
  438. }
  439. }
  440. // QuantifiedExpr
  441. internal class QuantifiedExpr : ExprSingle
  442. {
  443. QuantifiedExprBodyList body;
  444. ExprSingle satisfies;
  445. bool every;
  446. public QuantifiedExpr (bool every, QuantifiedExprBodyList body, ExprSingle satisfies)
  447. {
  448. this.every = every;
  449. this.body = body;
  450. this.satisfies = satisfies;
  451. }
  452. public bool Every {
  453. get { return every; }
  454. }
  455. public QuantifiedExprBodyList BodyList {
  456. get { return body; }
  457. }
  458. public ExprSingle Satisfies {
  459. get { return satisfies; }
  460. set { satisfies = value; }
  461. }
  462. internal override void CheckReference (XQueryASTCompiler compiler)
  463. {
  464. foreach (QuantifiedExprBody one in body) {
  465. if (one.Type != null)
  466. compiler.CheckSchemaType (one.Type);
  467. one.Expression.CheckReference (compiler);
  468. }
  469. Satisfies.CheckReference (compiler);
  470. }
  471. #region CompileAndEvaluate
  472. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  473. {
  474. Satisfies = Satisfies.Compile (compiler);
  475. for (int i = 0; i < BodyList.Count; i++) {
  476. BodyList [i].Expression = BodyList [i].Expression.Compile (compiler);
  477. if (BodyList [i].Type != null)
  478. compiler.CheckType (BodyList [i].Expression, BodyList [i].Type);
  479. }
  480. return this;
  481. }
  482. public override SequenceType StaticType {
  483. get { return SequenceType.Boolean; }
  484. }
  485. public override XPathSequence Evaluate (XPathSequence iter)
  486. {
  487. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter.Context);
  488. }
  489. public override bool EvaluateAsBoolean (XPathSequence iter)
  490. {
  491. return EvaluateQuantification (iter, BodyList.GetEnumerator ());
  492. }
  493. private bool EvaluateQuantification (XPathSequence iter, IEnumerator bodies)
  494. {
  495. if (bodies.MoveNext ()) {
  496. QuantifiedExprBody qb = bodies.Current as QuantifiedExprBody;
  497. XPathSequence seq = qb.Expression.Evaluate (iter);
  498. bool passed = false;
  499. foreach (XPathItem item in seq) {
  500. passed = true;
  501. // FIXME: consider qb.Type
  502. try {
  503. iter.Context.PushVariable (qb.VarName, item);
  504. if (EvaluateQuantification (iter, bodies)) {
  505. if (!Every)
  506. return true;
  507. }
  508. else if (Every)
  509. return false;
  510. } finally {
  511. iter.Context.PopVariable ();
  512. }
  513. }
  514. return passed;
  515. }
  516. return Satisfies.EvaluateAsBoolean (iter);
  517. }
  518. #endregion
  519. }
  520. internal class QuantifiedExprBodyList : CollectionBase
  521. {
  522. public QuantifiedExprBodyList ()
  523. {
  524. }
  525. public void Add (QuantifiedExprBody body)
  526. {
  527. List.Add (body);
  528. }
  529. public void Insert (int pos, QuantifiedExprBody body)
  530. {
  531. List.Insert (pos, body);
  532. }
  533. public QuantifiedExprBody this [int i] {
  534. get { return (QuantifiedExprBody) List [i]; }
  535. }
  536. }
  537. internal class QuantifiedExprBody
  538. {
  539. private XmlQualifiedName varName;
  540. private SequenceType type;
  541. private ExprSingle expr;
  542. public QuantifiedExprBody (XmlQualifiedName varName,
  543. SequenceType type, ExprSingle expr)
  544. {
  545. this.varName = varName;
  546. this.type = type ;
  547. this.expr = expr;
  548. }
  549. public XmlQualifiedName VarName {
  550. get { return varName; }
  551. }
  552. public SequenceType Type {
  553. get { return type; }
  554. }
  555. public ExprSingle Expression {
  556. get { return expr; }
  557. set { expr = value; }
  558. }
  559. }
  560. // TypeswitchExpr
  561. internal class TypeswitchExpr : ExprSingle
  562. {
  563. ExprSequence switchExpr;
  564. CaseClauseList caseList;
  565. XmlQualifiedName defaultVarName;
  566. ExprSingle defaultReturn;
  567. public TypeswitchExpr (ExprSequence switchExpr, CaseClauseList caseList, XmlQualifiedName defaultVarName, ExprSingle defaultReturn)
  568. {
  569. this.switchExpr = switchExpr;
  570. this.caseList = caseList;
  571. this.defaultVarName = defaultVarName;
  572. this.defaultReturn = defaultReturn;
  573. }
  574. public ExprSequence SwitchExpr {
  575. get { return switchExpr; }
  576. }
  577. public CaseClauseList Cases {
  578. get { return caseList; }
  579. }
  580. public XmlQualifiedName DefaultVarName {
  581. get { return defaultVarName; }
  582. }
  583. public ExprSingle DefaultReturn {
  584. get { return defaultReturn; }
  585. set { defaultReturn = value; }
  586. }
  587. internal override void CheckReference (XQueryASTCompiler compiler)
  588. {
  589. switchExpr.CheckReference (compiler);
  590. foreach (CaseClause cc in caseList) {
  591. compiler.CheckSchemaType (cc.Type);
  592. cc.Expr.CheckReference (compiler);
  593. }
  594. defaultReturn.CheckReference (compiler);
  595. }
  596. #region CompileAndEvaluate
  597. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  598. {
  599. for (int i = 0; i < SwitchExpr.Count; i++)
  600. SwitchExpr [i] = SwitchExpr [i].Compile (compiler);
  601. foreach (CaseClause cc in Cases)
  602. cc.Expr = cc.Expr.Compile (compiler);
  603. DefaultReturn = DefaultReturn.Compile (compiler);
  604. return this;
  605. }
  606. // FIXME: it can be optimized by checking all case clauses.
  607. public override SequenceType StaticType {
  608. get { return SequenceType.AnyType; }
  609. }
  610. public override XPathSequence Evaluate (XPathSequence iter)
  611. {
  612. // FIXME: should move to iterator?
  613. XPathSequence cond = new ExprSequenceIterator (iter, SwitchExpr);
  614. XPathSequence ret = null;
  615. foreach (CaseClause ccc in Cases) {
  616. if (ccc.Type.Matches (cond)) {
  617. if (ccc.VarName != XmlQualifiedName.Empty)
  618. iter.Context.PushVariable (ccc.VarName, cond);
  619. ret = ccc.Expr.Evaluate (iter);
  620. // FIXME: The design should make sure that in-scope variables are held on actual iteration.
  621. if (ccc.VarName != XmlQualifiedName.Empty)
  622. iter.Context.PopVariable ();
  623. return ret;
  624. }
  625. }
  626. if (DefaultVarName != XmlQualifiedName.Empty)
  627. iter.Context.PushVariable (DefaultVarName, cond);
  628. ret = DefaultReturn.Evaluate (iter);
  629. if (DefaultVarName != XmlQualifiedName.Empty)
  630. iter.Context.PopVariable ();
  631. return ret;
  632. }
  633. #endregion
  634. }
  635. internal class CaseClauseList : CollectionBase
  636. {
  637. public void Insert (int pos, CaseClause cc)
  638. {
  639. List.Insert (pos, cc);
  640. }
  641. public void Add (CaseClause cc)
  642. {
  643. List.Add (cc);
  644. }
  645. public CaseClause this [int i] {
  646. get { return (CaseClause) List [i]; }
  647. }
  648. }
  649. internal class CaseClause
  650. {
  651. public CaseClause (SequenceType type, ExprSingle expr, XmlQualifiedName varName)
  652. {
  653. this.type = type;
  654. this.expr = expr;
  655. this.varName = varName;
  656. }
  657. SequenceType type;
  658. ExprSingle expr;
  659. XmlQualifiedName varName;
  660. public SequenceType Type {
  661. get { return type; }
  662. }
  663. public ExprSingle Expr {
  664. get { return expr; }
  665. set { expr = value; }
  666. }
  667. public XmlQualifiedName VarName {
  668. get { return varName; }
  669. set { varName = value; }
  670. }
  671. }
  672. // IfExpr
  673. internal class IfExpr : ExprSingle
  674. {
  675. public IfExpr (ExprSequence condition, ExprSingle trueExpr, ExprSingle falseExpr)
  676. {
  677. this.condition = new ParenthesizedExpr (condition);
  678. this.trueExpr = trueExpr;
  679. this.falseExpr = falseExpr;
  680. }
  681. ExprSingle condition;
  682. ExprSingle trueExpr;
  683. ExprSingle falseExpr;
  684. public ExprSingle Condition {
  685. get { return condition; }
  686. set { condition = value; }
  687. }
  688. public ExprSingle TrueExpr {
  689. get { return trueExpr; }
  690. set { trueExpr = value; }
  691. }
  692. public ExprSingle FalseExpr {
  693. get { return falseExpr; }
  694. set { falseExpr = value; }
  695. }
  696. internal override void CheckReference (XQueryASTCompiler compiler)
  697. {
  698. condition.CheckReference (compiler);
  699. trueExpr.CheckReference (compiler);
  700. falseExpr.CheckReference (compiler);
  701. }
  702. #region CompileAndEvaluate
  703. SequenceType computedReturnType;
  704. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  705. {
  706. condition = condition.Compile (compiler);
  707. // FIXME: check if condition is constant, and returns trueExpr or falseExpr
  708. TrueExpr = TrueExpr.Compile (compiler);
  709. FalseExpr = FalseExpr.Compile (compiler);
  710. return this;
  711. }
  712. public override SequenceType StaticType {
  713. get {
  714. if (Context == null)
  715. return SequenceType.AnyType;
  716. if (computedReturnType == null)
  717. computedReturnType = SequenceType.ComputeCommonBase (TrueExpr.StaticType, FalseExpr.StaticType);
  718. return computedReturnType;
  719. }
  720. }
  721. public override XPathSequence Evaluate (XPathSequence iter)
  722. {
  723. if (condition.EvaluateAsBoolean (iter))
  724. return TrueExpr.Evaluate (iter);
  725. return FalseExpr.Evaluate (iter);
  726. }
  727. #endregion
  728. }
  729. // logical expr
  730. internal abstract class BinaryOperationExpr : ExprSingle
  731. {
  732. protected BinaryOperationExpr (ExprSingle left, ExprSingle right)
  733. {
  734. this.left = left;
  735. this.right = right;
  736. }
  737. ExprSingle left, right;
  738. public ExprSingle Left {
  739. get { return left; }
  740. set { left = value; }
  741. }
  742. public ExprSingle Right{
  743. get { return right; }
  744. set { right = value; }
  745. }
  746. internal override void CheckReference (XQueryASTCompiler compiler)
  747. {
  748. left.CheckReference (compiler);
  749. right.CheckReference (compiler);
  750. }
  751. #region CompileAndEvaluate
  752. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  753. {
  754. Left = Left.Compile (compiler);
  755. Right = Right.Compile (compiler);
  756. return this;
  757. }
  758. #endregion
  759. }
  760. internal class OrExpr : BinaryOperationExpr
  761. {
  762. public OrExpr (ExprSingle left, ExprSingle right)
  763. : base (left, right)
  764. {
  765. }
  766. #region CompileAndEvaluate
  767. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  768. {
  769. base.CompileCore (compiler);
  770. // FIXME: check constant value and return true or false
  771. return this;
  772. }
  773. public override SequenceType StaticType {
  774. get { return SequenceType.Boolean; }
  775. }
  776. public override bool EvaluateAsBoolean (XPathSequence iter)
  777. {
  778. return Left.EvaluateAsBoolean (iter) || Right.EvaluateAsBoolean (iter);
  779. }
  780. public override XPathSequence Evaluate (XPathSequence iter)
  781. {
  782. return new SingleItemIterator (EvaluateAsBoolean (iter) ?AtomicTrue : AtomicFalse, iter.Context);
  783. }
  784. /*
  785. - compiler -
  786. return leftExprBool (context) || rightExprBool (context);
  787. */
  788. #endregion
  789. }
  790. internal class AndExpr : BinaryOperationExpr
  791. {
  792. public AndExpr (ExprSingle left, ExprSingle right)
  793. : base (left, right)
  794. {
  795. }
  796. #region CompileAndEvaluate
  797. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  798. {
  799. base.CompileCore (compiler);
  800. // FIXME: check constant value and return true or false
  801. return this;
  802. }
  803. public override SequenceType StaticType {
  804. get { return SequenceType.Boolean; }
  805. }
  806. public override bool EvaluateAsBoolean (XPathSequence iter)
  807. {
  808. return Left.EvaluateAsBoolean (iter) && Right.EvaluateAsBoolean (iter);
  809. }
  810. public override XPathSequence Evaluate (XPathSequence iter)
  811. {
  812. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter.Context);
  813. }
  814. /*
  815. - compiler -
  816. return leftExprBool (context) && rightExprBool (context);
  817. */
  818. #endregion
  819. }
  820. // TypeOperation expr
  821. internal abstract class TypeOperationExpr : ExprSingle
  822. {
  823. protected TypeOperationExpr (ExprSingle expr, SequenceType type)
  824. {
  825. this.expr = expr;
  826. this.type = type;
  827. }
  828. ExprSingle expr;
  829. SequenceType type;
  830. public ExprSingle Expr {
  831. get { return expr; }
  832. set { expr = value; }
  833. }
  834. public SequenceType TargetType {
  835. get { return type; }
  836. }
  837. internal override void CheckReference (XQueryASTCompiler compiler)
  838. {
  839. expr.CheckReference (compiler);
  840. compiler.CheckSchemaType (type);
  841. }
  842. }
  843. internal abstract class AtomicTypeOperationExpr : ExprSingle
  844. {
  845. protected AtomicTypeOperationExpr (ExprSingle expr, XmlTypeCode type, bool optional)
  846. {
  847. this.expr = expr;
  848. this.targetType = SequenceType.Create (type, optional ? Occurence.Optional : Occurence.One);
  849. }
  850. ExprSingle expr;
  851. SequenceType targetType;
  852. internal ExprSingle Expr {
  853. get { return expr; }
  854. set { expr = value; }
  855. }
  856. /*
  857. public XmlTypeCode TypeCode {
  858. get { return typeCode; }
  859. }
  860. public bool Optional {
  861. get { return optional; }
  862. }
  863. */
  864. internal SequenceType TargetType {
  865. get { return targetType; }
  866. }
  867. internal override void CheckReference (XQueryASTCompiler compiler)
  868. {
  869. expr.CheckReference (compiler);
  870. }
  871. }
  872. internal class InstanceOfExpr : TypeOperationExpr
  873. {
  874. public InstanceOfExpr (ExprSingle expr, SequenceType type)
  875. : base (expr, type)
  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 false
  883. return this;
  884. }
  885. public override SequenceType StaticType {
  886. get { return SequenceType.Boolean; }
  887. }
  888. public override bool EvaluateAsBoolean (XPathSequence iter)
  889. {
  890. bool occured = false;
  891. bool onlyOnce = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.Optional);
  892. bool required = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.OneOrMore);
  893. foreach (XPathItem item in iter) {
  894. if (occured && onlyOnce)
  895. return false;
  896. if (!TargetType.IsInstance (item))
  897. return false;
  898. }
  899. return occured || !required;
  900. }
  901. public override XPathSequence Evaluate (XPathSequence iter)
  902. {
  903. return new SingleItemIterator (EvaluateAsBoolean (iter) ? AtomicTrue : AtomicFalse, iter.Context);
  904. }
  905. #endregion
  906. }
  907. internal class TreatExpr : TypeOperationExpr
  908. {
  909. public TreatExpr (ExprSingle expr, SequenceType type)
  910. : base (expr, type)
  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 false
  918. return this;
  919. }
  920. public override SequenceType StaticType {
  921. get { return SequenceType.AnyType; }
  922. }
  923. public override XPathSequence Evaluate (XPathSequence iter)
  924. {
  925. if (TargetType.CanConvert (iter))
  926. return iter;
  927. else
  928. throw new XmlQueryException (String.Format ("Cannot treat as {1}", TargetType));
  929. }
  930. #endregion
  931. }
  932. internal class CastableExpr : AtomicTypeOperationExpr
  933. {
  934. public CastableExpr (ExprSingle expr, XmlTypeCode atomicType, bool optional)
  935. : base (expr, atomicType, optional)
  936. {
  937. }
  938. #region CompileAndEvaluate
  939. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  940. {
  941. Expr = Expr.Compile (compiler);
  942. // FIXME: check return type and if it never matches then return boolean
  943. return this;
  944. }
  945. public override SequenceType StaticType {
  946. get { return SequenceType.Boolean; }
  947. }
  948. public override XPathSequence Evaluate (XPathSequence iter)
  949. {
  950. return new SingleItemIterator (new XPathAtomicValue (EvaluateAsBoolean (iter), XmlSchemaSimpleType.XsBoolean), iter.Context);
  951. }
  952. public override bool EvaluateAsBoolean (XPathSequence iter)
  953. {
  954. bool occured = false;
  955. bool onlyOnce = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.Optional);
  956. bool required = (TargetType.Occurence == Occurence.One || TargetType.Occurence == Occurence.OneOrMore);
  957. foreach (XPathItem item in iter) {
  958. if (occured && onlyOnce)
  959. return false;
  960. if (!TargetType.CanConvert (item))
  961. return false;
  962. }
  963. return occured || !required;
  964. }
  965. #endregion
  966. }
  967. internal class CastExpr : AtomicTypeOperationExpr
  968. {
  969. public CastExpr (ExprSingle expr, XmlTypeCode atomicType, bool optional)
  970. : base (expr, atomicType, optional)
  971. {
  972. }
  973. #region CompileAndEvaluate
  974. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  975. {
  976. Expr = Expr.Compile (compiler);
  977. // FIXME: check return type and if it never matches then return boolean
  978. return this;
  979. }
  980. public override SequenceType StaticType {
  981. get { return TargetType; }
  982. }
  983. public override XPathSequence Evaluate (XPathSequence iter)
  984. {
  985. if (TargetType.CanConvert (iter))
  986. return new ConvertingIterator (iter, TargetType);
  987. else
  988. throw new XmlQueryException (String.Format ("Cannot cast as {1}", TargetType));
  989. }
  990. #endregion
  991. }
  992. // ComparisonExpr
  993. internal class ComparisonExpr : BinaryOperationExpr
  994. {
  995. public ComparisonExpr (ExprSingle left, ExprSingle right, ComparisonOperator oper)
  996. : base (left, right)
  997. {
  998. this.oper = oper;
  999. }
  1000. ComparisonOperator oper;
  1001. public ComparisonOperator Operation {
  1002. get { return oper; }
  1003. }
  1004. #region CompileAndEvaluate
  1005. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1006. {
  1007. Left = Left.Compile (compiler);
  1008. Right = Right.Compile (compiler);
  1009. // FIXME: check return type and if it never matches then return boolean
  1010. return this;
  1011. }
  1012. public override SequenceType StaticType {
  1013. get { return SequenceType.Boolean; }
  1014. }
  1015. public override XPathSequence Evaluate (XPathSequence iter)
  1016. {
  1017. bool isEmpty;
  1018. bool result = EvaluateAsBoolean (iter, out isEmpty);
  1019. if (isEmpty)
  1020. return new XPathEmptySequence (iter.Context);
  1021. return new SingleItemIterator (result ? AtomicTrue : AtomicFalse, iter.Context);
  1022. }
  1023. public override bool EvaluateAsBoolean (XPathSequence iter)
  1024. {
  1025. bool isEmpty;
  1026. return EvaluateAsBoolean (iter, out isEmpty);
  1027. }
  1028. private bool EvaluateAsBoolean (XPathSequence iter, out bool isEmpty)
  1029. {
  1030. XPathSequence lseq, rseq;
  1031. isEmpty = false;
  1032. switch (Operation) {
  1033. // FIXME: it is curious but currently gmcs requires full typename.
  1034. case Mono.Xml.XPath2.ComparisonOperator.ValueEQ:
  1035. case Mono.Xml.XPath2.ComparisonOperator.ValueNE:
  1036. case Mono.Xml.XPath2.ComparisonOperator.ValueLT:
  1037. case Mono.Xml.XPath2.ComparisonOperator.ValueLE:
  1038. case Mono.Xml.XPath2.ComparisonOperator.ValueGT:
  1039. case Mono.Xml.XPath2.ComparisonOperator.ValueGE:
  1040. XPathItem itemVL = ExamineOneItem (Left.Evaluate (iter));
  1041. XPathItem itemVR = ExamineOneItem (Right.Evaluate (iter));
  1042. if (itemVL == null || itemVR == null) {
  1043. isEmpty = true;
  1044. return false;
  1045. }
  1046. return CompareAtomic (itemVL, itemVR);
  1047. case Mono.Xml.XPath2.ComparisonOperator.GeneralEQ:
  1048. case Mono.Xml.XPath2.ComparisonOperator.GeneralNE:
  1049. case Mono.Xml.XPath2.ComparisonOperator.GeneralLT:
  1050. case Mono.Xml.XPath2.ComparisonOperator.GeneralLE:
  1051. case Mono.Xml.XPath2.ComparisonOperator.GeneralGT:
  1052. case Mono.Xml.XPath2.ComparisonOperator.GeneralGE:
  1053. lseq = Left.Evaluate (iter);
  1054. rseq = Right.Evaluate (iter);
  1055. foreach (XPathItem itemGL in lseq) {
  1056. foreach (XPathItem itemGR in rseq.Clone ()) {
  1057. if (CompareAtomic (itemGL, itemGR))
  1058. return true;
  1059. }
  1060. }
  1061. return false;
  1062. case Mono.Xml.XPath2.ComparisonOperator.NodeIs:
  1063. case Mono.Xml.XPath2.ComparisonOperator.NodeFWD:
  1064. case Mono.Xml.XPath2.ComparisonOperator.NodeBWD:
  1065. XPathNavigator lnav = ExamineOneNode (Left.Evaluate (iter));
  1066. XPathNavigator rnav = ExamineOneNode (Right.Evaluate (iter));
  1067. if (lnav == null || rnav == null) {
  1068. isEmpty = true;
  1069. return false;
  1070. }
  1071. switch (Operation) {
  1072. case Mono.Xml.XPath2.ComparisonOperator.NodeIs:
  1073. return lnav.IsSamePosition (rnav);
  1074. case Mono.Xml.XPath2.ComparisonOperator.NodeFWD:
  1075. return lnav.ComparePosition (rnav) == XmlNodeOrder.Before;
  1076. case Mono.Xml.XPath2.ComparisonOperator.NodeBWD:
  1077. return lnav.ComparePosition (rnav) == XmlNodeOrder.After;
  1078. }
  1079. break;
  1080. }
  1081. throw new SystemException ("XQuery internal error: should not happen.");
  1082. }
  1083. // returns null if sequence was empty
  1084. private XPathItem ExamineOneItem (XPathSequence seq)
  1085. {
  1086. if (!seq.MoveNext ())
  1087. return null;
  1088. XPathItem item = seq.Current;
  1089. if (seq.MoveNext ())
  1090. throw new XmlQueryException ("Operand of value comparison expression must be evaluated as a sequence that contains exactly one item.");
  1091. return item;
  1092. }
  1093. // returns null if sequence was empty
  1094. private XPathNavigator ExamineOneNode (XPathSequence seq)
  1095. {
  1096. if (!seq.MoveNext ())
  1097. return null;
  1098. XPathNavigator nav = seq.Current as XPathNavigator;
  1099. if (nav == null || seq.MoveNext ())
  1100. throw new XmlQueryException ("Operand of node comparison expression must be evaluated as a sequence that contains exactly one node.");
  1101. return nav;
  1102. }
  1103. private bool CompareAtomic (XPathItem itemL, XPathItem itemR)
  1104. {
  1105. XmlSchemaSimpleType ua = XmlSchemaSimpleType.XdtUntypedAtomic;
  1106. XmlSchemaSimpleType str = XmlSchemaSimpleType.XsString;
  1107. // FIXME: XPathNavigator might be complex content.
  1108. bool uaL = itemL.XmlType == null || itemL.XmlType == ua;
  1109. bool uaR = itemR.XmlType == null || itemR.XmlType == ua;
  1110. bool bothUA = uaL && uaR;
  1111. XPathAtomicValue avL =
  1112. (uaL) ?
  1113. bothUA ? new XPathAtomicValue (itemL.Value, str) :
  1114. new XPathAtomicValue (itemL.Value, itemR.XmlType) :
  1115. Atomize (itemL);
  1116. XPathAtomicValue avR =
  1117. uaR ?
  1118. bothUA ? new XPathAtomicValue (itemR.Value, str) :
  1119. new XPathAtomicValue (itemR.Value, itemL.XmlType) :
  1120. Atomize (itemR);
  1121. switch (Operation) {
  1122. // FIXME: it is curious but currently gmcs requires full typename.
  1123. case Mono.Xml.XPath2.ComparisonOperator.ValueEQ:
  1124. case Mono.Xml.XPath2.ComparisonOperator.GeneralEQ:
  1125. return XQueryComparisonOperator.ValueEQ (avL, avR);
  1126. case Mono.Xml.XPath2.ComparisonOperator.ValueNE:
  1127. case Mono.Xml.XPath2.ComparisonOperator.GeneralNE:
  1128. return XQueryComparisonOperator.ValueNE (avL, avR);
  1129. case Mono.Xml.XPath2.ComparisonOperator.ValueLT:
  1130. case Mono.Xml.XPath2.ComparisonOperator.GeneralLT:
  1131. return XQueryComparisonOperator.ValueLT (avL, avR);
  1132. case Mono.Xml.XPath2.ComparisonOperator.ValueLE:
  1133. case Mono.Xml.XPath2.ComparisonOperator.GeneralLE:
  1134. return XQueryComparisonOperator.ValueLE (avL, avR);
  1135. case Mono.Xml.XPath2.ComparisonOperator.ValueGT:
  1136. case Mono.Xml.XPath2.ComparisonOperator.GeneralGT:
  1137. return XQueryComparisonOperator.ValueGT (avL, avR);
  1138. case Mono.Xml.XPath2.ComparisonOperator.ValueGE:
  1139. case Mono.Xml.XPath2.ComparisonOperator.GeneralGE:
  1140. return XQueryComparisonOperator.ValueGE (avL, avR);
  1141. }
  1142. return false; // should not happen
  1143. }
  1144. #endregion
  1145. }
  1146. public enum ComparisonOperator {
  1147. ValueEQ,
  1148. ValueNE,
  1149. ValueLT,
  1150. ValueLE,
  1151. ValueGT,
  1152. ValueGE,
  1153. GeneralEQ,
  1154. GeneralNE,
  1155. GeneralLT,
  1156. GeneralLE,
  1157. GeneralGT,
  1158. GeneralGE,
  1159. NodeIs,
  1160. NodeFWD,
  1161. NodeBWD
  1162. }
  1163. // Range
  1164. internal class RangeExpr : BinaryOperationExpr
  1165. {
  1166. public RangeExpr (ExprSingle left, ExprSingle right)
  1167. : base (left, right)
  1168. {
  1169. }
  1170. #region CompileAndEvaluate
  1171. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1172. {
  1173. Left = Left.Compile (compiler);
  1174. Right = Right.Compile (compiler);
  1175. return this;
  1176. }
  1177. public override SequenceType StaticType {
  1178. get { return SequenceType.IntegerList; }
  1179. }
  1180. public override XPathSequence Evaluate (XPathSequence iter)
  1181. {
  1182. int start = Left.EvaluateAsInt (iter);
  1183. int end = Right.EvaluateAsInt (iter);
  1184. return new IntegerRangeIterator (iter.Context, start, end);
  1185. }
  1186. public override void Serialize (XPathSequence iter)
  1187. {
  1188. int start = Left.EvaluateAsInt (iter);
  1189. int end = Right.EvaluateAsInt (iter);
  1190. for (int i = start; i <= end; i++) {
  1191. iter.Context.Writer.WriteValue (i);
  1192. if (i < end)
  1193. iter.Context.Writer.WriteWhitespace (" ");
  1194. }
  1195. }
  1196. #endregion
  1197. }
  1198. // arithmetic operation expr
  1199. public enum ArithmeticOperator {
  1200. Add,
  1201. Sub,
  1202. Mul,
  1203. Div,
  1204. IDiv,
  1205. IMod
  1206. }
  1207. internal class ArithmeticOperationExpr : BinaryOperationExpr
  1208. {
  1209. public ArithmeticOperationExpr (ExprSingle left, ExprSingle right, ArithmeticOperator oper)
  1210. : base (left, right)
  1211. {
  1212. this.oper = oper;
  1213. }
  1214. ArithmeticOperator oper;
  1215. public ArithmeticOperator Operation {
  1216. get { return oper; }
  1217. }
  1218. #region CompileAndEvaluate
  1219. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1220. {
  1221. Left = Left.Compile (compiler);
  1222. Right = Right.Compile (compiler);
  1223. return this;
  1224. }
  1225. // FIXME: It can be optimized by comparing l/r value types.
  1226. public override SequenceType StaticType {
  1227. get { return SequenceType.AnyType; }
  1228. }
  1229. public override XPathSequence Evaluate (XPathSequence iter)
  1230. {
  1231. XPathSequence lseq = Left.Evaluate (iter);
  1232. if (!lseq.MoveNext ())
  1233. return new XPathEmptySequence (iter.Context);
  1234. XPathSequence rseq = Right.Evaluate (iter);
  1235. if (!rseq.MoveNext ())
  1236. return new XPathEmptySequence (iter.Context);
  1237. XPathAtomicValue lvalue = Atomize (lseq.Current);
  1238. XPathAtomicValue rvalue = Atomize (rseq.Current);
  1239. if (lseq.MoveNext ())
  1240. throw new XmlQueryException ("XP0006: Left operand resulted in an sequence that contains more than one item.");
  1241. if (rseq.MoveNext ())
  1242. throw new XmlQueryException ("XP0006: Left operand resulted in an sequence that contains more than one item.");
  1243. // FIXME: handle "untypedAtomic to xs:double" casting
  1244. return new SingleItemIterator (Compute (lvalue, rvalue), iter.Context);
  1245. }
  1246. private XPathAtomicValue Compute (XPathAtomicValue lvalue, XPathAtomicValue rvalue)
  1247. {
  1248. switch (Operation) {
  1249. case ArithmeticOperator.Add:
  1250. return XQueryArithmeticOperator.Add (lvalue, rvalue);
  1251. case ArithmeticOperator.Sub:
  1252. return XQueryArithmeticOperator.Subtract (lvalue, rvalue);
  1253. case ArithmeticOperator.Mul:
  1254. return XQueryArithmeticOperator.Multiply (lvalue, rvalue);
  1255. case ArithmeticOperator.Div:
  1256. return XQueryArithmeticOperator.Divide (lvalue, rvalue);
  1257. case ArithmeticOperator.IDiv:
  1258. return XQueryArithmeticOperator.IntDivide (lvalue, rvalue);
  1259. case ArithmeticOperator.IMod:
  1260. return XQueryArithmeticOperator.Remainder (lvalue, rvalue);
  1261. default:
  1262. throw new SystemException ("XQuery internal error: should not happen.");
  1263. }
  1264. }
  1265. #endregion
  1266. }
  1267. internal class MinusExpr : ExprSingle
  1268. {
  1269. public MinusExpr (ExprSingle expr)
  1270. {
  1271. this.expr = expr;
  1272. }
  1273. ExprSingle expr;
  1274. public ExprSingle Expr {
  1275. get { return expr; }
  1276. set { expr = value; }
  1277. }
  1278. internal override void CheckReference (XQueryASTCompiler compiler)
  1279. {
  1280. expr.CheckReference (compiler);
  1281. }
  1282. #region CompileAndEvaluate
  1283. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1284. {
  1285. return new ArithmeticOperationExpr (new DecimalLiteralExpr (-1), Expr, ArithmeticOperator.Mul).Compile (compiler);
  1286. }
  1287. public override SequenceType StaticType {
  1288. get { return Expr.StaticType; }
  1289. }
  1290. public override XPathSequence Evaluate (XPathSequence iter)
  1291. {
  1292. throw new SystemException ("XQuery internal error: should not happen.");
  1293. }
  1294. #endregion
  1295. }
  1296. // aggregation expr
  1297. public enum AggregationType {
  1298. Union,
  1299. Intersect,
  1300. Except
  1301. }
  1302. internal class GroupExpr : BinaryOperationExpr
  1303. {
  1304. public GroupExpr (ExprSingle left, ExprSingle right, AggregationType aggrType)
  1305. : base (left, right)
  1306. {
  1307. this.aggrType = aggrType;
  1308. }
  1309. AggregationType aggrType;
  1310. public AggregationType AggregationType {
  1311. get { return aggrType; }
  1312. }
  1313. #region CompileAndEvaluate
  1314. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1315. {
  1316. Left = Left.Compile (compiler);
  1317. Right = Right.Compile (compiler);
  1318. return this;
  1319. }
  1320. // FIXME: It can be optimized by comparing l/r value types.
  1321. public override SequenceType StaticType {
  1322. get { return SequenceType.AnyType; }
  1323. }
  1324. // only applicable against node-sets
  1325. public override XPathSequence Evaluate (XPathSequence iter)
  1326. {
  1327. return new GroupIterator (iter, this);
  1328. }
  1329. #endregion
  1330. }
  1331. // validate expr
  1332. internal class ValidateExpr : ExprSingle
  1333. {
  1334. XmlSchemaContentProcessing schemaMode;
  1335. ExprSequence expr;
  1336. public ValidateExpr (XmlSchemaContentProcessing schemaMode, ExprSequence expr)
  1337. {
  1338. this.schemaMode = schemaMode;
  1339. this.expr = expr;
  1340. }
  1341. public ExprSequence Expr {
  1342. get { return expr; }
  1343. }
  1344. public XmlSchemaContentProcessing SchemaMode {
  1345. get { return schemaMode; }
  1346. }
  1347. internal override void CheckReference (XQueryASTCompiler compiler)
  1348. {
  1349. expr.CheckReference (compiler);
  1350. }
  1351. #region CompileAndEvaluate
  1352. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1353. {
  1354. for (int i = 0; i < expr.Count; i++)
  1355. expr [i] = expr [i].Compile (compiler);
  1356. return this;
  1357. }
  1358. public override SequenceType StaticType {
  1359. get { return SequenceType.AnyType; }
  1360. }
  1361. public override XPathSequence Evaluate (XPathSequence iter)
  1362. {
  1363. // TBD (see 3.13).
  1364. throw new NotImplementedException ();
  1365. }
  1366. #endregion
  1367. }
  1368. // Path expr
  1369. internal abstract class PathExpr : ExprSingle
  1370. {
  1371. }
  1372. // '/'
  1373. internal class PathRootExpr : PathExpr
  1374. {
  1375. public PathRootExpr ()
  1376. {
  1377. }
  1378. internal override void CheckReference (XQueryASTCompiler compiler)
  1379. {
  1380. }
  1381. #region CompileAndEvaluate
  1382. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1383. {
  1384. return this;
  1385. }
  1386. public override SequenceType StaticType {
  1387. get { return SequenceType.Document; }
  1388. }
  1389. public override XPathSequence Evaluate (XPathSequence iter)
  1390. {
  1391. XPathNavigator nav = iter.Context.CurrentItem as XPathNavigator;
  1392. if (nav == null)
  1393. throw new XmlQueryException ("Context item is not a node when evaluating expression '/'.");
  1394. nav = nav.Clone ();
  1395. nav.MoveToRoot ();
  1396. return new SingleItemIterator (nav, iter.Context);
  1397. }
  1398. #endregion
  1399. }
  1400. internal abstract class PathStepExpr : PathExpr
  1401. {
  1402. ExprSingle first;
  1403. ExprSingle next;
  1404. public PathStepExpr (ExprSingle first, ExprSingle next)
  1405. {
  1406. this.first = first;
  1407. this.next = next;
  1408. }
  1409. public ExprSingle First {
  1410. get { return first; }
  1411. set { first = value; }
  1412. }
  1413. public ExprSingle Next {
  1414. get { return next; }
  1415. set { next = value; }
  1416. }
  1417. internal override void CheckReference (XQueryASTCompiler compiler)
  1418. {
  1419. first.CheckReference (compiler);
  1420. next.CheckReference (compiler);
  1421. }
  1422. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1423. {
  1424. first = first.Compile (compiler);
  1425. next = next.Compile (compiler);
  1426. return this;
  1427. }
  1428. }
  1429. // 'foo/bar'
  1430. internal class PathSlashExpr : PathStepExpr
  1431. {
  1432. public PathSlashExpr (ExprSingle first, ExprSingle next)
  1433. : base (first, next)
  1434. {
  1435. }
  1436. #region CompileAndEvaluate
  1437. // FIXME: It can be optimized by comparing l/r value types.
  1438. public override SequenceType StaticType {
  1439. get { return SequenceType.Node; }
  1440. }
  1441. public override XPathSequence Evaluate (XPathSequence iter)
  1442. {
  1443. return new PathStepIterator (First.Evaluate (iter), this);
  1444. }
  1445. #endregion
  1446. }
  1447. // 'foo//bar'
  1448. internal class PathSlash2Expr : PathStepExpr
  1449. {
  1450. public PathSlash2Expr (ExprSingle first, ExprSingle next)
  1451. : base (first, next)
  1452. {
  1453. }
  1454. #region CompileAndEvaluate
  1455. // FIXME: It can be optimized by comparing l/r value types.
  1456. public override SequenceType StaticType {
  1457. get { return SequenceType.Node; }
  1458. }
  1459. public override XPathSequence Evaluate (XPathSequence iter)
  1460. {
  1461. XPathSequence seq = First.Evaluate (iter);
  1462. if (!seq.MoveNext ())
  1463. return new XPathEmptySequence (iter.Context);
  1464. return new PathStepIterator (
  1465. new DescendantOrSelfIterator (seq.Current as XPathNavigator, seq.Context), this);
  1466. }
  1467. #endregion
  1468. }
  1469. internal class AxisStepExpr : PathExpr
  1470. {
  1471. public AxisStepExpr (XPathAxis axis, XPath2NodeTest test)
  1472. {
  1473. this.axis = axis;
  1474. if (test == null)
  1475. nameTest = XmlQualifiedName.Empty;
  1476. else {
  1477. if (test.NameTest != null)
  1478. this.nameTest = test.NameTest;
  1479. else
  1480. this.kindTest = test.KindTest;
  1481. }
  1482. }
  1483. XPathAxis axis;
  1484. XmlQualifiedName nameTest;
  1485. KindTest kindTest;
  1486. public XPathAxis Axis {
  1487. get { return axis; }
  1488. }
  1489. public XmlQualifiedName NameTest {
  1490. get { return nameTest; }
  1491. set { nameTest = value; }
  1492. }
  1493. public KindTest KindTest {
  1494. get { return kindTest; }
  1495. set { kindTest = value; }
  1496. }
  1497. internal override void CheckReference (XQueryASTCompiler compiler)
  1498. {
  1499. if (KindTest != null)
  1500. KindTest.CheckReference (compiler);
  1501. }
  1502. #region CompileAndEvaluate
  1503. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1504. {
  1505. if (KindTest != null)
  1506. KindTest.Compile (compiler);
  1507. return this;
  1508. }
  1509. public override SequenceType StaticType {
  1510. get {
  1511. switch (Axis.AxisType) {
  1512. case XPathAxisType.Attribute:
  1513. return SequenceType.Attribute;
  1514. case XPathAxisType.Namespace:
  1515. return SequenceType.Namespace;
  1516. }
  1517. // FIXME: we can more filtering by KindTest
  1518. return SequenceType.Node;
  1519. }
  1520. }
  1521. public override XPathSequence Evaluate (XPathSequence iter)
  1522. {
  1523. XQueryContext ctx = iter.Context;
  1524. if (iter.Position == 0) {
  1525. iter = iter.Clone ();
  1526. if (!iter.MoveNext ())
  1527. return new XPathEmptySequence (iter.Context);
  1528. }
  1529. XPathNavigator nav = iter.Current as XPathNavigator;
  1530. if (nav == null)
  1531. throw new XmlQueryException ("Node set is expected.");
  1532. NodeIterator argIter = null;
  1533. switch (Axis.AxisType) {
  1534. case XPathAxisType.Child:
  1535. argIter = new ChildIterator (nav, ctx); break;
  1536. case XPathAxisType.Descendant:
  1537. argIter = new DescendantIterator (nav, ctx); break;
  1538. case XPathAxisType.Attribute:
  1539. argIter = new AttributeIterator (nav, ctx); break;
  1540. case XPathAxisType.Self:
  1541. argIter = new SelfIterator (nav, ctx); break;
  1542. case XPathAxisType.DescendantOrSelf:
  1543. argIter = new DescendantOrSelfIterator (nav, ctx); break;
  1544. case XPathAxisType.FollowingSibling:
  1545. argIter = new FollowingSiblingIterator (nav, ctx); break;
  1546. case XPathAxisType.Following:
  1547. argIter = new FollowingIterator (nav, ctx); break;
  1548. case XPathAxisType.Parent:
  1549. argIter = new ParentIterator (nav, ctx); break;
  1550. case XPathAxisType.Ancestor:
  1551. argIter = new AncestorIterator (nav, ctx); break;
  1552. case XPathAxisType.PrecedingSibling:
  1553. argIter = new PrecedingSiblingIterator (nav, ctx); break;
  1554. case XPathAxisType.Preceding:
  1555. argIter = new PrecedingIterator (nav, ctx); break;
  1556. case XPathAxisType.AncestorOrSelf:
  1557. argIter = new AncestorOrSelfIterator (nav, ctx); break;
  1558. case XPathAxisType.Namespace: // only applicable under XPath 2.0: not XQuery 1.0
  1559. argIter = new NamespaceIterator (nav, ctx); break;
  1560. }
  1561. return new AxisIterator (argIter, this);
  1562. }
  1563. internal bool Matches (XPathNavigator nav)
  1564. {
  1565. if (nameTest != null)
  1566. return nameTest == XmlQualifiedName.Empty ||
  1567. ((nameTest.Name == nav.LocalName || nameTest.Name == "*") &&
  1568. (nameTest.Namespace == nav.NamespaceURI || nameTest.Namespace == "*"));
  1569. else
  1570. return kindTest.Matches (nav);
  1571. }
  1572. #endregion
  1573. }
  1574. internal class FilterStepExpr : PathExpr
  1575. {
  1576. public FilterStepExpr (ExprSingle expr, ExprSequence predicate)
  1577. {
  1578. this.expr = expr;
  1579. this.predicate = predicate;
  1580. }
  1581. ExprSingle expr;
  1582. ExprSequence predicate;
  1583. public ExprSingle Expr {
  1584. get { return expr; }
  1585. set { expr = value; }
  1586. }
  1587. public ExprSequence Predicate {
  1588. get { return predicate; }
  1589. }
  1590. internal override void CheckReference (XQueryASTCompiler compiler)
  1591. {
  1592. expr.CheckReference (compiler);
  1593. predicate.CheckReference (compiler);
  1594. }
  1595. #region CompileAndEvaluate
  1596. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1597. {
  1598. Expr = Expr.Compile (compiler);
  1599. for (int i = 0; i < predicate.Count; i++)
  1600. predicate [i] = predicate [i].Compile (compiler);
  1601. return this;
  1602. }
  1603. public override SequenceType StaticType {
  1604. get { return Expr.StaticType; }
  1605. }
  1606. public override XPathSequence Evaluate (XPathSequence iter)
  1607. {
  1608. return new FilteredIterator (iter, this);
  1609. }
  1610. #endregion
  1611. }
  1612. /*
  1613. // predicates == exprsequence list == list of list of exprsingle
  1614. internal class PredicateList : CollectionBase
  1615. {
  1616. public void Add (ExprSequence expr)
  1617. {
  1618. List.Add (expr);
  1619. }
  1620. public void Insert (int pos, ExprSequence expr)
  1621. {
  1622. List.Insert (pos, expr);
  1623. }
  1624. public ExprSequence this [int i] {
  1625. get { return (ExprSequence) List [i]; }
  1626. }
  1627. }
  1628. */
  1629. internal class XPath2NodeTest
  1630. {
  1631. public XPath2NodeTest (XmlQualifiedName nameTest)
  1632. {
  1633. this.NameTest = nameTest;
  1634. }
  1635. public XPath2NodeTest (KindTest kindTest)
  1636. {
  1637. this.KindTest = kindTest;
  1638. }
  1639. public XmlQualifiedName NameTest;
  1640. public KindTest KindTest;
  1641. }
  1642. internal class EnclosedExpr : ExprSingle
  1643. {
  1644. ExprSequence expr;
  1645. public EnclosedExpr (ExprSequence expr)
  1646. {
  1647. this.expr = expr;
  1648. }
  1649. public ExprSequence Expr {
  1650. get { return expr; }
  1651. }
  1652. internal override void CheckReference (XQueryASTCompiler compiler)
  1653. {
  1654. expr.CheckReference (compiler);
  1655. }
  1656. #region CompileAndEvaluate
  1657. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1658. {
  1659. if (Expr.Count == 1)
  1660. return Expr [0].Compile (compiler);
  1661. for (int i = 0; i < Expr.Count; i++)
  1662. Expr [i] = Expr [i].Compile (compiler);
  1663. return this;
  1664. }
  1665. // FIXME: can be optimized by checking all items in Expr
  1666. public override SequenceType StaticType {
  1667. get { return SequenceType.AnyType; }
  1668. }
  1669. public override XPathSequence Evaluate (XPathSequence iter)
  1670. {
  1671. return new ExprSequenceIterator (iter, Expr);
  1672. }
  1673. #endregion
  1674. }
  1675. // PrimaryExpr
  1676. internal abstract class PrimaryExpr : ExprSingle
  1677. {
  1678. internal override void CheckReference (XQueryASTCompiler compiler)
  1679. {
  1680. }
  1681. #region CompileAndEvaluate
  1682. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1683. {
  1684. return this;
  1685. }
  1686. public override XPathSequence Evaluate (XPathSequence iter)
  1687. {
  1688. return new SingleItemIterator (EvaluateAsAtomic (iter), iter.Context);
  1689. }
  1690. #endregion
  1691. }
  1692. internal class StringLiteralExpr : PrimaryExpr
  1693. {
  1694. string literal;
  1695. public StringLiteralExpr (string literal)
  1696. {
  1697. this.literal = literal;
  1698. }
  1699. public string Literal {
  1700. get { return literal; }
  1701. }
  1702. #region CompileAndEvaluate
  1703. XmlSchemaSimpleType stringType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("string", XmlSchema.Namespace));
  1704. public override SequenceType StaticType {
  1705. get { return SequenceType.AtomicString; }
  1706. }
  1707. public override string EvaluateAsString (XPathSequence iter)
  1708. {
  1709. return Literal;
  1710. }
  1711. public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  1712. {
  1713. return new XPathAtomicValue (Literal, stringType);
  1714. }
  1715. #endregion
  1716. }
  1717. internal class DecimalLiteralExpr : PrimaryExpr
  1718. {
  1719. decimal value;
  1720. public DecimalLiteralExpr (decimal value)
  1721. {
  1722. this.value = value;
  1723. }
  1724. public decimal Value {
  1725. get { return value; }
  1726. }
  1727. #region CompileAndEvaluate
  1728. XmlSchemaSimpleType decimalType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("decimal", XmlSchema.Namespace));
  1729. public override SequenceType StaticType {
  1730. get { return SequenceType.Decimal; }
  1731. }
  1732. public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  1733. {
  1734. return new XPathAtomicValue (Value, decimalType);
  1735. }
  1736. #endregion
  1737. }
  1738. internal class DoubleLiteralExpr : PrimaryExpr
  1739. {
  1740. double value;
  1741. public DoubleLiteralExpr (double value)
  1742. {
  1743. this.value = value;
  1744. }
  1745. public double Value {
  1746. get { return value; }
  1747. }
  1748. #region CompileAndEvaluate
  1749. XmlSchemaSimpleType doubleType = XmlSchemaType.GetBuiltInSimpleType (new XmlQualifiedName ("double", XmlSchema.Namespace));
  1750. public override SequenceType StaticType {
  1751. get { return SequenceType.Double; }
  1752. }
  1753. public override XPathAtomicValue EvaluateAsAtomic (XPathSequence iter)
  1754. {
  1755. return new XPathAtomicValue (Value, doubleType);
  1756. }
  1757. #endregion
  1758. }
  1759. internal class VariableReferenceExpr : PrimaryExpr
  1760. {
  1761. XmlQualifiedName varName;
  1762. public VariableReferenceExpr (XmlQualifiedName varName)
  1763. {
  1764. this.varName = varName;
  1765. }
  1766. public XmlQualifiedName VariableName {
  1767. get { return varName; }
  1768. }
  1769. // FIXME: variable name must be stacked in any area
  1770. // whereever variables are defined.
  1771. internal override void CheckReference (XQueryASTCompiler compiler)
  1772. {
  1773. compiler.CheckVariableName (varName);
  1774. }
  1775. #region CompileAndEvaluate
  1776. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1777. {
  1778. // FIXME: try to resolve static context variable and return the actual value expression
  1779. return this;
  1780. }
  1781. public override SequenceType StaticType {
  1782. get { return SequenceType.AnyType; }
  1783. }
  1784. public override XPathSequence Evaluate (XPathSequence iter)
  1785. {
  1786. XPathSequence variable = iter.Context.ResolveVariable (VariableName);
  1787. // FIXME: if Evaluate() accepts XPathSequence, then XPathSequence must be public class (to make IXPath2Variable public).
  1788. return variable;
  1789. }
  1790. #endregion
  1791. }
  1792. internal class ParenthesizedExpr : PrimaryExpr
  1793. {
  1794. ExprSequence expr;
  1795. public ParenthesizedExpr (ExprSequence expr)
  1796. {
  1797. if (expr == null)
  1798. expr = new ExprSequence ();
  1799. this.expr = expr;
  1800. }
  1801. ExprSequence Expr {
  1802. get { return expr; }
  1803. }
  1804. #region CompileAndEvaluate
  1805. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1806. {
  1807. if (Expr.Count == 1)
  1808. return Expr [0].Compile (compiler);
  1809. for (int i = 0; i < Expr.Count; i++)
  1810. Expr [i] = Expr [i].Compile (compiler);
  1811. return this;
  1812. }
  1813. // FIXME: can be optimized by checking all items in Expr
  1814. public override SequenceType StaticType {
  1815. get { return SequenceType.AnyType; }
  1816. }
  1817. public override XPathSequence Evaluate (XPathSequence iter)
  1818. {
  1819. switch (Expr.Count) {
  1820. case 0:
  1821. return new XPathEmptySequence (iter.Context);
  1822. case 1:
  1823. return Expr [0].Evaluate (iter);
  1824. default:
  1825. return new ExprSequenceIterator (iter, Expr);
  1826. }
  1827. }
  1828. #endregion
  1829. }
  1830. // "."
  1831. internal class ContextItemExpr : PrimaryExpr
  1832. {
  1833. public ContextItemExpr ()
  1834. {
  1835. }
  1836. #region CompileAndEvaluate
  1837. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1838. {
  1839. return this;
  1840. }
  1841. public override SequenceType StaticType {
  1842. get { return SequenceType.AnyType; }
  1843. }
  1844. public override XPathSequence Evaluate (XPathSequence iter)
  1845. {
  1846. return new SingleItemIterator (iter.Context.CurrentItem, iter.Context);
  1847. }
  1848. #endregion
  1849. }
  1850. internal abstract class FunctionCallExprBase : PrimaryExpr
  1851. {
  1852. XmlQualifiedName name;
  1853. ExprSequence args;
  1854. public FunctionCallExprBase (XmlQualifiedName name, ExprSequence args)
  1855. {
  1856. if (args == null)
  1857. throw new ArgumentNullException (String.Format ("Function argument expressions for {0} is null.", name));
  1858. this.name = name;
  1859. this.args = args;
  1860. }
  1861. public XmlQualifiedName Name {
  1862. get { return name; }
  1863. }
  1864. public ExprSequence Args {
  1865. get { return args; }
  1866. }
  1867. internal override void CheckReference (XQueryASTCompiler compiler)
  1868. {
  1869. compiler.CheckFunctionName (name);
  1870. }
  1871. #region CompileAndEvaluate
  1872. /*
  1873. internal static DefaultFunctionCall Create (
  1874. XmlQualifiedName name,
  1875. ExprSingle [] args,
  1876. XQueryStaticContext ctx)
  1877. {
  1878. switch (name.Namespace) {
  1879. case XQueryFunction.Namespace:
  1880. switch (name.Name) {
  1881. case "node-name":
  1882. return new FnNodeNameCall (ctx, args);
  1883. case "nilled":
  1884. return new FnNilledCall (ctx, args);
  1885. case "string":
  1886. return new FnStringCall (ctx, args);
  1887. case "data":
  1888. return new FnDataCall (ctx, args);
  1889. case "base-uri":
  1890. return new FnBaseUriCall (ctx, args);
  1891. case "document-uri":
  1892. return new FnDocumentUriCall (ctx, args);
  1893. case "error":
  1894. return new FnErrorCall (ctx, args);
  1895. case "trace":
  1896. return new FnTraceCall (ctx, args);
  1897. case "abs":
  1898. return new FnAbsCall (ctx, args);
  1899. case "ceiling":
  1900. return new FnCeilingCall (ctx, args);
  1901. case "floor":
  1902. return new FnFloorCall (ctx, args);
  1903. case "round":
  1904. return new FnRoundCall (ctx, args);
  1905. case "round-half-to-even":
  1906. return new FnRoundHalfToEvenCall (ctx, args);
  1907. case "codepoints-to-string":
  1908. return new FnCodepointsToStringCall (ctx, args);
  1909. case "string-to-codepoints":
  1910. return new FnStringCallToCodepointsCall (ctx, args);
  1911. }
  1912. goto default;
  1913. case XmlSchema.XdtNamespace:
  1914. case XmlSchema.Namespace:
  1915. XmlSchemaType type = XmlSchemaType.GetBuiltInSimpleType (name);
  1916. if (type != null)
  1917. return new AtomicConstructorCall (ctx, SequenceType.Create (type, Occurence.One), args);
  1918. type = XmlSchemaType.GetBuiltInComplexType (name);
  1919. if (type == null)
  1920. goto default;
  1921. return null;
  1922. default:
  1923. XQueryFunction func = ctx.CompileContext.InEffectFunctions [name];
  1924. if (func != null)
  1925. return new CustomFunctionCallExpression (ctx, args, func);
  1926. return null;
  1927. }
  1928. }
  1929. */
  1930. internal void CheckArguments (XQueryASTCompiler compiler)
  1931. {
  1932. if (args.Count < MinArgs || args.Count > MaxArgs)
  1933. // FIXME: add more info
  1934. throw new XmlQueryCompileException (String.Format ("{0} is invalid for the number of {1} function argument. MinArgs = {2}, MaxArgs = {3}.", args.Count, name, MinArgs, MaxArgs));
  1935. }
  1936. public abstract int MinArgs { get; }
  1937. public abstract int MaxArgs { get; }
  1938. #endregion
  1939. }
  1940. internal class FunctionCallExpr : FunctionCallExprBase
  1941. {
  1942. public FunctionCallExpr (XmlQualifiedName name, ExprSequence args)
  1943. : base (name, args)
  1944. {
  1945. }
  1946. XQueryFunction function;
  1947. public XQueryFunction Function {
  1948. get { return function; }
  1949. }
  1950. #region CompileAndEvaluate
  1951. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  1952. {
  1953. // resolve function
  1954. function = compiler.ResolveFunction (Name);
  1955. CheckArguments (compiler);
  1956. for (int i = 0; i < Args.Count; i++)
  1957. Args [i] = Args [i].Compile (compiler);
  1958. return this;
  1959. }
  1960. public override int MinArgs {
  1961. get { return function.MinArgs; }
  1962. }
  1963. public override int MaxArgs {
  1964. get { return function.MaxArgs; }
  1965. }
  1966. public override SequenceType StaticType {
  1967. get { return function.ReturnType; }
  1968. }
  1969. public override XPathSequence Evaluate (XPathSequence iter)
  1970. {
  1971. return Function.Evaluate (iter, Args);
  1972. }
  1973. // FIXME: add all overrides that delegates to XQueryFunction
  1974. #endregion
  1975. }
  1976. /*
  1977. #region CompileAndEvaluate
  1978. // It is instantiated per function call expression.
  1979. // (e.g. the example below contains 4 FunctionCallExpression instances:
  1980. // "replace(node-name (node-before(/*)), 'foo', node-name($var))"
  1981. internal class CustomFunctionCallExpr : FunctionCallExprBase
  1982. {
  1983. public CustomFunctionCallExpr (ExprSequence args, XQueryFunction function)
  1984. : base (function.Name, args)
  1985. {
  1986. this.function = function;
  1987. }
  1988. XQueryFunction function;
  1989. public XQueryFunction Function {
  1990. get { return function; }
  1991. }
  1992. public override int MinArgs {
  1993. get { return function.MinArgs; }
  1994. }
  1995. public override int MaxArgs {
  1996. get { return function.MaxArgs; }
  1997. }
  1998. public override SequenceType StaticType {
  1999. get { return function.ReturnType; }
  2000. }
  2001. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  2002. {
  2003. CheckArguments (compiler);
  2004. for (int i = 0; i < Args.Count; i++)
  2005. Args [i] = Args [i].Compile (compiler);
  2006. return this;
  2007. }
  2008. public override XPathSequence Evaluate (XPathSequence iter)
  2009. {
  2010. return Function.Evaluate (iter, Args);
  2011. }
  2012. // FIXME: add all overrides that delegates to XQueryFunction
  2013. }
  2014. #endregion
  2015. */
  2016. // Ordered / Unordered
  2017. internal class OrderSpecifiedExpr : ExprSingle
  2018. {
  2019. bool ordered;
  2020. ExprSequence expr;
  2021. public OrderSpecifiedExpr (ExprSequence expr, bool ordered)
  2022. {
  2023. this.ordered = ordered;
  2024. this.expr = expr;
  2025. }
  2026. public ExprSequence Expr {
  2027. get { return expr; }
  2028. }
  2029. public bool Ordered {
  2030. get { return ordered; }
  2031. }
  2032. internal override void CheckReference (XQueryASTCompiler compiler)
  2033. {
  2034. expr.CheckReference (compiler);
  2035. }
  2036. #region CompileAndEvaluate
  2037. public override SequenceType StaticType {
  2038. // FIXME: could be optimized by checking all the expressions
  2039. get { return SequenceType.AnyType; }
  2040. }
  2041. public override bool RequireSorting {
  2042. get { return Ordered; }
  2043. }
  2044. internal override ExprSingle CompileCore (XQueryASTCompiler compiler)
  2045. {
  2046. for (int i = 0; i < Expr.Count; i++)
  2047. Expr [i] = Expr [i].Compile (compiler);
  2048. return this;
  2049. }
  2050. public override XPathSequence Evaluate (XPathSequence iter)
  2051. {
  2052. throw new NotImplementedException ();
  2053. }
  2054. #endregion
  2055. }
  2056. }
  2057. #endif