parent
54d6b0b113
commit
2ad175b687
|
|
@ -19,16 +19,20 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
|
||||
{
|
||||
var chunks = Context.CodeTreeBuilder.CodeTree.Chunks;
|
||||
var modelChunks = Context.CodeTreeBuilder.CodeTree.Chunks.OfType<ModelChunk>();
|
||||
|
||||
// If there were any model chunks then we need to modify the class declaration signature.
|
||||
if (chunks.OfType<ModelChunk>().Any())
|
||||
if (modelChunks.Any())
|
||||
{
|
||||
writer.Write(string.Format(CultureInfo.CurrentCulture, "public class {0} : ", Context.ClassName));
|
||||
|
||||
// Grab the last model chunk so it gets intellisense.
|
||||
// NOTE: If there's more than 1 model chunk there will be a Razor error BUT we want intellisense to show up
|
||||
// on the current model chunk that the user is typing.
|
||||
var lastModelChunk = modelChunks.Last();
|
||||
var modelVisitor = new ModelChunkVisitor(writer, Context);
|
||||
// This generates the base class signature
|
||||
modelVisitor.Accept(chunks);
|
||||
modelVisitor.Accept(lastModelChunk);
|
||||
|
||||
writer.WriteLine();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,11 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Project.json" />
|
||||
<Content Include="TestFiles\Input\Model.cshtml" />
|
||||
<Content Include="TestFiles\Input\Inject.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ModelChunkVisitorTest.cs" />
|
||||
<Compile Include="InjectChunkVisitorTest.cs" />
|
||||
<Compile Include="MvcCSharpRazorCodeParserTest.cs" />
|
||||
<Compile Include="SpanFactory\RawTextSymbol.cs" />
|
||||
|
|
@ -35,6 +37,7 @@
|
|||
<Compile Include="SpanFactory\SpanFactoryExtensions.cs" />
|
||||
<Compile Include="SpanFactory\UnclassifiedSpanConstructor.cs" />
|
||||
<Compile Include="StringTextBuffer.cs" />
|
||||
<Compile Include="TestFiles\Output\Model.cs" />
|
||||
<Compile Include="TestFiles\Output\Inject.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.Razor;
|
||||
using Microsoft.AspNet.Razor.Generator;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
public class ModelChunkVisitorTest
|
||||
{
|
||||
[Fact]
|
||||
public void Visit_IgnoresNonModelChunks()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CSharpCodeWriter();
|
||||
var context = CreateContext();
|
||||
|
||||
var visitor = new ModelChunkVisitor(writer, context);
|
||||
|
||||
// Act
|
||||
visitor.Accept(new Chunk[]
|
||||
{
|
||||
new LiteralChunk(),
|
||||
new CodeAttributeChunk()
|
||||
});
|
||||
var code = writer.GenerateCode();
|
||||
|
||||
// Assert
|
||||
Assert.Empty(code);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Visit_GeneratesBaseClass_ForModelChunks()
|
||||
{
|
||||
// Arrange
|
||||
var expected =
|
||||
"MyBase<" + Environment.NewLine +
|
||||
"#line 1 \"\"" + Environment.NewLine +
|
||||
"My_Generic.After.Periods" + Environment.NewLine +
|
||||
Environment.NewLine +
|
||||
"#line default" + Environment.NewLine +
|
||||
"#line hidden" + Environment.NewLine +
|
||||
">";
|
||||
var writer = new CSharpCodeWriter();
|
||||
var context = CreateContext();
|
||||
|
||||
var visitor = new ModelChunkVisitor(writer, context);
|
||||
var factory = SpanFactory.CreateCsHtml();
|
||||
var node = (Span)factory.Code("Some code")
|
||||
.As(new ModelCodeGenerator("MyBase", "MyGeneric"));
|
||||
|
||||
// Act
|
||||
visitor.Accept(new Chunk[]
|
||||
{
|
||||
new LiteralChunk(),
|
||||
new ModelChunk("MyBase", "My_Generic.After.Periods") { Association = node }
|
||||
});
|
||||
var code = writer.GenerateCode();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, code);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Visit_WithDesignTimeHost_GeneratesBaseClass_ForModelChunks()
|
||||
{
|
||||
// Arrange
|
||||
var expected =
|
||||
"MyBase<" + Environment.NewLine +
|
||||
"#line 1 \"\"" + Environment.NewLine +
|
||||
"My_Generic.After.Periods" + Environment.NewLine +
|
||||
Environment.NewLine +
|
||||
"#line default" + Environment.NewLine +
|
||||
"#line hidden" + Environment.NewLine +
|
||||
">";
|
||||
var writer = new CSharpCodeWriter();
|
||||
var context = CreateContext();
|
||||
context.Host.DesignTimeMode = true;
|
||||
|
||||
var visitor = new ModelChunkVisitor(writer, context);
|
||||
var factory = SpanFactory.CreateCsHtml();
|
||||
var node = (Span)factory.Code("Some code")
|
||||
.As(new ModelCodeGenerator("MyType", "MyPropertyName"));
|
||||
|
||||
// Act
|
||||
visitor.Accept(new Chunk[]
|
||||
{
|
||||
new LiteralChunk(),
|
||||
new ModelChunk("MyBase", "My_Generic.After.Periods") { Association = node }
|
||||
});
|
||||
var code = writer.GenerateCode();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, code);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ModelVisitor_GeneratesCorrectLineMappings()
|
||||
{
|
||||
// Arrange
|
||||
var host = new MvcRazorHost("RazorView")
|
||||
{
|
||||
DesignTimeMode = true
|
||||
};
|
||||
host.NamespaceImports.Clear();
|
||||
var engine = new RazorTemplateEngine(host);
|
||||
var source = ReadResource("Model.cshtml");
|
||||
var expectedCode = ReadResource("Model.cs");
|
||||
var expectedLineMappings = new List<LineMapping>
|
||||
{
|
||||
BuildLineMapping(7, 0, 7, 126, 6, 7, 30),
|
||||
};
|
||||
|
||||
// Act
|
||||
GeneratorResults results;
|
||||
using (var buffer = new StringTextBuffer(source))
|
||||
{
|
||||
results = engine.GenerateCode(buffer);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.True(results.Success);
|
||||
Assert.Equal(expectedCode, results.GeneratedCode);
|
||||
Assert.Empty(results.ParserErrors);
|
||||
Assert.Equal(expectedLineMappings, results.DesignTimeLineMappings);
|
||||
}
|
||||
|
||||
private string ReadResource(string resourceName)
|
||||
{
|
||||
var assembly = typeof(ModelChunkVisitorTest).Assembly;
|
||||
|
||||
using (var stream = assembly.GetManifestResourceStream(resourceName))
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
{
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private static CodeGeneratorContext CreateContext()
|
||||
{
|
||||
return CodeGeneratorContext.Create(new MvcRazorHost("RazorView"),
|
||||
"MyClass",
|
||||
"MyNamespace",
|
||||
string.Empty,
|
||||
shouldGenerateLinePragmas: true);
|
||||
}
|
||||
|
||||
private static LineMapping BuildLineMapping(int documentAbsoluteIndex,
|
||||
int documentLineIndex,
|
||||
int documentCharacterIndex,
|
||||
int generatedAbsoluteIndex,
|
||||
int generatedLineIndex,
|
||||
int generatedCharacterIndex,
|
||||
int contentLength)
|
||||
{
|
||||
var documentLocation = new SourceLocation(documentAbsoluteIndex,
|
||||
documentLineIndex,
|
||||
documentCharacterIndex);
|
||||
var generatedLocation = new SourceLocation(generatedAbsoluteIndex,
|
||||
generatedLineIndex,
|
||||
generatedCharacterIndex);
|
||||
|
||||
return new LineMapping(
|
||||
documentLocation: new MappingLocation(documentLocation, contentLength),
|
||||
generatedLocation: new MappingLocation(generatedLocation, contentLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
@model System.Collections.IEnumerable
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Razor
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class __CompiledTemplate : RazorView<
|
||||
#line 1 ""
|
||||
System.Collections.IEnumerable
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
>
|
||||
{
|
||||
private static object @__o;
|
||||
private void @__RazorDesignTimeHelpers__()
|
||||
{
|
||||
#pragma warning disable 219
|
||||
#pragma warning restore 219
|
||||
}
|
||||
#line hidden
|
||||
|
||||
#line hidden
|
||||
public __CompiledTemplate()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue