forked from aspnet/AspNetWebStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpan.cs
More file actions
153 lines (131 loc) · 4.98 KB
/
Copy pathSpan.cs
File metadata and controls
153 lines (131 loc) · 4.98 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// 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.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Web.Razor.Editor;
using System.Web.Razor.Generator;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;
using Microsoft.Internal.Web.Utils;
namespace System.Web.Razor.Parser.SyntaxTree
{
public class Span : SyntaxTreeNode
{
private SourceLocation _start;
public Span(SpanBuilder builder)
{
ReplaceWith(builder);
}
public SpanKind Kind { get; protected set; }
public IEnumerable<ISymbol> Symbols { get; protected set; }
// Allow test code to re-link spans
public Span Previous { get; protected internal set; }
public Span Next { get; protected internal set; }
public SpanEditHandler EditHandler { get; protected set; }
public ISpanCodeGenerator CodeGenerator { get; protected set; }
public override bool IsBlock
{
get { return false; }
}
public override int Length
{
get { return Content.Length; }
}
public override SourceLocation Start
{
get { return _start; }
}
public string Content { get; private set; }
public void Change(Action<SpanBuilder> changes)
{
SpanBuilder builder = new SpanBuilder(this);
changes(builder);
ReplaceWith(builder);
}
public void ReplaceWith(SpanBuilder builder)
{
Debug.Assert(!builder.Symbols.Any() || builder.Symbols.All(s => s != null));
Kind = builder.Kind;
Symbols = builder.Symbols;
EditHandler = builder.EditHandler;
CodeGenerator = builder.CodeGenerator ?? SpanCodeGenerator.Null;
_start = builder.Start;
// Since we took references to the values in SpanBuilder, clear its references out
builder.Reset();
// Calculate other properties
Content = Symbols.Aggregate(new StringBuilder(), (sb, sym) => sb.Append(sym.Content), sb => sb.ToString());
}
/// <summary>
/// Accepts the specified visitor
/// </summary>
/// <remarks>
/// Calls the VisitSpan method on the specified visitor, passing in this
/// </remarks>
public override void Accept(ParserVisitor visitor)
{
visitor.VisitSpan(this);
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.Append(Kind);
builder.AppendFormat(" Span at {0}::{1} - [{2}]", Start, Length, Content);
builder.Append(" Edit: <");
builder.Append(EditHandler.ToString());
builder.Append(">");
builder.Append(" Gen: <");
builder.Append(CodeGenerator.ToString());
builder.Append("> {");
builder.Append(String.Join(";", Symbols.GroupBy(sym => sym.GetType()).Select(grp => String.Concat(grp.Key.Name, ":", grp.Count()))));
builder.Append("}");
return builder.ToString();
}
public void ChangeStart(SourceLocation newStart)
{
_start = newStart;
Span current = this;
SourceLocationTracker tracker = new SourceLocationTracker(newStart);
tracker.UpdateLocation(Content);
while ((current = current.Next) != null)
{
current._start = tracker.CurrentLocation;
tracker.UpdateLocation(current.Content);
}
}
internal void SetStart(SourceLocation newStart)
{
_start = newStart;
}
/// <summary>
/// Checks that the specified span is equivalent to the other in that it has the same start point and content.
/// </summary>
public override bool EquivalentTo(SyntaxTreeNode node)
{
Span other = node as Span;
return other != null &&
Kind.Equals(other.Kind) &&
Start.Equals(other.Start) &&
EditHandler.Equals(other.EditHandler) &&
String.Equals(other.Content, Content, StringComparison.Ordinal);
}
public override bool Equals(object obj)
{
Span other = obj as Span;
return other != null &&
Kind.Equals(other.Kind) &&
EditHandler.Equals(other.EditHandler) &&
CodeGenerator.Equals(other.CodeGenerator) &&
Symbols.SequenceEqual(other.Symbols);
}
public override int GetHashCode()
{
return HashCodeCombiner.Start()
.Add((int)Kind)
.Add(Start)
.Add(Content)
.CombinedHash;
}
}
}