Browse Source
Use the @model directive to generate a strongly typed WebViewPage class. Support completion on the Model property in a view.pull/28/head
8 changed files with 310 additions and 9 deletions
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Web.Razor; |
||||
using ICSharpCode.SharpDevelop; |
||||
|
||||
namespace ICSharpCode.AspNet.Mvc.Completion |
||||
{ |
||||
public class RazorCSharpModelTypeLocater |
||||
{ |
||||
public RazorCSharpModelTypeLocater(ITextBuffer textBuffer) |
||||
{ |
||||
ParserResults results = ParseTemplate(textBuffer); |
||||
ModelTypeName = GetModelTypeName(results); |
||||
} |
||||
|
||||
ParserResults ParseTemplate(ITextBuffer textBuffer) |
||||
{ |
||||
var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); |
||||
var engine = new RazorTemplateEngine(host); |
||||
return engine.ParseTemplate(textBuffer.CreateReader()); |
||||
} |
||||
|
||||
string GetModelTypeName(ParserResults results) |
||||
{ |
||||
var visitor = new RazorCSharpParserModelTypeVisitor(); |
||||
results.Document.Accept(visitor); |
||||
return visitor.ModelTypeName; |
||||
} |
||||
|
||||
public string ModelTypeName { get; private set; } |
||||
} |
||||
} |
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Web.Razor.Parser; |
||||
using System.Web.Razor.Parser.SyntaxTree; |
||||
|
||||
namespace ICSharpCode.AspNet.Mvc.Completion |
||||
{ |
||||
public class RazorCSharpParserModelTypeVisitor : ParserVisitor |
||||
{ |
||||
bool foundModelTypeName; |
||||
|
||||
public RazorCSharpParserModelTypeVisitor() |
||||
{ |
||||
ModelTypeName = String.Empty; |
||||
} |
||||
|
||||
public string ModelTypeName { get; private set; } |
||||
|
||||
public override void VisitSpan(Span span) |
||||
{ |
||||
Console.WriteLine("Span.Kind: " + span.Kind); |
||||
Console.WriteLine("Span.GetType(): " + span.GetType().Name); |
||||
Console.WriteLine("Span.Content: '" + span.Content + "'"); |
||||
|
||||
if (foundModelTypeName) |
||||
return; |
||||
|
||||
if (IsModelSpan(span)) { |
||||
VisitModelNameSpan(span.Next); |
||||
} |
||||
} |
||||
|
||||
bool IsModelSpan(Span span) |
||||
{ |
||||
return span.Content == "model"; |
||||
} |
||||
|
||||
void VisitModelNameSpan(Span span) |
||||
{ |
||||
if (span == null) |
||||
return; |
||||
|
||||
string firstLineOfMarkup = GetFirstLine(span.Content); |
||||
ModelTypeName = firstLineOfMarkup.Trim(); |
||||
foundModelTypeName = true; |
||||
} |
||||
|
||||
string GetFirstLine(string text) |
||||
{ |
||||
int endOfLineIndex = text.IndexOf('\r'); |
||||
if (endOfLineIndex > 0) { |
||||
return text.Substring(0, endOfLineIndex); |
||||
} |
||||
return text; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.AspNet.Mvc.Completion |
||||
{ |
||||
public class RazorCompilationUnit : DefaultCompilationUnit |
||||
{ |
||||
public RazorCompilationUnit(IProjectContent projectContent) |
||||
: base(projectContent) |
||||
{ |
||||
} |
||||
|
||||
public static RazorCompilationUnit CreateFromParseInfo(ParseInformation parseInformation) |
||||
{ |
||||
return new RazorCompilationUnit(parseInformation.CompilationUnit.ProjectContent) { |
||||
ModelTypeName = GetModelTypeName(parseInformation.CompilationUnit) |
||||
}; |
||||
} |
||||
|
||||
static string GetModelTypeName(ICompilationUnit compilationUnit) |
||||
{ |
||||
var originalRazorCompilationUnit = compilationUnit as RazorCompilationUnit; |
||||
if (originalRazorCompilationUnit != null) { |
||||
return originalRazorCompilationUnit.ModelTypeName; |
||||
} |
||||
return String.Empty; |
||||
} |
||||
|
||||
public string ModelTypeName { get; set; } |
||||
} |
||||
} |
@ -0,0 +1,148 @@
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.AspNet.Mvc.Completion; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using NUnit.Framework; |
||||
|
||||
namespace AspNet.Mvc.Tests.Completion |
||||
{ |
||||
[TestFixture] |
||||
public class RazorCSharpParserTests |
||||
{ |
||||
RazorCSharpParser parser; |
||||
|
||||
void CreateParser() |
||||
{ |
||||
parser = new RazorCSharpParser(); |
||||
} |
||||
|
||||
ICompilationUnit Parse(string code) |
||||
{ |
||||
var projectContent = new DefaultProjectContent(); |
||||
var textBuffer = new StringTextBuffer(code); |
||||
return parser.Parse(projectContent, @"d:\MyProject\Views\Index.cshtml", textBuffer); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_ModelDirectiveWithTypeName_ModelTypeNameFound() |
||||
{ |
||||
CreateParser(); |
||||
string code = "@model MvcApplication.MyModel\r\n"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual("MvcApplication.MyModel", compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_ModelDirectiveWithTypeNameFollowedByHtmlMarkup_ModelTypeNameFound() |
||||
{ |
||||
CreateParser(); |
||||
string code = |
||||
"@model MvcApplication.LogonModel\r\n" + |
||||
"<h2>Index</h2>\r\n"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual("MvcApplication.LogonModel", compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_SingleLineFileWithModelDirectiveAndTypeNameButNoNewLineAtEnd_ModelTypeNameFound() |
||||
{ |
||||
CreateParser(); |
||||
string code = "@model MvcApplication.MyModel"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual("MvcApplication.MyModel", compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_ModelTypeDirectiveWithTypeNameFollowedByRazorBlock_ModelTypeNameFound() |
||||
{ |
||||
CreateParser(); |
||||
|
||||
string code = |
||||
"@model IEnumerable<MvcApplication1.Models.MyClass>\r\n" + |
||||
"\r\n" + |
||||
"@{\r\n" + |
||||
" ViewBag.Title = \"Title1\";\r\n" + |
||||
"}\r\n" + |
||||
"\r\n"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual("IEnumerable<MvcApplication1.Models.MyClass>", compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_UsingDirective_ModelTypeNameIsEmptyString() |
||||
{ |
||||
CreateParser(); |
||||
string code = "@using System.Xml\r\n"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual(String.Empty, compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_HelperDirective_ModelTypeNameIsEmptyString() |
||||
{ |
||||
CreateParser(); |
||||
string code = "@helper MyHelper\r\n"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual(String.Empty, compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_HtmlMarkupOnly_ModelTypeNameIsEmptyString() |
||||
{ |
||||
CreateParser(); |
||||
string code = "<h1>heading</h1>\r\n"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual(String.Empty, compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_ModelDirectiveOnly_ModelTypeNameIsEmptyString() |
||||
{ |
||||
CreateParser(); |
||||
string code = "@model"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual(String.Empty, compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_ModelStringInsideParagraphTags_ModelTypeNameIsEmptyString() |
||||
{ |
||||
CreateParser(); |
||||
string code = "<p>model</p>"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual(String.Empty, compilationUnit.ModelTypeName); |
||||
} |
||||
|
||||
[Test] |
||||
public void Parse_ModelStringOnlyWithoutRazorTransition_ModelTypeNameIsEmptyString() |
||||
{ |
||||
CreateParser(); |
||||
string code = "model"; |
||||
|
||||
var compilationUnit = Parse(code) as RazorCompilationUnit; |
||||
|
||||
Assert.AreEqual(String.Empty, compilationUnit.ModelTypeName); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue