diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/Microsoft.AspNet.Mvc.Razor.Host.kproj b/src/Microsoft.AspNet.Mvc.Razor.Host/Microsoft.AspNet.Mvc.Razor.Host.kproj
index 577f5a3481..227e4f8f8a 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/Microsoft.AspNet.Mvc.Razor.Host.kproj
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/Microsoft.AspNet.Mvc.Razor.Host.kproj
@@ -25,6 +25,10 @@
+
+
+
+
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/ModelChunk.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/ModelChunk.cs
new file mode 100644
index 0000000000..0b034fd66a
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/ModelChunk.cs
@@ -0,0 +1,21 @@
+using Microsoft.AspNet.Razor.Generator.Compiler;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ public class ModelChunk : Chunk
+ {
+ ///
+ /// Represents the chunk for an @model statement.
+ ///
+ /// The base type of the view.
+ /// The type of the view's Model.
+ public ModelChunk(string baseType, string modelType)
+ {
+ BaseType = baseType;
+ ModelType = modelType;
+ }
+
+ public string BaseType { get; private set; }
+ public string ModelType { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/ModelChunkVisitor.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/ModelChunkVisitor.cs
new file mode 100644
index 0000000000..8c38523769
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/ModelChunkVisitor.cs
@@ -0,0 +1,22 @@
+using Microsoft.AspNet.Razor.Generator;
+using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ public class ModelChunkVisitor : MvcCSharpCodeVisitor
+ {
+ public ModelChunkVisitor([NotNull] CSharpCodeWriter writer,
+ [NotNull] CodeGeneratorContext context)
+ : base(writer, context)
+ { }
+
+ protected override void Visit(ModelChunk chunk)
+ {
+ var csharpVisitor = new CSharpCodeVisitor(Writer, Context);
+
+ Writer.Write(chunk.BaseType).Write("<");
+ csharpVisitor.CreateExpressionCodeMapping(chunk.ModelType, chunk);
+ Writer.Write(">");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/ModelCodeGenerator.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/ModelCodeGenerator.cs
new file mode 100644
index 0000000000..632678dcba
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/ModelCodeGenerator.cs
@@ -0,0 +1,41 @@
+using System;
+using Microsoft.AspNet.Mvc.Razor;
+using Microsoft.AspNet.Razor.Parser.SyntaxTree;
+
+namespace Microsoft.AspNet.Razor.Generator
+{
+ public class ModelCodeGenerator : SpanCodeGenerator
+ {
+ public ModelCodeGenerator(string baseType, string modelType)
+ {
+ BaseType = baseType;
+ ModelType = modelType;
+ }
+
+ public string BaseType { get; private set; }
+ public string ModelType { get; private set; }
+
+ public override void GenerateCode(Span target, CodeGeneratorContext context)
+ {
+ var modelChunk = new ModelChunk(BaseType, ModelType);
+ context.CodeTreeBuilder.AddChunk(modelChunk, target, topLevel: true);
+ }
+
+ public override string ToString()
+ {
+ return "Full Model Type: " + BaseType + "<" + ModelType + ">";
+ }
+
+ public override bool Equals(object obj)
+ {
+ var other = obj as ModelCodeGenerator;
+ return other != null &&
+ string.Equals(ModelType, other.ModelType, StringComparison.Ordinal);
+ }
+
+ public override int GetHashCode()
+ {
+ return ModelType.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpChunkVisitor.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpChunkVisitor.cs
new file mode 100644
index 0000000000..887466eed5
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpChunkVisitor.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNet.Razor.Generator;
+using Microsoft.AspNet.Razor.Generator.Compiler;
+using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ public abstract class MvcCSharpChunkVisitor : CodeVisitor
+ {
+ public MvcCSharpChunkVisitor([NotNull] CSharpCodeWriter writer,
+ [NotNull] CodeGeneratorContext context)
+ : base(writer, context)
+ { }
+
+ public override void Accept(Chunk chunk)
+ {
+ if (chunk is InjectChunk)
+ {
+ Visit((InjectChunk)chunk);
+ }
+ else if (chunk is ModelChunk)
+ {
+ Visit((ModelChunk)chunk);
+ }
+ else
+ {
+ base.Accept(chunk);
+ }
+ }
+
+ protected abstract void Visit(InjectChunk chunk);
+ protected abstract void Visit(ModelChunk chunk);
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs
index a3a9ac5c63..c7a510feda 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs
@@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Razor.Generator;
+using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
namespace Microsoft.AspNet.Mvc.Razor
@@ -15,6 +17,29 @@ namespace Microsoft.AspNet.Mvc.Razor
{
}
+ protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
+ {
+ var chunks = Context.CodeTreeBuilder.CodeTree.Chunks;
+
+ // If there were any model chunks then we need to modify the class declaration signature.
+ if (chunks.OfType().Any())
+ {
+ writer.Write(string.Format(CultureInfo.CurrentCulture, "public class {0} : ", Context.ClassName));
+
+ var modelVisitor = new ModelChunkVisitor(writer, Context);
+ // This generates the base class signature
+ modelVisitor.Accept(chunks);
+
+ writer.WriteLine();
+
+ return new CSharpCodeWritingScope(writer);
+ }
+ else
+ {
+ return base.BuildClassDeclaration(writer);
+ }
+ }
+
protected override void BuildConstructor([NotNull] CSharpCodeWriter writer)
{
writer.WriteLineHiddenDirective();
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeVistor.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeVistor.cs
index 89a843d307..334873d574 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeVistor.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeVistor.cs
@@ -2,31 +2,22 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Razor.Generator;
-using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
namespace Microsoft.AspNet.Mvc.Razor
{
- public abstract class MvcCSharpCodeVisitor : CodeVisitor
+ public abstract class MvcCSharpCodeVisitor : MvcCSharpChunkVisitor
{
- public MvcCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
+ public MvcCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
[NotNull] CodeGeneratorContext context)
: base(writer, context)
+ { }
+
+ protected override void Visit(InjectChunk chunk)
{
}
-
- public override void Accept(Chunk chunk)
+ protected override void Visit(ModelChunk chunk)
{
- if (chunk is InjectChunk)
- {
- Visit((InjectChunk)chunk);
- }
- else
- {
- base.Accept(chunk);
- }
}
-
- protected abstract void Visit(InjectChunk chunk);
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
index 6b19279dac..6601e4920c 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorCodeParser.cs
@@ -1,7 +1,6 @@
// 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.Globalization;
using Microsoft.AspNet.Mvc.Razor.Host;
using Microsoft.AspNet.Razor.Generator;
using Microsoft.AspNet.Razor.Parser;
@@ -13,7 +12,6 @@ namespace Microsoft.AspNet.Mvc.Razor
{
public class MvcRazorCodeParser : CSharpCodeParser
{
- private const string GenericTypeFormat = "{0}<{1}>";
private const string ModelKeyword = "model";
private const string InjectKeyword = "inject";
private readonly string _baseType;
@@ -138,12 +136,7 @@ namespace Microsoft.AspNet.Mvc.Razor
private SpanCodeGenerator CreateModelCodeGenerator(string model)
{
- // In the event we have an empty model, the name we generate does not matter since it's a parser error.
- // We'll use the non-generic version of the base type.
- var baseType = string.IsNullOrEmpty(model) ?
- _baseType :
- string.Format(CultureInfo.InvariantCulture, GenericTypeFormat, _baseType, model);
- return new SetBaseTypeCodeGenerator(baseType);
+ return new ModelCodeGenerator(_baseType, model);
}
}
}