2
0

XPath2Expression.cs 58 KB

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