diff options
Diffstat (limited to 'src/System.Web.Mvc/Razor/MvcVBRazorCodeParser.cs')
-rw-r--r-- | src/System.Web.Mvc/Razor/MvcVBRazorCodeParser.cs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/System.Web.Mvc/Razor/MvcVBRazorCodeParser.cs b/src/System.Web.Mvc/Razor/MvcVBRazorCodeParser.cs new file mode 100644 index 00000000..d2e33479 --- /dev/null +++ b/src/System.Web.Mvc/Razor/MvcVBRazorCodeParser.cs @@ -0,0 +1,93 @@ +using System.Globalization; +using System.Linq; +using System.Web.Mvc.Properties; +using System.Web.Razor.Generator; +using System.Web.Razor.Parser; +using System.Web.Razor.Parser.SyntaxTree; +using System.Web.Razor.Text; +using System.Web.Razor.Tokenizer.Symbols; + +namespace System.Web.Mvc.Razor +{ + public class MvcVBRazorCodeParser : VBCodeParser + { + internal const string ModelTypeKeyword = "ModelType"; + private const string GenericTypeFormatString = "{0}(Of {1})"; + private SourceLocation? _endInheritsLocation; + private bool _modelStatementFound; + + public MvcVBRazorCodeParser() + { + MapDirective(ModelTypeKeyword, ModelTypeDirective); + } + + protected override bool InheritsStatement() + { + // Verify we're on the right keyword and accept + Assert(VBKeyword.Inherits); + VBSymbol inherits = CurrentSymbol; + NextToken(); + _endInheritsLocation = CurrentLocation; + PutCurrentBack(); + PutBack(inherits); + EnsureCurrent(); + + bool result = base.InheritsStatement(); + CheckForInheritsAndModelStatements(); + return result; + } + + private void CheckForInheritsAndModelStatements() + { + if (_modelStatementFound && _endInheritsLocation.HasValue) + { + Context.OnError(_endInheritsLocation.Value, String.Format(CultureInfo.CurrentCulture, MvcResources.MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword, ModelTypeKeyword)); + } + } + + protected virtual bool ModelTypeDirective() + { + AssertDirective(ModelTypeKeyword); + + Span.CodeGenerator = SpanCodeGenerator.Null; + Context.CurrentBlock.Type = BlockType.Directive; + + AcceptAndMoveNext(); + SourceLocation endModelLocation = CurrentLocation; + + if (At(VBSymbolType.WhiteSpace)) + { + Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None; + } + + AcceptWhile(VBSymbolType.WhiteSpace); + Output(SpanKind.MetaCode); + + if (_modelStatementFound) + { + Context.OnError(endModelLocation, String.Format(CultureInfo.CurrentCulture, MvcResources.MvcRazorCodeParser_OnlyOneModelStatementIsAllowed, ModelTypeKeyword)); + } + _modelStatementFound = true; + + if (EndOfFile || At(VBSymbolType.WhiteSpace) || At(VBSymbolType.NewLine)) + { + Context.OnError(endModelLocation, MvcResources.MvcRazorCodeParser_ModelKeywordMustBeFollowedByTypeName, ModelTypeKeyword); + } + + // Just accept to a newline + AcceptUntil(VBSymbolType.NewLine); + if (!Context.DesignTimeMode) + { + // We want the newline to be treated as code, but it causes issues at design-time. + Optional(VBSymbolType.NewLine); + } + + string baseType = String.Concat(Span.Symbols.Select(s => s.Content)).Trim(); + Span.CodeGenerator = new SetModelTypeCodeGenerator(baseType, GenericTypeFormatString); + + CheckForInheritsAndModelStatements(); + Output(SpanKind.Code); + return false; + } + } +} |