From 49ffb5ae8160575ddbf88ceebcdd493066ec5c9c Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Mon, 24 Feb 2014 17:29:52 -0800 Subject: [PATCH] Map semicolon's in using statements. This allows for users to write "@using System;" and still have proper intellisense and mapping. Also removed some legacy code that I came across when running tests. --- .../CSharp/Visitors/CSharpUsingVisitor.cs | 28 ++++++++++++++++--- .../Generator/CSharpRazorCodeGeneratorTest.cs | 5 +--- .../CodeTree/CSharpCodeBuilderTests.cs | 6 ++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpUsingVisitor.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpUsingVisitor.cs index 185c7080a8..f11a3cd158 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpUsingVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpUsingVisitor.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNet.Razor.Parser.SyntaxTree; namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { @@ -14,14 +16,32 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp protected override void Visit(UsingChunk chunk) { - ImportedUsings.Add(chunk.Namespace); + string documentContent = ((Span)chunk.Association).Content.Trim(); + bool mapSemicolon = false; - using (Writer.BuildLineMapping(chunk.Start, chunk.Association.Length, Context.SourceFile)) + if (documentContent.LastOrDefault() == ';') { - Writer.WriteUsing(chunk.Namespace, endLine: false); + mapSemicolon = true; } - Writer.WriteLine(";"); + ImportedUsings.Add(chunk.Namespace); + + // Depending on if the user has a semicolon in their @using statement we have to conditionally decide + // to include the semicolon in the line mapping. + using (Writer.BuildLineMapping(chunk.Start, documentContent.Length, Context.SourceFile)) + { + Writer.WriteUsing(chunk.Namespace, endLine: false); + + if (mapSemicolon) + { + Writer.Write(";"); + } + } + + if (!mapSemicolon) + { + Writer.WriteLine(";"); + } } } } diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs index 2f084353cf..08734660cc 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs @@ -91,10 +91,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator Directory.CreateDirectory("./tests"); } - RunTest(testType, onResults: (results) => - { - File.WriteAllText(String.Format("./tests/{0}.cs", testType), results.GeneratedCode); - }); + RunTest(testType); } [Fact] diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CodeTree/CSharpCodeBuilderTests.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CodeTree/CSharpCodeBuilderTests.cs index 378337aae3..e6aaf09667 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/CodeTree/CSharpCodeBuilderTests.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/CodeTree/CSharpCodeBuilderTests.cs @@ -12,12 +12,12 @@ namespace Microsoft.AspNet.Razor.Test.Generator.CodeTree [Fact] public void CodeTreeWithUsings() { - var syntaxTreeNode = Mock.Of(); + var syntaxTreeNode = new Mock(new SpanBuilder()); var language = new CSharpRazorCodeLanguage(); RazorEngineHost host = new RazorEngineHost(language); var context = CodeGeneratorContext.Create(host, "TestClass", "TestNamespace", "Foo.cs", shouldGenerateLinePragmas: false); - context.CodeTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode); - context.CodeTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode); + context.CodeTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode.Object); + context.CodeTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode.Object); CodeBuilder codeBuilder = language.CreateBuilder(context); // Act