Sfoglia il codice sorgente

2004-08-30 Atsushi Enomoto <[email protected]>

	* XPath2Expression.cs : empty ExprSequence should not be allowed for
	  FLWORExpr.WhereClause. It should be null.
	* XPathSequence.cs : ExprSequenceIterator.Clone() was missing copy of
	  the input sequence. FLWORIterator.MoveNext() had incorrect !(not)
	  and wrong Where test.
	* XQueryContext.cs : sequence should be cloned when pushed to context.

svn path=/trunk/mcs/; revision=33031
Atsushi Eno 21 anni fa
parent
commit
e4b1cc6ead

+ 9 - 0
mcs/class/System.XML/System.Xml.Query/ChangeLog

@@ -1,3 +1,12 @@
+2004-08-30  Atsushi Enomoto <[email protected]>
+
+	* XPath2Expression.cs : empty ExprSequence should not be allowed for
+	  FLWORExpr.WhereClause. It should be null.
+	* XPathSequence.cs : ExprSequenceIterator.Clone() was missing copy of
+	  the input sequence. FLWORIterator.MoveNext() had incorrect !(not)
+	  and wrong Where test.
+	* XQueryContext.cs : sequence should be cloned when pushed to context.
+
 2004-08-30  Atsushi Enomoto <[email protected]>
 
 	* XQueryCommandImpl.cs : dust cleaning :(

+ 10 - 6
mcs/class/System.XML/System.Xml.Query/XPath2Expression.cs

@@ -240,7 +240,8 @@ namespace Mono.Xml.XPath2
 		public FLWORExpr (ForLetClauseCollection forlet, ExprSequence whereClause, OrderSpecList orderBy, ExprSingle ret)
 		{
 			this.fl = forlet;
-			this.whereClause = new ParenthesizedExpr (whereClause);
+			if (whereClause != null)
+				this.whereClause = new ParenthesizedExpr (whereClause);
 			this.orderBy = orderBy;
 			this.ret = ret;
 		}
@@ -293,8 +294,6 @@ namespace Mono.Xml.XPath2
 				}
 			}
 			if (WhereClause != null)
-//				for (int i = 0; i < WhereClause.Count; i++)
-//					WhereClause [i] = WhereClause [i].Compile (compiler);
 				whereClause = whereClause.Compile (compiler);
 			if (OrderBy != null)
 				foreach (OrderSpec os in OrderBy)
@@ -1820,7 +1819,7 @@ namespace Mono.Xml.XPath2
 
 		public override XPathSequence Evaluate (XPathSequence iter)
 		{
-			return new SingleItemIterator (EvaluateAsAtomic (iter), iter);
+			return new SingleItemIterator (EvaluateAsAtomic (iter), iter.Context);
 		}
 #endregion
 	}
@@ -1983,9 +1982,14 @@ namespace Mono.Xml.XPath2
 
 		public override XPathSequence Evaluate (XPathSequence iter)
 		{
-			if (Expr.Count == 0)
+			switch (Expr.Count) {
+			case 0:
 				return new XPathEmptySequence (iter.Context);
-			return new ExprSequenceIterator (iter, Expr);
+			case 1:
+				return Expr [0].Evaluate (iter);
+			default:
+				return new ExprSequenceIterator (iter, Expr);
+			}
 		}
 #endregion
 	}

+ 20 - 18
mcs/class/System.XML/System.Xml.Query/XPathSequence.cs

@@ -518,6 +518,7 @@ namespace Mono.Xml.XPath2
 				foreach (ExprSequence expr in filter) {
 					bool doesntPass = true;
 					// Treat as OK if any of expr passed.
+					// FIXME: handle numeric predicate.
 					foreach (ExprSingle single in expr) {
 						if (single.EvaluateAsBoolean (left)) {
 							doesntPass = false;
@@ -1145,6 +1146,7 @@ namespace Mono.Xml.XPath2
 			if (other.iter != null)
 				iter = other.iter.Clone ();
 			expr = other.expr;
+			contextSequence = other.contextSequence;
 			currentExprIndex = other.currentExprIndex;
 		}
 
@@ -1212,62 +1214,62 @@ namespace Mono.Xml.XPath2
 		{
 			if (en == null)
 				en = GetEnumerator ();
-			return !en.MoveNext ();
+			return en.MoveNext ();
 		}
 
 		public override IEnumerator GetEnumerator ()
 		{
-			IEnumerator forLetClauses = expr.ForLetClauses.GetEnumerator ();
-			return EvaluateRemainingForLet (forLetClauses);
+			IEnumerator forLetEnum = expr.ForLetClauses.GetEnumerator ();
+			// FIXME: this invokation seems to result in an Invalid IL error.
+			return EvaluateRemainingForLet (forLetEnum);
 		}
 		
-		private IEnumerator EvaluateRemainingForLet (IEnumerator forLetClauses)
+		private IEnumerator EvaluateRemainingForLet (IEnumerator forLetEnum)
 		{
 			// Prepare iteration stack
-			if (forLetClauses.MoveNext ()) {
-				ForLetClause flc = (ForLetClause) forLetClauses.Current;
+			if (forLetEnum.MoveNext ()) {
+				ForLetClause flc = (ForLetClause) forLetEnum.Current;
 				IEnumerator flsb = flc.GetEnumerator ();
-				IEnumerator items = EvaluateRemainingForLetSingleItem (forLetClauses, flsb);
+				IEnumerator items = EvaluateRemainingSingleItem (forLetEnum, flsb);
 				while (items.MoveNext ())
 					yield return items.Current;
 				yield break;
 			}
-			bool passedFilter = false;
-			if (expr.WhereClause != null)
+
+			bool passedFilter = expr.WhereClause == null;
+			if (!passedFilter)
 				passedFilter = expr.WhereClause.EvaluateAsBoolean (contextSequence);
-			if (passedFilter)
+			if (passedFilter) {
 				foreach (XPathItem item in expr.ReturnExpr.Evaluate (contextSequence))
 					yield return item;
+			}
 		}
 
-		private IEnumerator EvaluateRemainingForLetSingleItem (IEnumerator forLetClauses, IEnumerator singleBodies)
+		private IEnumerator EvaluateRemainingSingleItem (IEnumerator forLetClauses, IEnumerator singleBodies)
 		{
 			if (singleBodies.MoveNext ()) {
 				ForLetSingleBody sb = singleBodies.Current as ForLetSingleBody;
 				ForSingleBody fsb = sb as ForSingleBody;
 				if (fsb != null) {
 					XPathSequence backup = contextSequence;
-					contextSequence = sb.Expression.Evaluate (Context.CurrentSequence);
-					Context.ContextManager.PushCurrentSequence (contextSequence);
-//					Context = Context.ContextManager.CurrentContext;
-					foreach (XPathItem forItem in contextSequence) {
+					Context.ContextManager.PushCurrentSequence (sb.Expression.Evaluate (Context.CurrentSequence));
+					foreach (XPathItem forItem in Context.CurrentSequence) {
 						Context.PushVariable (fsb.PositionalVar, Context.CurrentSequence.Position);
 						Context.PushVariable (sb.VarName, forItem);
 						// recurse here (including following bindings)
 						IEnumerator items = 
-EvaluateRemainingForLetSingleItem (forLetClauses, singleBodies);
+EvaluateRemainingSingleItem (forLetClauses, singleBodies);
 						while (items.MoveNext ())
 							yield return (XPathItem) items.Current;
 						Context.PopVariable ();
 						Context.PopVariable ();
 					}
 					Context.ContextManager.PopCurrentSequence ();
-//					Context = Context.ContextManager.CurrentContext;
 					contextSequence = backup;
 				} else {
 					Context.PushVariable (sb.VarName, sb.Expression.Evaluate (contextSequence));
 					// recurse here (including following bindings)
-					IEnumerator items = EvaluateRemainingForLetSingleItem (forLetClauses, singleBodies);
+					IEnumerator items = EvaluateRemainingSingleItem (forLetClauses, singleBodies);
 					while (items.MoveNext ())
 						yield return (XPathItem) items.Current;
 					Context.PopVariable ();

+ 1 - 0
mcs/class/System.XML/System.Xml.Query/XQueryContext.cs

@@ -121,6 +121,7 @@ namespace Mono.Xml.XPath2
 		{
 			if (sequence == null)
 				throw new ArgumentNullException ();
+			sequence = sequence.Clone ();
 #if SEEMS_CONTEXT_FOR_CURRENT_REQURED
 			contextStack.Push (currentContext);
 			currentsequence = sequence;