forked from aspnet/AspNetWebStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHelperCodeGenerator.cs
More file actions
116 lines (101 loc) · 4.24 KB
/
HelperCodeGenerator.cs
File metadata and controls
116 lines (101 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.CodeDom;
using System.Globalization;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Text;
using Microsoft.Internal.Web.Utils;
namespace System.Web.Razor.Generator
{
public class HelperCodeGenerator : BlockCodeGenerator
{
private const string HelperWriterName = "__razor_helper_writer";
private CodeWriter _writer;
private string _oldWriter;
private IDisposable _statementCollectorToken;
public HelperCodeGenerator(LocationTagged<string> signature, bool headerComplete)
{
Signature = signature;
HeaderComplete = headerComplete;
}
public LocationTagged<string> Signature { get; private set; }
public LocationTagged<string> Footer { get; set; }
public bool HeaderComplete { get; private set; }
public override void GenerateStartBlockCode(Block target, CodeGeneratorContext context)
{
_writer = context.CreateCodeWriter();
string prefix = context.BuildCodeString(
cw => cw.WriteHelperHeaderPrefix(context.Host.GeneratedClassContext.TemplateTypeName, context.Host.StaticHelpers));
_writer.WriteLinePragma(
context.GenerateLinePragma(Signature.Location, prefix.Length, Signature.Value.Length));
_writer.WriteSnippet(prefix);
_writer.WriteSnippet(Signature);
if (HeaderComplete)
{
_writer.WriteHelperHeaderSuffix(context.Host.GeneratedClassContext.TemplateTypeName);
}
_writer.WriteLinePragma(null);
if (HeaderComplete)
{
_writer.WriteReturn();
_writer.WriteStartConstructor(context.Host.GeneratedClassContext.TemplateTypeName);
_writer.WriteStartLambdaDelegate(HelperWriterName);
}
_statementCollectorToken = context.ChangeStatementCollector(AddStatementToHelper);
_oldWriter = context.TargetWriterName;
context.TargetWriterName = HelperWriterName;
}
public override void GenerateEndBlockCode(Block target, CodeGeneratorContext context)
{
_statementCollectorToken.Dispose();
if (HeaderComplete)
{
_writer.WriteEndLambdaDelegate();
_writer.WriteEndConstructor();
_writer.WriteEndStatement();
}
if (Footer != null && !String.IsNullOrEmpty(Footer.Value))
{
_writer.WriteLinePragma(
context.GenerateLinePragma(Footer.Location, 0, Footer.Value.Length));
_writer.WriteSnippet(Footer);
_writer.WriteLinePragma();
}
_writer.WriteHelperTrailer();
context.GeneratedClass.Members.Add(new CodeSnippetTypeMember(_writer.Content));
context.TargetWriterName = _oldWriter;
}
public override bool Equals(object obj)
{
HelperCodeGenerator other = obj as HelperCodeGenerator;
return other != null &&
base.Equals(other) &&
HeaderComplete == other.HeaderComplete &&
Equals(Signature, other.Signature);
}
public override int GetHashCode()
{
return HashCodeCombiner.Start()
.Add(base.GetHashCode())
.Add(Signature)
.CombinedHash;
}
public override string ToString()
{
return "Helper:" + Signature.ToString("F", CultureInfo.CurrentCulture) + ";" + (HeaderComplete ? "C" : "I");
}
private void AddStatementToHelper(string statement, CodeLinePragma pragma)
{
if (pragma != null)
{
_writer.WriteLinePragma(pragma);
}
_writer.WriteSnippet(statement);
_writer.InnerWriter.WriteLine(); // CodeDOM normally inserts an extra line so we need to do so here.
if (pragma != null)
{
_writer.WriteLinePragma();
}
}
}
}