diff --git a/mustache-sharp.test/FormatCompilerTester.cs b/mustache-sharp.test/FormatCompilerTester.cs
index 148ba2b..a05cb60 100644
--- a/mustache-sharp.test/FormatCompilerTester.cs
+++ b/mustache-sharp.test/FormatCompilerTester.cs
@@ -362,10 +362,34 @@ Content";
Assert.IsNotNull(context, "The context was not set.");
Assert.AreEqual(2, context.Length, "The context did not contain the right number of items.");
- Assert.AreEqual(String.Empty, context[0].Tag.Name, "The top-most context had the wrong tag type.");
- Assert.AreEqual("this", context[0].Argument, "The top-level argument should always be 'this'.");
- Assert.AreEqual("with", context[1].Tag.Name, "The inner context should have been a 'with' tag.");
- Assert.AreEqual("Address", context[1].Argument, "The inner context argument was wrong.");
+
+ Assert.AreEqual(String.Empty, context[0].TagName, "The top-most context had the wrong tag type.");
+ Assert.AreEqual("with", context[1].TagName, "The bottom context had the wrong tag type.");
+
+ Assert.AreEqual(0, context[0].Parameters.Length, "The top-most context had the wrong number of parameters.");
+ Assert.AreEqual(1, context[1].Parameters.Length, "The bottom context had the wrong number of parameters.");
+ Assert.AreEqual("Address", context[1].Parameters[0].Argument, "The bottom context had the wrong argument.");
+ }
+
+ ///
+ /// I was leaving behind context even after reaching a closing tag. We need to make sure
+ /// that context is like a call stack and that it is cleaned up after leaving the context.
+ ///
+ [TestMethod]
+ public void TestCompile_ExitContext_RemoveContext()
+ {
+ FormatCompiler compiler = new FormatCompiler();
+ Context[] context = null;
+ compiler.PlaceholderFound += (o, e) =>
+ {
+ context = e.Context;
+ };
+ compiler.Compile(@"{{#with Address}}{{/with}}{{FirstName}}");
+
+ Assert.IsNotNull(context, "The context was not set.");
+ Assert.AreEqual(1, context.Length, "The context did not contain the right number of items.");
+
+ Assert.AreEqual(String.Empty, context[0].TagName, "The top-most context had the wrong tag type.");
}
#endregion
diff --git a/mustache-sharp.test/Properties/AssemblyInfo.cs b/mustache-sharp.test/Properties/AssemblyInfo.cs
index 8a79168..ee7d29c 100644
--- a/mustache-sharp.test/Properties/AssemblyInfo.cs
+++ b/mustache-sharp.test/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("0.0.7.0")]
-[assembly: AssemblyFileVersion("0.0.7.0")]
+[assembly: AssemblyVersion("0.0.7.1")]
+[assembly: AssemblyFileVersion("0.0.7.1")]
diff --git a/mustache-sharp/CompoundGenerator.cs b/mustache-sharp/CompoundGenerator.cs
index c01add3..a6fb146 100644
--- a/mustache-sharp/CompoundGenerator.cs
+++ b/mustache-sharp/CompoundGenerator.cs
@@ -26,20 +26,6 @@ namespace mustache
_primaryGenerators = new LinkedList();
}
- ///
- /// Gets the argument that will act as the context for the content.
- ///
- /// The argument that will act as the context for the content.
- public string GetContextArgument()
- {
- TagParameter parameter = _definition.GetChildContextParameter();
- if (parameter == null)
- {
- return null;
- }
- return _arguments.GetKey(parameter);
- }
-
///
/// Adds the given generator.
///
diff --git a/mustache-sharp/ConditionTagDefinition.cs b/mustache-sharp/ConditionTagDefinition.cs
index 6e08a54..14e1d82 100644
--- a/mustache-sharp/ConditionTagDefinition.cs
+++ b/mustache-sharp/ConditionTagDefinition.cs
@@ -90,12 +90,12 @@ namespace mustache
}
///
- /// Gets the parameter that is used to create a new child context.
+ /// Gets the parameters that are used to create a new child context.
///
- /// The parameter that is used to create a new child context.
- public override TagParameter GetChildContextParameter()
+ /// The parameters that are used to create a new child context.
+ public override IEnumerable GetChildContextParameters()
{
- return null;
+ return new TagParameter[0];
}
}
}
diff --git a/mustache-sharp/Context.cs b/mustache-sharp/Context.cs
index b9d97b5..6e754b6 100644
--- a/mustache-sharp/Context.cs
+++ b/mustache-sharp/Context.cs
@@ -10,22 +10,22 @@ namespace mustache
///
/// Initializes a new instance of a Context.
///
- /// The definition of tag that created the context.
+ /// The name of the tag that created the context.
/// The argument used to create the context.
- internal Context(TagDefinition definition, string argument)
+ internal Context(string tagName, ContextParameter[] parameters)
{
- Tag = definition;
- Argument = argument;
+ TagName = tagName;
+ Parameters = parameters;
}
///
/// Gets the tag that created the context.
///
- public TagDefinition Tag { get; private set; }
+ public string TagName { get; private set; }
///
/// Gets the argument used to create the context.
///
- public string Argument { get; private set; }
+ public ContextParameter[] Parameters { get; private set; }
}
}
diff --git a/mustache-sharp/ContextParameter.cs b/mustache-sharp/ContextParameter.cs
new file mode 100644
index 0000000..2cc19b3
--- /dev/null
+++ b/mustache-sharp/ContextParameter.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace mustache
+{
+ ///
+ /// Holds information describing a parameter that creates a new context.
+ ///
+ public sealed class ContextParameter
+ {
+ ///
+ /// Initializes a new instance of a ContextParameter.
+ ///
+ /// The parameter that is used to create a new context.
+ /// The key whose corresponding value will be used to create the context.
+ internal ContextParameter(string parameter, string argument)
+ {
+ Parameter = parameter;
+ Argument = argument;
+ }
+
+ ///
+ /// Gets the parameter that is used to create a new context.
+ ///
+ public string Parameter { get; private set; }
+
+ ///
+ /// Gets the key whose corresponding value will be used to create the context.
+ ///
+ public string Argument { get; private set; }
+ }
+}
diff --git a/mustache-sharp/EachTagDefinition.cs b/mustache-sharp/EachTagDefinition.cs
index 05c512d..3d798d7 100644
--- a/mustache-sharp/EachTagDefinition.cs
+++ b/mustache-sharp/EachTagDefinition.cs
@@ -70,12 +70,12 @@ namespace mustache
}
///
- /// Gets the parameter that is used to create a new child context.
+ /// Gets the parameters that are used to create a new child context.
///
- /// The parameter that is used to create a new child context.
- public override TagParameter GetChildContextParameter()
+ /// The parameters that are used to create a new child context.
+ public override IEnumerable GetChildContextParameters()
{
- return collection;
+ return new TagParameter[] { collection };
}
}
}
diff --git a/mustache-sharp/ElseTagDefinition.cs b/mustache-sharp/ElseTagDefinition.cs
index 35a0868..08f5aff 100644
--- a/mustache-sharp/ElseTagDefinition.cs
+++ b/mustache-sharp/ElseTagDefinition.cs
@@ -33,12 +33,12 @@ namespace mustache
}
///
- /// Gets the parameter that is used to create a new child context.
+ /// Gets the parameters that are used to create a new child context.
///
- /// The parameter that is used to create a new child context.
- public override TagParameter GetChildContextParameter()
+ /// The parameters that are used to create a new child context.
+ public override IEnumerable GetChildContextParameters()
{
- return null;
+ return new TagParameter[0];
}
}
}
diff --git a/mustache-sharp/FormatCompiler.cs b/mustache-sharp/FormatCompiler.cs
index 4910c00..bf99be4 100644
--- a/mustache-sharp/FormatCompiler.cs
+++ b/mustache-sharp/FormatCompiler.cs
@@ -74,7 +74,7 @@ namespace mustache
}
CompoundGenerator generator = new CompoundGenerator(_masterDefinition, new ArgumentCollection());
Trimmer trimmer = new Trimmer();
- List context = new List() { new Context(_masterDefinition, "this") };
+ List context = new List() { new Context(_masterDefinition.Name, new ContextParameter[0]) };
int formatIndex = buildCompoundGenerator(_masterDefinition, context, generator, trimmer, format, 0);
string trailing = format.Substring(formatIndex);
generator.AddStaticGenerators(trimmer.RecordText(trailing, false, false));
@@ -218,13 +218,19 @@ namespace mustache
generator.AddStaticGenerators(trimmer.RecordText(leading, true, false));
ArgumentCollection arguments = getArguments(nextDefinition, match);
CompoundGenerator compoundGenerator = new CompoundGenerator(nextDefinition, arguments);
- string newContext = compoundGenerator.GetContextArgument();
- if (newContext != null)
+ IEnumerable contextParameters = nextDefinition.GetChildContextParameters();
+ bool hasContext = contextParameters.Any();
+ if (hasContext)
{
- context.Add(new Context(nextDefinition, newContext));
+ ContextParameter[] parameters = contextParameters.Select(p => new ContextParameter(p.Name, arguments.GetKey(p))).ToArray();
+ context.Add(new Context(nextDefinition.Name, parameters));
}
formatIndex = buildCompoundGenerator(nextDefinition, context, compoundGenerator, trimmer, format, formatIndex);
generator.AddGenerator(nextDefinition, compoundGenerator);
+ if (hasContext)
+ {
+ context.RemoveAt(context.Count - 1);
+ }
}
else
{
diff --git a/mustache-sharp/InlineTagDefinition.cs b/mustache-sharp/InlineTagDefinition.cs
index 264e35e..b658b51 100644
--- a/mustache-sharp/InlineTagDefinition.cs
+++ b/mustache-sharp/InlineTagDefinition.cs
@@ -38,12 +38,12 @@ namespace mustache
}
///
- /// Gets the parameter that is used to create a child context.
+ /// Gets the parameters that are used to create a child context.
///
- /// The parameter that is used to create a child context.
- public override TagParameter GetChildContextParameter()
+ /// The parameters that are used to create a child context.
+ public override IEnumerable GetChildContextParameters()
{
- return null;
+ return new TagParameter[0];
}
}
}
diff --git a/mustache-sharp/MasterTagDefinition.cs b/mustache-sharp/MasterTagDefinition.cs
index e55146e..b733def 100644
--- a/mustache-sharp/MasterTagDefinition.cs
+++ b/mustache-sharp/MasterTagDefinition.cs
@@ -34,12 +34,12 @@ namespace mustache
}
///
- /// Gets the parameter that is used to create a new child context.
+ /// Gets the parameters that are used to create a new child context.
///
- /// The parameter that is used to create a new child context.
- public override TagParameter GetChildContextParameter()
+ /// The parameters that are used to create a new child context.
+ public override IEnumerable GetChildContextParameters()
{
- return null;
+ return new TagParameter[0];
}
}
}
diff --git a/mustache-sharp/Properties/AssemblyInfo.cs b/mustache-sharp/Properties/AssemblyInfo.cs
index 1103a73..c2029f3 100644
--- a/mustache-sharp/Properties/AssemblyInfo.cs
+++ b/mustache-sharp/Properties/AssemblyInfo.cs
@@ -34,6 +34,6 @@ using System.Runtime.CompilerServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.0.7.0")]
-[assembly: AssemblyFileVersion("0.0.7.0")]
+[assembly: AssemblyVersion("0.0.7.1")]
+[assembly: AssemblyFileVersion("0.0.7.1")]
[assembly: InternalsVisibleTo("mustache-sharp.test")]
\ No newline at end of file
diff --git a/mustache-sharp/TagDefinition.cs b/mustache-sharp/TagDefinition.cs
index 89f56a0..45fe938 100644
--- a/mustache-sharp/TagDefinition.cs
+++ b/mustache-sharp/TagDefinition.cs
@@ -133,7 +133,7 @@ namespace mustache
/// Gets the parameter that will be used to create a new child scope.
///
/// The parameter that will be used to create a new child scope -or- null if no new scope is created.
- public abstract TagParameter GetChildContextParameter();
+ public abstract IEnumerable GetChildContextParameters();
///
/// Gets the context to use when building the inner text of the tag.
diff --git a/mustache-sharp/WithGenerator.cs b/mustache-sharp/WithGenerator.cs
index 6525f57..c36131a 100644
--- a/mustache-sharp/WithGenerator.cs
+++ b/mustache-sharp/WithGenerator.cs
@@ -38,12 +38,12 @@ namespace mustache
}
///
- /// Gets the parameter that is used to create a new child context.
+ /// Gets the parameters that are used to create a new child context.
///
- /// The parameter that is used to create a new child context.
- public override TagParameter GetChildContextParameter()
+ /// The parameters that are used to create a new child context.
+ public override IEnumerable GetChildContextParameters()
{
- return context;
+ return new TagParameter[] { context };
}
///
diff --git a/mustache-sharp/mustache-sharp.csproj b/mustache-sharp/mustache-sharp.csproj
index fefc132..3dee76a 100644
--- a/mustache-sharp/mustache-sharp.csproj
+++ b/mustache-sharp/mustache-sharp.csproj
@@ -39,6 +39,7 @@
+