2
// Based on MvcCSharpRazorCodeParser.cs
3
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
4
// Licensed under the Microsoft Public License (MS-PL)
7
// Author: Michael Hutchinson <mhutch@xamarin.com>
8
// Copyright (c) 2012 Xamarin Inc (http://xamarin.com)
9
// Licensed under the Microsoft Public License (MS-PL)
12
using System.Globalization;
13
using System.Web.Razor.Generator;
14
using System.Web.Razor.Parser;
15
using System.Web.Razor.Text;
16
using System.Collections.Generic;
17
using System.Web.Razor.Parser.SyntaxTree;
18
using System.Web.Razor.Tokenizer.Symbols;
22
namespace MonoDevelop.RazorGenerator
24
class PreprocessedCSharpRazorCodeParser : CSharpCodeParser
26
public const string ModelKeyword = "model";
27
public const string PropertyKeyword = "__property";
28
public const string ClassKeyword = "__class";
30
HashSet<string> directives = new HashSet<string> ();
32
public PreprocessedCSharpRazorCodeParser()
34
MapDirectives (ModelDirective, ModelKeyword);
35
MapDirectives (PropertyDirective, PropertyKeyword);
36
MapDirectives (ClassDirective, ClassKeyword);
39
void ModelDirective ()
41
ValueDirective (ModelKeyword, true, (s, l) => {
42
var split = GetArgumentWords (s);
43
if (split.Length == 1) {
44
return new PropertyCodeGenerator (split[0], "Model");
46
Context.OnError (l, string.Format ("The '{0}' directive requires exactly one argument", ModelKeyword));
51
void PropertyDirective ()
53
ValueDirective (PropertyKeyword, true, (s, l) => {
54
var split = GetArgumentWords (s);
55
if (split.Length == 2) {
56
return new PropertyCodeGenerator (split[0], split[1]);
58
Context.OnError (l, string.Format ("The '{0}' directive requires exactly two arguments", PropertyKeyword));
63
void ClassDirective ()
65
ValueDirective (ClassKeyword, true, (s, l) => {
66
var split = GetArgumentWords (s);
67
if (split.Length != 1 && split.Length != 2) {
68
Context.OnError (l, string.Format ("The '{0}' directive requires one or two arguments", ClassKeyword));
71
string name = null, access = null;
72
if (split[0] == "public" || split[0] == "internal") {
77
if (split.Length == 2) {
79
string err = "If '{0}' directive has two arguments, the first must be 'public' or 'internal'.";
80
Context.OnError (l, string.Format (err, ClassKeyword));
85
return new ClassNameCodeGenerator (access, name);
89
static char[] wordSplitChars = new[] { ' ', '\t'};
90
static string[] GetArgumentWords (string value)
92
return value.Split (wordSplitChars, StringSplitOptions.RemoveEmptyEntries);
95
void ValueDirective (string keyword, bool checkOne, Func<string,SourceLocation,SpanCodeGenerator> valueParsed)
97
AssertDirective (ClassKeyword);
99
if (checkOne && !directives.Add (keyword)) {
102
string.Format ("Only one '{0}' directive is permitted", keyword)
105
SourceLocation location = CurrentLocation;
107
string.Format ("The '{0}' directive must have a value", keyword),
110
return valueParsed (s, location);
116
class PropertyCodeGenerator : SpanCodeGenerator
118
public PropertyCodeGenerator (string type, string name)
124
public string Type {get; private set; }
125
public string Name { get; private set; }
127
public override void GenerateCode (Span target, CodeGeneratorContext context)
129
var text = string.Format ("public {0} {1} {{ get; set; }}\n", Type, Name);
130
var prop = new CodeSnippetTypeMember (text);
131
prop.LinePragma = new CodeLinePragma (context.SourceFile, target.Start.LineIndex + 1);
132
context.GeneratedClass.Members.Add (prop);
136
class ClassNameCodeGenerator : SpanCodeGenerator
138
public ClassNameCodeGenerator (string access, string name)
140
this.Access = access;
144
public string Name {get; private set; }
145
public string Access {get; private set; }
147
public override void GenerateCode (Span target, CodeGeneratorContext context)
150
var idx = Name.LastIndexOf ('.');
152
context.Namespace.Name = Name.Substring (0, idx);
153
context.GeneratedClass.Name = Name.Substring (idx + 1);
155
context.GeneratedClass.Name = Name;
159
if (Access == "public") {
160
context.GeneratedClass.TypeAttributes |= System.Reflection.TypeAttributes.Public;
161
} else if (Access == "internal") {
162
context.GeneratedClass.TypeAttributes &= ~System.Reflection.TypeAttributes.Public;
b'\\ No newline at end of file'