Changeset 221
- Timestamp:
- 10/23/08 06:58:08 (3 months ago)
- Files:
-
- branches/codedom/src/Spark.Tests/CodeDomViewCompilerTester.cs (modified) (6 diffs)
- branches/codedom/src/Spark.Tests/Compiler/VariableTrackerTester.cs (added)
- branches/codedom/src/Spark.Tests/Spark.Tests.csproj (modified) (1 diff)
- branches/codedom/src/Spark/Compiler/BatchCompiler.cs (modified) (2 diffs)
- branches/codedom/src/Spark/Compiler/CSharp/ChunkVisitors/GeneratedCodeVisitor.cs (modified) (27 diffs)
- branches/codedom/src/Spark/Compiler/CSharp/ChunkVisitors/VariableTracker.cs (added)
- branches/codedom/src/Spark/Compiler/CodeDom/ChunkVisitors/CodeDomUtility.cs (modified) (1 diff)
- branches/codedom/src/Spark/Compiler/CodeDom/ChunkVisitors/GeneratedCodeVisitor.cs (modified) (7 diffs)
- branches/codedom/src/Spark/Compiler/CodeDom/ChunkVisitors/GlobalMembersVisitor.cs (modified) (4 diffs)
- branches/codedom/src/Spark/Compiler/CodeDom/CodeDomViewCompiler.cs (modified) (6 diffs)
- branches/codedom/src/Spark/Compiler/CodeDom/CsCodeDomViewCompiler.cs (added)
- branches/codedom/src/Spark/Compiler/CodeDom/VbCodeDomViewCompiler.cs (added)
- branches/codedom/src/Spark/Spark.csproj (modified) (1 diff)
- branches/codedom/src/Spark/SparkViewEngine.cs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/codedom/src/Spark.Tests/CodeDomViewCompilerTester.cs
r220 r221 8 8 using Spark.Compiler.CodeDom; 9 9 using Spark.Parser; 10 using Spark.Tests.Stubs; 10 11 11 12 namespace Spark.Tests … … 19 20 public void Init() 20 21 { 21 _compiler = new CodeDomViewCompiler("vb") { BaseClass = typeof(Stubs.StubSparkView).FullName, Debug = true };22 _compiler = new VbCodeDomViewCompiler { BaseClass = typeof(Stubs.StubSparkView).FullName, Debug = false }; 22 23 } 23 24 … … 27 28 } 28 29 29 private StringWriter ExecuteView() 30 { 31 var view = (ISparkView)Activator.CreateInstance(_compiler.CompiledType); 30 private string ExecuteView() 31 { 32 return ExecuteView(new StubViewData()); 33 } 34 35 private string ExecuteView(StubViewData viewData) 36 { 37 var view = (Stubs.StubSparkView)Activator.CreateInstance(_compiler.CompiledType); 38 view.ViewData = viewData; 32 39 var contents = new StringWriter(); 33 40 view.RenderView(contents); 34 return contents ;41 return contents.ToString(); 35 42 } 36 43 … … 123 130 _compiler.CompileView(chunks, chunks); 124 131 var contents = ExecuteView(); 125 Assert.AreEqual("Hello World", contents .ToString());132 Assert.AreEqual("Hello World", contents); 126 133 } 127 134 … … 135 142 } 136 143 144 137 145 [Test] 138 146 public void SettingLocalVariable() 139 147 { 140 148 var chunks = Chunks( 141 new LocalVariableChunk { Type = "object",Name = "x", Value = "4" },149 new LocalVariableChunk { Name = "x", Value = "4" }, 142 150 new SendExpressionChunk { Code = "x" }, 143 151 new AssignVariableChunk { Name = "x", Value = "2" }, … … 145 153 _compiler.CompileView(chunks, chunks); 146 154 var contents = ExecuteView(); 147 Assert.AreEqual("42", contents.ToString()); 148 } 149 155 Assert.AreEqual("42", contents); 156 } 157 158 159 [Test] 160 public void SettingGlobalVariable() 161 { 162 var chunks = Chunks( 163 new GlobalVariableChunk { Type = "int", Name = "x", Value = "4" }, 164 new SendExpressionChunk { Code = "x" }, 165 new AssignVariableChunk { Name = "x", Value = "2" }, 166 new SendExpressionChunk { Code = "x" }); 167 _compiler.CompileView(chunks, chunks); 168 var contents = ExecuteView(); 169 Assert.AreEqual("42", contents); 170 } 171 172 [Test] 173 public void UsingViewData() 174 { 175 var chunks = Chunks( 176 new ViewDataChunk { Type = "int", Name = "HelloNumber", Key = "hello" }, 177 new SendExpressionChunk { Code = "HelloNumber" }); 178 _compiler.CompileView(chunks, chunks); 179 var contents = ExecuteView(new StubViewData { { "hello", 42 } }); 180 Assert.AreEqual("42", contents); 181 } 182 183 [Test] 184 public void UsingViewDataDefault() 185 { 186 var chunks = Chunks( 187 new ViewDataChunk { Type = "int", Name = "HelloNumber", Key = "hello", Default = "55" }, 188 new SendExpressionChunk { Code = "HelloNumber" }); 189 190 _compiler.CompileView(chunks, chunks); 191 192 var contents = ExecuteView(new StubViewData { { "hello", 42 } }); 193 Assert.AreEqual("42", contents); 194 195 var contents2 = ExecuteView(); 196 Assert.AreEqual("55", contents2); 197 } 198 199 [Test] 200 public void InlineCodeStatements() 201 { 202 //TODO: null protection. silent nulls. 203 204 var chunks = Chunks( 205 new CodeStatementChunk { Code = "Dim x As Object" }, 206 new CodeStatementChunk { Code = "x = 20" }, 207 new SendExpressionChunk { Code = "x + 22" }); 208 _compiler.CompileView(chunks, chunks); 209 var contents = ExecuteView(); 210 Assert.AreEqual(contents, "42"); 211 } 212 213 [Test] 214 public void ScopeTest() 215 { 216 var scope1 = new ScopeChunk(); 217 scope1.Body.Add(new LocalVariableChunk { Name = "x", Value = "4" }); 218 scope1.Body.Add(new SendExpressionChunk { Code = "x" }); 219 var scope2 = new ScopeChunk(); 220 scope2.Body.Add(new LocalVariableChunk { Name = "x", Value = "2" }); 221 scope2.Body.Add(new SendExpressionChunk { Code = "x" }); 222 223 var chunks = Chunks(scope1, scope2); 224 _compiler.CompileView(chunks, chunks); 225 var contents = ExecuteView(); 226 Assert.AreEqual(contents, "42"); 227 } 228 229 [Test] 230 public void ForEachLoopOverArray() 231 { 232 var loop = new ForEachChunk { Code = "system.int32 number in numbers" }; 233 loop.Body.Add(new SendExpressionChunk { Code = "number" }); 234 235 var chunks = Chunks( 236 new ViewDataChunk { Name = "numbers", Type = "Integer()" }, 237 loop); 238 _compiler.CompileView(chunks, chunks); 239 var contents = ExecuteView(new StubViewData { { "numbers", new[] { 1, 2, 3, 4, 5 } } }); 240 Assert.AreEqual("12345", contents); 241 } 150 242 } 151 243 } branches/codedom/src/Spark.Tests/Spark.Tests.csproj
r218 r221 58 58 <Compile Include="Compiler\ExpressionBuilderTester.cs" /> 59 59 <Compile Include="Compiler\ForEachInspectorTester.cs" /> 60 <Compile Include="Compiler\VariableTrackerTester.cs" /> 60 61 <Compile Include="DefaultResourcePathManagerTester.cs" /> 61 62 <Compile Include="FileSystem\CombinedViewFolderTester.cs" /> branches/codedom/src/Spark/Compiler/BatchCompiler.cs
r218 r221 52 52 continue; 53 53 } 54 compilerParameters.ReferencedAssemblies.Add(location); 54 if (!string.IsNullOrEmpty(location)) 55 compilerParameters.ReferencedAssemblies.Add(location); 55 56 } 56 57 … … 121 122 using (var reader = new StringReader(sourceCodeItem)) 122 123 { 123 for (int lineNumber = 1; ; ++lineNumber)124 for (int lineNumber = 1; ; ++lineNumber) 124 125 { 125 126 var line = reader.ReadLine(); branches/codedom/src/Spark/Compiler/CSharp/ChunkVisitors/GeneratedCodeVisitor.cs
r208 r221 13 13 // limitations under the License. 14 14 // 15 using System.Collections;16 15 using System.Collections.Generic; 17 using System.IO;18 16 using System.Linq; 19 17 using System.Text; … … 25 23 { 26 24 private readonly StringBuilder _source; 25 private readonly VariableTracker _variables; 27 26 28 27 public GeneratedCodeVisitor(StringBuilder output, Dictionary<string, object> globalSymbols) 29 28 { 30 29 _source = output; 31 32 _scope = new Scope(new Scope(null) {Variables = globalSymbols}); 30 _variables = new VariableTracker(globalSymbols); 33 31 } 34 32 … … 59 57 60 58 61 class Scope62 {63 public Scope(Scope prior)64 {65 Variables = new Dictionary<string, object>();66 Prior = prior;67 }68 public Dictionary<string,object> Variables { get; set; }69 public Scope Prior { get; set; }70 }71 72 private Scope _scope;73 74 void PushScope()75 {76 _scope = new Scope(_scope);77 }78 void PopScope()79 {80 _scope = _scope.Prior;81 }82 void DeclareVariable(string name)83 {84 _scope.Variables.Add(name, null);85 }86 bool IsVariableDeclared(string name)87 {88 var scan = _scope;89 while(scan != null)90 {91 if (scan.Variables.ContainsKey(name))92 return true;93 scan = scan.Prior;94 }95 return false;96 }97 59 98 60 … … 143 105 protected override void Visit(LocalVariableChunk chunk) 144 106 { 145 DeclareVariable(chunk.Name);107 _variables.Declare(chunk.Name); 146 108 147 109 CodeIndent(chunk).Append(chunk.Type).Append(' ').Append(chunk.Name); … … 156 118 protected override void Visit(DefaultVariableChunk chunk) 157 119 { 158 if ( IsVariableDeclared(chunk.Name))120 if (_variables.IsDeclared(chunk.Name)) 159 121 return; 160 122 161 DeclareVariable(chunk.Name);123 _variables.Declare(chunk.Name); 162 124 CodeIndent(chunk).Append(chunk.Type).Append(' ').Append(chunk.Name); 163 125 if (!string.IsNullOrEmpty(chunk.Value)) … … 179 141 CodeIndent(chunk).AppendLine(string.Format("foreach({0})", chunk.Code)); 180 142 CodeDefault(); 181 PushScope();143 _variables.PushScope(); 182 144 AppendIndent().AppendLine("{"); 183 145 Indent += 4; … … 185 147 Indent -= 4; 186 148 AppendIndent().AppendLine(string.Format("}} //foreach {0}", chunk.Code.Replace("\r", "").Replace("\n", " "))); 187 PopScope();149 _variables.PopScope(); 188 150 } 189 151 else … … 202 164 } 203 165 204 PushScope();166 _variables.PushScope(); 205 167 AppendIndent().AppendLine("{"); 206 168 if (autoIndex.Detected) 207 169 { 208 DeclareVariable(variableName + "Index");170 _variables.Declare(variableName + "Index"); 209 171 _source.Append(' ', Indent + 4).AppendFormat("int {0}Index = 0;\r\n", variableName); 210 172 } 211 173 if (autoIsFirst.Detected) 212 174 { 213 DeclareVariable(variableName + "IsFirst");175 _variables.Declare(variableName + "IsFirst"); 214 176 _source.Append(' ', Indent + 4).AppendFormat("bool {0}IsFirst = true;\r\n", variableName); 215 177 } 216 178 if (autoCount.Detected) 217 179 { 218 DeclareVariable(variableName + "Count");180 _variables.Declare(variableName + "Count"); 219 181 string collectionCode = string.Join(" ", terms.ToArray(), inIndex + 1, terms.Count - inIndex - 1); 220 182 _source.Append(' ', Indent + 4).AppendFormat("int {0}Count = global::Spark.Compiler.CollectionUtility.Count({1});\r\n", variableName, collectionCode); … … 225 187 CodeDefault(); 226 188 227 PushScope();228 DeclareVariable(variableName);189 _variables.PushScope(); 190 _variables.Declare(variableName); 229 191 _source.Append(' ', Indent).AppendLine("{"); 230 192 … … 232 194 if (autoIsLast.Detected) 233 195 { 234 DeclareVariable(variableName + "IsLast");196 _variables.Declare(variableName + "IsLast"); 235 197 _source.Append(' ', Indent + 4).AppendFormat("bool {0}IsLast = ({0}Index == {0}Count - 1);\r\n", 236 198 variableName); … … 250 212 251 213 _source.Append(' ').AppendLine("}"); 252 PopScope();214 _variables.PopScope(); 253 215 254 216 AppendIndent().AppendFormat("}} //foreach {0}\r\n", chunk.Code.Replace("\r", "").Replace("\n", " ")); 255 PopScope();217 _variables.PopScope(); 256 218 } 257 219 } … … 259 221 protected override void Visit(ScopeChunk chunk) 260 222 { 261 PushScope();223 _variables.PushScope(); 262 224 CodeIndent(chunk).AppendLine("{"); 263 225 CodeDefault(); … … 266 228 Indent -= 4; 267 229 AppendIndent().AppendLine("}"); 268 PopScope();230 _variables.PopScope(); 269 231 } 270 232 … … 283 245 { 284 246 CodeIndent(chunk).AppendLine(string.Format("using(OutputScope(\"{0}\"))", chunk.Name)); 285 PushScope();247 _variables.PushScope(); 286 248 AppendIndent().AppendLine("{"); 287 249 Indent += 4; … … 289 251 Indent -= 4; 290 252 AppendIndent().AppendLine("}"); 291 PopScope();253 _variables.PopScope(); 292 254 } 293 255 294 256 protected override void Visit(UseImportChunk chunk) 295 257 { 296 258 297 259 } 298 260 … … 302 264 CodeDefault(); 303 265 304 PushScope();266 _variables.PushScope(); 305 267 AppendIndent().AppendLine("{"); 306 268 Indent += 4; … … 325 287 Indent -= 4; 326 288 AppendIndent().AppendLine("}"); 327 PopScope();289 _variables.PopScope(); 328 290 329 291 CodeDefault(); … … 334 296 CodeIndent(chunk).AppendLine(string.Format("if (Content.ContainsKey(\"{0}\"))", chunk.Name)); 335 297 CodeHidden(); 336 PushScope();298 _variables.PushScope(); 337 299 AppendIndent().AppendLine("{"); 338 300 _source.Append(' ', Indent + 4).AppendLine(string.Format("global::Spark.Spool.TextWriterExtensions.WriteTo(Content[\"{0}\"], Output);", chunk.Name)); 339 301 AppendIndent().AppendLine("}"); 340 PopScope();302 _variables.PopScope(); 341 303 342 304 if (chunk.Default.Count != 0) 343 305 { 344 306 AppendIndent().AppendLine("else"); 345 PushScope();307 _variables.PushScope(); 346 308 AppendIndent().AppendLine("{"); 347 309 Indent += 4; … … 349 311 Indent -= 4; 350 312 AppendIndent().AppendLine("}"); 351 PopScope();313 _variables.PopScope(); 352 314 } 353 315 CodeDefault(); … … 408 370 CodeIndent(chunk).AppendLine(string.Format("if ({0})", chunk.Condition)); 409 371 CodeDefault(); 410 PushScope();372 _variables.PushScope(); 411 373 AppendIndent().AppendLine("{"); 412 374 Indent += 4; … … 415 377 AppendIndent().AppendLine(string.Format("}} // if ({0})", 416 378 chunk.Condition.Replace("\r", "").Replace("\n", " "))); 417 PopScope();379 _variables.PopScope(); 418 380 } 419 381 break; … … 422 384 CodeIndent(chunk).AppendLine(string.Format("else if ({0})", chunk.Condition)); 423 385 CodeDefault(); 424 PushScope();386 _variables.PushScope(); 425 387 AppendIndent().AppendLine("{"); 426 388 Indent += 4; … … 429 391 AppendIndent().AppendLine(string.Format("}} // else if ({0})", 430 392 chunk.Condition.Replace("\r", "").Replace("\n", " "))); 431 PopScope();393 _variables.PopScope(); 432 394 } 433 395 break; … … 435 397 { 436 398 AppendIndent().AppendLine("else"); 437 PushScope();399 _variables.PushScope(); 438 400 CodeIndent(chunk).AppendLine("{"); 439 401 CodeDefault(); … … 442 404 Indent -= 4; 443 405 AppendIndent().AppendLine("}"); 444 PopScope();406 _variables.PopScope(); 445 407 } 446 408 break; … … 448 410 { 449 411 CodeIndent(chunk).Append("if (Once(").Append(chunk.Condition).AppendLine("))"); 450 PushScope();412 _variables.PushScope(); 451 413 AppendIndent().AppendLine("{"); 452 414 CodeDefault(); … … 455 417 Indent -= 4; 456 418 AppendIndent().AppendLine("}"); 457 PopScope();419 _variables.PopScope(); 458 420 } 459 421 break; branches/codedom/src/Spark/Compiler/CodeDom/ChunkVisitors/CodeDomUtility.cs
r220 r221 32 32 public static CodeTypeReference TypeReference(string type) 33 33 { 34 if (type == null) 35 return null; 36 34 37 if (_primativeTypes.ContainsKey(type)) 35 38 return _primativeTypes[type]; 39 36 40 return new CodeTypeReference(type); 37 41 } branches/codedom/src/Spark/Compiler/CodeDom/ChunkVisitors/GeneratedCodeVisitor.cs
r220 r221 1 1 using System; 2 2 using System.CodeDom; 3 using System.CodeDom.Compiler; 3 4 using System.Collections.Generic; 5 using System.IO; 4 6 using System.Linq; 5 7 using System.Text; 6 8 using Spark.Compiler.ChunkVisitors; 9 using Spark.Compiler.CSharp.ChunkVisitors; 7 10 using Spark.Spool; 8 11 … … 11 14 public class GeneratedCodeVisitor : ChunkVisitor 12 15 { 16 private readonly CodeDomViewCompiler _viewCompiler; 13 17 private CodeStatementCollection _statements; 14 15 public GeneratedCodeVisitor() 16 { 18 private VariableTracker _variables; 19 20 public GeneratedCodeVisitor(CodeDomViewCompiler viewCompiler, Dictionary<string, object> globalSymbols) 21 { 22 _viewCompiler = viewCompiler; 17 23 _statements = new CodeStatementCollection(); 24 _variables = new VariableTracker(globalSymbols); 18 25 } 19 26 … … 46 53 } 47 54 55 protected override void Visit(CodeStatementChunk chunk) 56 { 57 Statements.Add(new CodeSnippetStatement(chunk.Code)); 58 } 59 48 60 protected override void Visit(AssignVariableChunk chunk) 49 61 { … … 56 68 protected override void Visit(LocalVariableChunk chunk) 57 69 { 58 //DeclareVariable(chunk.Name); 59 60 //CodeIndent(chunk).Append(chunk.Type).Append(' ').Append(chunk.Name); 61 //if (!string.IsNullOrEmpty(chunk.Value)) 62 //{ 63 // _source.Append(" = ").Append(chunk.Value); 64 //} 65 //_source.AppendLine(";"); 66 //CodeDefault(); 67 68 var declarationStatement = new CodeVariableDeclarationStatement(CodeDomUtility.TypeReference(chunk.Type), chunk.Name); 69 if (!string.IsNullOrEmpty(chunk.Value)) 70 { 71 declarationStatement.InitExpression = new CodeSnippetExpression(chunk.Value); 72 } 73 Statements.Add(declarationStatement); 70 _variables.Declare(chunk.Name); 71 72 if (chunk.Type == "var") 73 { 74 // not normally supported 75 Statements.Add(_viewCompiler.LanguageSpecific_ImplicitLocalVariable(chunk.Name, chunk.Value)); 76 } 77 else 78 { 79 // type name = value; 80 81 var declarationStatement = new CodeVariableDeclarationStatement(CodeDomUtility.TypeReference(chunk.Type), chunk.Name); 82 if (!string.IsNullOrEmpty(chunk.Value)) 83 { 84 declarationStatement.InitExpression = new CodeSnippetExpression(chunk.Value); 85 } 86 Statements.Add(declarationStatement); 87 } 74 88 } 75 89 … … 83 97 try 84 98 { 99 // if (Content.ContainsKey(name)) 100 // TextWriterExtensions.WriteTo(Content[name], Output); 101 // else 102 // default 103 85 104 var containsKey = new CodeMethodInvokeExpression( 86 105 new CodePropertyReferenceExpression( … … 92 111 var writeTo = new CodeExpressionStatement( 93 112 new CodeMethodInvokeExpression( 94 new CodeTypeReferenceExpression(typeof (TextWriterExtensions)),113 new CodeTypeReferenceExpression(typeof(TextWriterExtensions)), 95 114 "WriteTo", 96 115 new CodeArrayIndexerExpression( … … 117 136 _statements = back; 118 137 } 119 120 //if (chunk.Default.Count != 0) 121 //{ 122 // AppendIndent().AppendLine("else"); 123 // PushScope(); 124 // AppendIndent().AppendLine("{"); 125 // Indent += 4; 126 // Accept(chunk.Default); 127 // Indent -= 4; 128 // AppendIndent().AppendLine("}"); 129 // PopScope(); 130 //} 131 //CodeDefault(); 132 //base.Visit(chunk); 138 } 139 140 protected override void Visit(ScopeChunk chunk) 141 { 142 var prior = _statements; 143 try 144 { 145 // using an if(true) because codedom doesn't have 146 // a universal block-with-nothing-in-it concept. 147 148 var block = new CodeConditionStatement(new CodePrimitiveExpression(true)); 149 _statements.Add(block); 150 _statements = block.TrueStatements; 151 152 _variables.PushScope(); 153 Accept(chunk.Body); 154 _variables.PopScope(); 155 } 156 finally 157 { 158 _statements = prior; 159 } 160 } 161 162 protected override void Visit(ForEachChunk chunk) 163 { 164 var terms = chunk.Code.Split(' ', '\r', '\n', '\t').ToList(); 165 var inIndex = terms.IndexOf("in"); 166 string variableName = (inIndex < 2 ? null : terms[inIndex - 1]); 167 168 if (variableName == null) 169 { 170 throw new CompilerException(string.Format("Unrecognized loop syntax: {0}", chunk.Code)); 171 } 172 173 var prior = _statements; 174 try 175 { 176 var detect = new DetectCodeExpressionVisitor(OuterPartial); 177 var autoIndex = detect.Add(variableName + "Index"); 178 var autoCount = detect.Add(variableName + "Count"); 179 var autoIsFirst = detect.Add(variableName + "IsFirst"); 180 var autoIsLast = detect.Add(variableName + "IsLast"); 181 detect.Accept(chunk.Body); 182 183 if (autoIsLast.Detected) 184 { 185 autoIndex.Detected = true; 186 autoCount.Detected = true; 187 } 188 189 string typeCode = string.Join(" ", terms.ToArray(), 0, inIndex - 1); 190 string collectionCode = string.Join(" ", terms.ToArray(), inIndex + 1, terms.Count - inIndex - 1); 191 192 _variables.PushScope(); 193 var scopeAutoVariables = new CodeConditionStatement(new CodePrimitiveExpression(true)); 194 _statements.Add(scopeAutoVariables); 195 _statements = scopeAutoVariables.TrueStatements; 196 197 if (autoIndex.Detected) 198 { 199 _variables.Declare(variableName + "Index"); 200 _statements.Add( 201 new CodeVariableDeclarationStatement( 202 typeof (int), 203 variableName + "Index", 204 new CodePrimitiveExpression(0))); 205 } 206 if (autoIsFirst.Detected) 207 { 208 _variables.Declare(variableName + "IsFirst"); 209 _statements.Add( 210 new CodeVariableDeclarationStatement( 211 typeof(bool), 212 variableName + "IsFirst", 213 new CodePrimitiveExpression(true))); 214 } 215 if (autoCount.Detected) 216 { 217 //int {0}Count = global::Spark.Compiler.CollectionUtility.Count({1}); 218 _variables.Declare(variableName + "Count"); 219 _statements.Add( 220 new CodeVariableDeclarationStatement( 221 typeof(int), 222 variableName + "Count", 223 new CodeMethodInvokeExpression( 224 new CodeTypeReferenceExpression(typeof(CollectionUtility)), 225 "Count", 226 new CodeSnippetExpression(collectionCode)))); 227 } 228 229 _variables.PushScope(); 230 _variables.Declare(variableName); 231 _statements.Add(_viewCompiler.LanguageSpecific_ForEachBegin(typeCode , variableName, collectionCode)); 232 233 if (autoIsLast.Detected) 234 { 235 //bool {0}IsLast = ({0}Index == {0}Count - 1); 236 _variables.Declare(variableName + "IsLast"); 237 _statements.Add( 238 new CodeVariableDeclarationStatement( 239 typeof (bool), 240 variableName + "IsLast", 241 new CodeBinaryOperatorExpression( 242 new CodeVariableReferenceExpression(variableName + "Index"), 243 CodeBinaryOperatorType.ValueEquality, 244 new CodeBinaryOperatorExpression( 245 new CodeVariableReferenceExpression(variableName + "Count"), 246 CodeBinaryOperatorType.Subtract, 247 new CodePrimitiveExpression(1))))); 248 } 249 250 Accept(chunk.Body); 251 252 253 254 if (autoIndex.Detected) 255 { 256 //{0}Index={0}Index+1 257 _statements.Add( 258 new CodeAssignStatement( 259 new CodeVariableReferenceExpression(variableName + "Index"), 260 new CodeBinaryOperatorExpression( 261 new CodeVariableReferenceExpression(variableName + "Index"), 262 CodeBinaryOperatorType.Add, 263 new CodePrimitiveExpression(1)))); 264 } 265 266 if (autoIsFirst.Detected) 267 { 268 //{0}IsFirst = false 269 _statements.Add( 270 new CodeAssignStatement( 271 new CodeVariableReferenceExpression(variableName + "IsFirst"), 272 new CodePrimitiveExpression(false))); 273 } 274 275 276 _statements.Add(_viewCompiler.LanguageSpecific_ForEachEnd()); 277 _variables.PopScope(); 278 _variables.PopScope(); 279 } 280 finally 281 { 282 _statements = prior; 283 } 284 } 285 286 public RenderPartialChunk OuterPartial { get; set; } 287 protected override void Visit(RenderPartialChunk chunk) 288 { 289 var priorOuterPartial = OuterPartial; 290 OuterPartial = chunk; 291 Accept(chunk.FileContext.Contents); 292 OuterPartial = priorOuterPartial; 133 293 } 134 294 } branches/codedom/src/Spark/Compiler/CodeDom/ChunkVisitors/GlobalMembersVisitor.cs
r220 r221 24 24 public class GlobalMembersVisitor : ChunkVisitor 25 25 { 26 private readonly CodeDomViewCompiler _viewCompiler; 26 27 private readonly CodeTypeDeclaration _viewType; 27 28 private readonly Dictionary<string, object> _globalSymbols; … … 29 30 readonly Dictionary<string, GlobalVariableChunk> _globalAdded = new Dictionary<string, GlobalVariableChunk>(); 30 31 31 public GlobalMembersVisitor(CodeTypeDeclaration viewType, Dictionary<string, object> globalSymbols) 32 { 32 public GlobalMembersVisitor(CodeDomViewCompiler viewCompiler, CodeTypeDeclaration viewType, Dictionary<string, object> globalSymbols) 33 { 34 _viewCompiler = viewCompiler; 33 35 _viewType = viewType; 34 36 _globalSymbols = globalSymbols; … … 56 58 if (typeParts.Contains("const") || typeParts.Contains("readonly")) 57 59 { 58 //_source.AppendFormat("\r\n {0} {1} = {2};", 59 // type, chunk.Name, chunk.Value); 60 //type name = value; 60 61 _viewType.Members.Add(new CodeMemberField(CodeDomUtility.TypeReference(type), chunk.Name) { InitExpression = new CodeSnippetExpression(chunk.Value) }); 61 62 } 62 63 else 63 64 { 64 //_source.AppendFormat( 65 // "\r\n {0} _{1} = {2};\r\n public {0} {1} {{ get {{return _{1};}} set {{_{1} = value;}} }}", 66 // type, chunk.Name, chunk.Value); 65 //type _name = value; 66 //public type name {get {return _name;} set {_name = value;} } 67 67 _viewType.Members.Add(new CodeMemberField(CodeDomUtility.TypeReference(type), "_" + chunk.Name) { InitExpression = new CodeSnippetExpression(chunk.Value) }); 68 68 var memberProperty = new CodeMemberProperty … … 107 107 protected override void Visit(ViewDataChunk chunk) 108 108 { 109 //var key = chunk.Key; 110 //var name = chunk.Name; 111 //var type = chunk.Type ?? "object"; 112 113 //if (!_globalSymbols.ContainsKey(chunk.Name)) 114 // _globalSymbols.Add(chunk.Name, null); 115 116 //if (_viewDataAdded.ContainsKey(name)) 117 //{ 118 // if (_viewDataAdded[name] != key + ":" + type) 119 // { 120 // throw new CompilerException( 121 // string.Format("The view data named {0} cannot be declared with different types '{1}' and '{2}'", 122 // name, type, _viewDataAdded[name])); 123 // } 124 // return; 125 //} 126 127 //_viewDataAdded.Add(name, key + ":" + type); 128 //AppendIndent().Append(type).Append(" ").AppendLine(name); 129 //if (string.IsNullOrEmpty(chunk.Default)) 130 //{ 131 // CodeIndent(chunk) 132 // .Append("{get {return (") 133 // .Append(type) 134 // .Append(")ViewData.Eval(\"") 135 // .Append(key) 136 // .AppendLine("\");}}"); 137 //} 138 //else 139 //{ 140 // CodeIndent(chunk) 141 // .Append("{get {return (") 142 // .Append(type) 143 // .Append(")(ViewData.Eval(\"") 144 // .Append(key) 145 // .Append("\")??") 146 // .Append(chunk.Default) 147 // .AppendLine(");}}"); 148 //} 149 //CodeDefault(); 109 var key = chunk.Key ?? chunk.Name; 110 var name = chunk.Name; 111 var type = chunk.Type ?? "object"; 112 113 if (!_globalSymbols.ContainsKey(chunk.Name)) 114 _globalSymbols.Add(chunk.Name, null); 115 116 if (_viewDataAdded.ContainsKey(name)) 117 { 118 if (_viewDataAdded[name] != key + ":" + type) 119 { 120 throw new CompilerException( 121 string.Format("The view data named {0} cannot be declared with different types '{1}' and '{2}'", 122 name, type, _viewDataAdded[name])); 123 } 124 return;  
