Browse Source

2009-02-25 Marek Habersack <[email protected]>

	* AspTokenizer.cs: put_back now uses a stack and allows more than
	one invocation when called inside a tag.

	* AspGenerator.cs: when a nested parser is used, pay attention to
	server tags found inside client tags and add them to the control
	tree.

svn path=/trunk/mcs/; revision=127935
Marek Habersack 17 years ago
parent
commit
39ea4c8b32

+ 32 - 13
mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs

@@ -667,7 +667,7 @@ namespace System.Web.Compilation
 				if (this.text.Length > 0)
 					FlushText (true);
 				CodeRenderParser r = new CodeRenderParser (text, stack.Builder);
-				r.AddChildren ();
+				r.AddChildren (this);
 				return;
 			}
 			
@@ -1020,22 +1020,24 @@ namespace System.Web.Compilation
 		{
 			string str;
 			ControlBuilder builder;
-
+			AspGenerator generator;
+			
 			public CodeRenderParser (string str, ControlBuilder builder)
 			{
 				this.str = str;
 				this.builder = builder;
 			}
 
-			public void AddChildren ()
+			public void AddChildren (AspGenerator generator)
 			{
+				this.generator = generator;
 				int index = str.IndexOf ("<%");
 				if (index > 0) {
 					TextParsed (null, str.Substring (0, index));
 					str = str.Substring (index);
 				}
-
-				AspParser parser = new AspParser ("@@inner_string@@", new StringReader (str));
+				
+				AspParser parser = new AspParser ("@@nested_tag@@", new StringReader (str));
 				parser.Error += new ParseErrorHandler (ParseError);
 				parser.TagParsed += new TagParsedHandler (TagParsed);
 				parser.TextParsed += new TextParsedHandler (TextParsed);
@@ -1044,14 +1046,31 @@ namespace System.Web.Compilation
 
 			void TagParsed (ILocation location, TagType tagtype, string tagid, TagAttributes attributes)
 			{
-				if (tagtype == TagType.CodeRender)
-					builder.AppendSubBuilder (new CodeRenderBuilder (tagid, false, location));
-				else if (tagtype == TagType.CodeRenderExpression)
-					builder.AppendSubBuilder (new CodeRenderBuilder (tagid, true, location));
-				else if (tagtype == TagType.DataBinding)
-					builder.AppendSubBuilder (new DataBindingBuilder (tagid, location));
-				else
-					builder.AppendLiteralString (location.PlainText);
+				switch (tagtype) {
+					case TagType.CodeRender:
+						builder.AppendSubBuilder (new CodeRenderBuilder (tagid, false, location));
+						break;
+						
+					case TagType.CodeRenderExpression:
+						builder.AppendSubBuilder (new CodeRenderBuilder (tagid, true, location));
+						break;
+						
+					case TagType.DataBinding:
+						builder.AppendSubBuilder (new DataBindingBuilder (tagid, location));
+						break;
+
+					case TagType.Tag:
+					case TagType.SelfClosing:
+						if (generator != null)
+							generator.TagParsed (location, tagtype, tagid, attributes);
+						else
+							goto default;
+						break;
+						
+					default:
+						builder.AppendLiteralString (location.PlainText);
+						break;
+				}
 			}
 
 			void TextParsed (ILocation location, string text)

+ 30 - 5
mcs/class/System.Web/System.Web.Compilation/AspTokenizer.cs

@@ -48,6 +48,20 @@ namespace System.Web.Compilation
 
 	class AspTokenizer
 	{
+		class PutBackItem
+		{
+			public readonly string Value;
+			public readonly int Position;
+			public readonly int CurrentToken;
+			
+			public PutBackItem (string value, int position, int currentToken)
+			{
+				Value = value;
+				Position = position;
+				CurrentToken = currentToken;
+			}
+		}
+		
 		static char [] lfcr = new char [] { '\n', '\r' };
 		TextReader sr;
 		int current_token;
@@ -64,6 +78,7 @@ namespace System.Web.Compilation
 		bool have_unget;
 		int unget_value;
 		string val;
+		Stack putBackBuffer;
 		
 		public AspTokenizer (TextReader reader)
 		{
@@ -82,18 +97,28 @@ namespace System.Web.Compilation
 
 		public void put_back ()
 		{
-			if (hasPutBack)
+			if (hasPutBack && !inTag)
 				throw new HttpException ("put_back called twice!");
 			
 			hasPutBack = true;
-			position -= Value.Length;
+			if (putBackBuffer == null)
+				putBackBuffer = new Stack ();
+
+			string val = Value;
+			putBackBuffer.Push (new PutBackItem (val, position, current_token));
+			position -= val.Length;
 		}
 		
 		public int get_token ()
 		{
-			if (hasPutBack){
-				hasPutBack = false;
-				position += Value.Length;
+			if (hasPutBack) {
+				PutBackItem pbi = putBackBuffer.Pop () as PutBackItem;
+				hasPutBack = putBackBuffer.Count > 0;
+				position = pbi.Position;
+				have_value = false;
+				val = null;
+				sb = new StringBuilder (pbi.Value);
+				current_token = pbi.CurrentToken;
 				return current_token;
 			}
 

+ 9 - 0
mcs/class/System.Web/System.Web.Compilation/ChangeLog

@@ -1,3 +1,12 @@
+2009-02-25  Marek Habersack  <[email protected]>
+
+	* AspTokenizer.cs: put_back now uses a stack and allows more than
+	one invocation when called inside a tag.
+
+	* AspGenerator.cs: when a nested parser is used, pay attention to
+	server tags found inside client tags and add them to the control
+	tree.
+
 2009-02-24  Marek Habersack  <[email protected]>
 
 	* BuildManager.cs: Path.Combine must not be passed null first