Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Commit 5148739

Browse files
committed
Rewrite intermediate phase
1 parent 6c970d3 commit 5148739

File tree

136 files changed

+2299
-998
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+2299
-998
lines changed

src/Microsoft.AspNetCore.Razor.Language/ClassifiedSpanVisitor.cs

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public override SyntaxNode VisitMarkupBlock(MarkupBlockSyntax node)
9999

100100
public override SyntaxNode VisitGenericBlock(GenericBlockSyntax node)
101101
{
102-
if (!(node.Parent is MarkupDynamicAttributeValueSyntax) &&
103-
node.FirstAncestorOrSelf<SyntaxNode>(n => n is MarkupDynamicAttributeValueSyntax) != null)
102+
if (!(node.Parent is MarkupTagHelperAttributeValueSyntax) &&
103+
node.FirstAncestorOrSelf<SyntaxNode>(n => n is MarkupTagHelperAttributeValueSyntax) != null)
104104
{
105105
return WriteBlock(node, BlockKindInternal.Expression, base.VisitGenericBlock);
106106
}
@@ -284,8 +284,8 @@ private void WriteSpan(SyntaxNode node, SpanKindInternal kind, AcceptedCharacter
284284
return;
285285
}
286286

287-
var spanSource = GetSourceSpanForNode(node);
288-
var blockSource = GetSourceSpanForNode(_currentBlock);
287+
var spanSource = node.GetSourceSpan(_source);
288+
var blockSource = _currentBlock.GetSourceSpan(_source);
289289
if (!acceptedCharacters.HasValue)
290290
{
291291
acceptedCharacters = AcceptedCharactersInternal.Any;
@@ -337,35 +337,5 @@ private MarkupTextLiteralSyntax MergeTextLiteralSpans(params MarkupTextLiteralSy
337337

338338
return (MarkupTextLiteralSyntax)mergedLiteralSyntax.CreateRed(parent, position);
339339
}
340-
341-
private SourceSpan GetSourceSpanForNode(SyntaxNode node)
342-
{
343-
try
344-
{
345-
if (_source.Length == 0)
346-
{
347-
// Just a marker symbol
348-
return new SourceSpan(_source.FilePath, 0, 0, 0, node.FullWidth);
349-
}
350-
if (node.Position >= _source.Length)
351-
{
352-
// E.g. Marker symbol at the end of the document
353-
var lastLocation = _source.Lines.GetLocation(_source.Length - 1);
354-
return new SourceSpan(
355-
lastLocation.FilePath,
356-
lastLocation.AbsoluteIndex + 1,
357-
lastLocation.LineIndex,
358-
lastLocation.CharacterIndex + 1,
359-
node.FullWidth);
360-
}
361-
362-
return node.GetSourceSpan(_source);
363-
}
364-
catch (IndexOutOfRangeException)
365-
{
366-
Debug.Assert(false, "Node position should stay within document length.");
367-
return new SourceSpan(_source.FilePath, node.Position, 0, 0, node.FullWidth);
368-
}
369-
}
370340
}
371341
}

src/Microsoft.AspNetCore.Razor.Language/DefaultRazorIntermediateNodeLoweringPhase.cs

Lines changed: 603 additions & 293 deletions
Large diffs are not rendered by default.

src/Microsoft.AspNetCore.Razor.Language/DefaultRazorParsingPhase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ protected override void OnIntialized()
1616
protected override void ExecuteCore(RazorCodeDocument codeDocument)
1717
{
1818
var options = codeDocument.GetParserOptions() ??_optionsFeature.GetOptions();
19-
var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options);
19+
var syntaxTree = RazorSyntaxTree.Parse(codeDocument.Source, options, legacy: false);
2020
codeDocument.SetSyntaxTree(syntaxTree);
2121

2222
var importSyntaxTrees = new RazorSyntaxTree[codeDocument.Imports.Count];
2323
for (var i = 0; i < codeDocument.Imports.Count; i++)
2424
{
25-
importSyntaxTrees[i] = RazorSyntaxTree.Parse(codeDocument.Imports[i], options);
25+
importSyntaxTrees[i] = RazorSyntaxTree.Parse(codeDocument.Imports[i], options, legacy: false);
2626
}
2727
codeDocument.SetImportSyntaxTrees(importSyntaxTrees);
2828
}

src/Microsoft.AspNetCore.Razor.Language/DefaultRazorTagHelperBinderPhase.cs

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -185,66 +185,80 @@ public DirectiveVisitor(IReadOnlyList<TagHelperDescriptor> tagHelpers)
185185

186186
public HashSet<TagHelperDescriptor> Matches { get; } = new HashSet<TagHelperDescriptor>();
187187

188-
public override SyntaxNode VisitRazorDirectiveBody(RazorDirectiveBodySyntax node)
188+
public override SyntaxNode VisitRazorDirective(RazorDirectiveSyntax node)
189189
{
190-
var context = node.GetSpanContext();
191-
if (context.ChunkGenerator is AddTagHelperChunkGenerator addTagHelper)
190+
var descendantLiterals = node.DescendantNodes();
191+
foreach (var child in descendantLiterals)
192192
{
193-
if (addTagHelper.AssemblyName == null)
193+
if (!(child is CSharpStatementLiteralSyntax literal))
194194
{
195-
// Skip this one, it's an error
196-
return base.VisitRazorDirectiveBody(node);
195+
continue;
197196
}
198197

199-
if (!AssemblyContainsTagHelpers(addTagHelper.AssemblyName, _tagHelpers))
198+
var context = literal.GetSpanContext();
199+
if (context == null)
200200
{
201-
// No tag helpers in the assembly.
202-
return base.VisitRazorDirectiveBody(node);
201+
// We can't find a chunk generator.
202+
continue;
203203
}
204-
205-
for (var i = 0; i < _tagHelpers.Count; i++)
204+
else if (context.ChunkGenerator is AddTagHelperChunkGenerator addTagHelper)
206205
{
207-
var tagHelper = _tagHelpers[i];
208-
if (MatchesDirective(tagHelper, addTagHelper.TypePattern, addTagHelper.AssemblyName))
206+
if (addTagHelper.AssemblyName == null)
207+
{
208+
// Skip this one, it's an error
209+
continue;
210+
}
211+
212+
if (!AssemblyContainsTagHelpers(addTagHelper.AssemblyName, _tagHelpers))
209213
{
210-
Matches.Add(tagHelper);
214+
// No tag helpers in the assembly.
215+
continue;
216+
}
217+
218+
for (var i = 0; i < _tagHelpers.Count; i++)
219+
{
220+
var tagHelper = _tagHelpers[i];
221+
if (MatchesDirective(tagHelper, addTagHelper.TypePattern, addTagHelper.AssemblyName))
222+
{
223+
Matches.Add(tagHelper);
224+
}
211225
}
212226
}
213-
}
214-
else if (context.ChunkGenerator is RemoveTagHelperChunkGenerator removeTagHelper)
215-
{
216-
if (removeTagHelper.AssemblyName == null)
227+
else if (context.ChunkGenerator is RemoveTagHelperChunkGenerator removeTagHelper)
217228
{
218-
// Skip this one, it's an error
219-
return base.VisitRazorDirectiveBody(node);
220-
}
229+
if (removeTagHelper.AssemblyName == null)
230+
{
231+
// Skip this one, it's an error
232+
continue;
233+
}
221234

222235

223-
if (!AssemblyContainsTagHelpers(removeTagHelper.AssemblyName, _tagHelpers))
224-
{
225-
// No tag helpers in the assembly.
226-
return base.VisitRazorDirectiveBody(node);
227-
}
236+
if (!AssemblyContainsTagHelpers(removeTagHelper.AssemblyName, _tagHelpers))
237+
{
238+
// No tag helpers in the assembly.
239+
continue;
240+
}
228241

229-
for (var i = 0; i < _tagHelpers.Count; i++)
230-
{
231-
var tagHelper = _tagHelpers[i];
232-
if (MatchesDirective(tagHelper, removeTagHelper.TypePattern, removeTagHelper.AssemblyName))
242+
for (var i = 0; i < _tagHelpers.Count; i++)
233243
{
234-
Matches.Remove(tagHelper);
244+
var tagHelper = _tagHelpers[i];
245+
if (MatchesDirective(tagHelper, removeTagHelper.TypePattern, removeTagHelper.AssemblyName))
246+
{
247+
Matches.Remove(tagHelper);
248+
}
235249
}
236250
}
237-
}
238-
else if (context.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator tagHelperPrefix)
239-
{
240-
if (!string.IsNullOrEmpty(tagHelperPrefix.DirectiveText))
251+
else if (context.ChunkGenerator is TagHelperPrefixDirectiveChunkGenerator tagHelperPrefix)
241252
{
242-
// We only expect to see a single one of these per file, but that's enforced at another level.
243-
TagHelperPrefix = tagHelperPrefix.DirectiveText;
253+
if (!string.IsNullOrEmpty(tagHelperPrefix.DirectiveText))
254+
{
255+
// We only expect to see a single one of these per file, but that's enforced at another level.
256+
TagHelperPrefix = tagHelperPrefix.DirectiveText;
257+
}
244258
}
245259
}
246260

247-
return base.VisitRazorDirectiveBody(node);
261+
return base.VisitRazorDirective(node);
248262
}
249263

250264
private bool AssemblyContainsTagHelpers(string assemblyName, IReadOnlyList<TagHelperDescriptor> tagHelpers)

src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpParser.cs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,14 @@ private void ParseTemplate(in SyntaxListBuilder<RazorSyntaxNode> builder)
685685
RazorDiagnosticFactory.CreateParsing_InlineMarkupBlocksCannotBeNested(
686686
new SourceSpan(CurrentStart, contentLength: 1 /* @ */)));
687687
}
688-
builder.Add(OutputTokensAsStatementLiteral());
688+
if (SpanContext.ChunkGenerator is ExpressionChunkGenerator)
689+
{
690+
builder.Add(OutputTokensAsExpressionLiteral());
691+
}
692+
else
693+
{
694+
builder.Add(OutputTokensAsStatementLiteral());
695+
}
689696

690697
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
691698
{
@@ -777,14 +784,14 @@ private void ParseTagHelperPrefixDirective(SyntaxListBuilder<RazorSyntaxNode> bu
777784

778785
var directiveBody = ParseTagHelperDirective(
779786
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
780-
(prefix, errors) =>
787+
(prefix, errors, startLocation) =>
781788
{
782789
if (duplicateDiagnostic != null)
783790
{
784791
errors.Add(duplicateDiagnostic);
785792
}
786793

787-
var parsedDirective = ParseDirective(prefix, CurrentStart, TagHelperDirectiveType.TagHelperPrefix, errors);
794+
var parsedDirective = ParseDirective(prefix, startLocation, TagHelperDirectiveType.TagHelperPrefix, errors);
788795

789796
return new TagHelperPrefixDirectiveChunkGenerator(
790797
prefix,
@@ -800,9 +807,9 @@ private void ParseAddTagHelperDirective(SyntaxListBuilder<RazorSyntaxNode> build
800807
{
801808
var directiveBody = ParseTagHelperDirective(
802809
SyntaxConstants.CSharp.AddTagHelperKeyword,
803-
(lookupText, errors) =>
810+
(lookupText, errors, startLocation) =>
804811
{
805-
var parsedDirective = ParseDirective(lookupText, CurrentStart, TagHelperDirectiveType.AddTagHelper, errors);
812+
var parsedDirective = ParseDirective(lookupText, startLocation, TagHelperDirectiveType.AddTagHelper, errors);
806813

807814
return new AddTagHelperChunkGenerator(
808815
lookupText,
@@ -820,9 +827,9 @@ private void ParseRemoveTagHelperDirective(SyntaxListBuilder<RazorSyntaxNode> bu
820827
{
821828
var directiveBody = ParseTagHelperDirective(
822829
SyntaxConstants.CSharp.RemoveTagHelperKeyword,
823-
(lookupText, errors) =>
830+
(lookupText, errors, startLocation) =>
824831
{
825-
var parsedDirective = ParseDirective(lookupText, CurrentStart, TagHelperDirectiveType.RemoveTagHelper, errors);
832+
var parsedDirective = ParseDirective(lookupText, startLocation, TagHelperDirectiveType.RemoveTagHelper, errors);
826833

827834
return new RemoveTagHelperChunkGenerator(
828835
lookupText,
@@ -838,7 +845,7 @@ private void ParseRemoveTagHelperDirective(SyntaxListBuilder<RazorSyntaxNode> bu
838845

839846
private RazorDirectiveBodySyntax ParseTagHelperDirective(
840847
string keyword,
841-
Func<string, List<RazorDiagnostic>, ISpanChunkGenerator> chunkGeneratorFactory)
848+
Func<string, List<RazorDiagnostic>, SourceLocation, ISpanChunkGenerator> chunkGeneratorFactory)
842849
{
843850
AssertDirective(keyword);
844851

@@ -851,6 +858,7 @@ private RazorDirectiveBodySyntax ParseTagHelperDirective(
851858
Context.ErrorSink = directiveErrorSink;
852859

853860
string directiveValue = null;
861+
SourceLocation? valueStartLocation = null;
854862
try
855863
{
856864
EnsureDirectiveIsAtStartOfLine();
@@ -885,7 +893,7 @@ private RazorDirectiveBodySyntax ParseTagHelperDirective(
885893
else
886894
{
887895
// Need to grab the current location before we accept until the end of the line.
888-
var startLocation = CurrentStart;
896+
valueStartLocation = CurrentStart;
889897

890898
// Parse to the end of the line. Essentially accepts anything until end of line, comments, invalid code
891899
// etc.
@@ -900,15 +908,18 @@ private RazorDirectiveBodySyntax ParseTagHelperDirective(
900908
{
901909
Context.ErrorSink.OnError(
902910
RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
903-
new SourceSpan(startLocation, rawValue.Length), keyword));
911+
new SourceSpan(valueStartLocation.Value, rawValue.Length), keyword));
904912
}
905913

906914
directiveValue = rawValue;
907915
}
908916
}
909917
finally
910918
{
911-
SpanContext.ChunkGenerator = chunkGeneratorFactory(directiveValue, directiveErrorSink.Errors.ToList());
919+
SpanContext.ChunkGenerator = chunkGeneratorFactory(
920+
directiveValue,
921+
directiveErrorSink.Errors.ToList(),
922+
valueStartLocation ?? CurrentStart);
912923
Context.ErrorSink = savedErrorSink;
913924
}
914925

@@ -1234,6 +1245,7 @@ RazorDirectiveSyntax BuildDirective()
12341245
var directiveBody = SyntaxFactory.RazorDirectiveBody(keywordBlock, directiveCodeBlock);
12351246
var directive = SyntaxFactory.RazorDirective(transition, directiveBody);
12361247
directive = (RazorDirectiveSyntax)directive.SetDiagnostics(directiveErrorSink.Errors.ToArray());
1248+
directive = directive.WithDirectiveDescriptor(descriptor);
12371249
return directive;
12381250
}
12391251
}
@@ -1846,7 +1858,7 @@ private void ParseUsingDeclaration(in SyntaxListBuilder<RazorSyntaxNode> builder
18461858

18471859
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.AnyExceptNewline;
18481860
SpanContext.ChunkGenerator = new AddImportChunkGenerator(new LocationTagged<string>(
1849-
string.Concat(TokenBuilder.ToList().Nodes.Select(s => s.Content)),
1861+
string.Concat(TokenBuilder.ToList().Nodes.Skip(1).Select(s => s.Content)),
18501862
start));
18511863

18521864
// Optional ";"
@@ -2058,7 +2070,15 @@ protected override void ParseEmbeddedTransition(in SyntaxListBuilder<RazorSyntax
20582070
{
20592071
// Output tokens before parsing the comment.
20602072
AcceptMarkerTokenIfNecessary();
2061-
builder.Add(OutputTokensAsStatementLiteral());
2073+
if (SpanContext.ChunkGenerator is ExpressionChunkGenerator)
2074+
{
2075+
builder.Add(OutputTokensAsExpressionLiteral());
2076+
}
2077+
else
2078+
{
2079+
builder.Add(OutputTokensAsStatementLiteral());
2080+
}
2081+
20622082
var comment = ParseRazorComment();
20632083
builder.Add(comment);
20642084
}

src/Microsoft.AspNetCore.Razor.Language/Legacy/RazorParser.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Linq;
65

76
namespace Microsoft.AspNetCore.Razor.Language.Legacy
87
{
@@ -25,7 +24,7 @@ public RazorParser(RazorParserOptions options)
2524

2625
public RazorParserOptions Options { get; }
2726

28-
public virtual RazorSyntaxTree Parse(RazorSourceDocument source)
27+
public virtual RazorSyntaxTree Parse(RazorSourceDocument source, bool legacy = false)
2928
{
3029
if (source == null)
3130
{
@@ -39,12 +38,16 @@ public virtual RazorSyntaxTree Parse(RazorSourceDocument source)
3938
codeParser.HtmlParser = markupParser;
4039
markupParser.CodeParser = codeParser;
4140

42-
markupParser.ParseDocument1();
43-
44-
var root = context.Builder.Build();
45-
4641
var diagnostics = context.ErrorSink.Errors;
4742

43+
if (legacy)
44+
{
45+
markupParser.ParseDocument1();
46+
var legacyRoot = context.Builder.Build();
47+
return RazorSyntaxTree.Create(legacyRoot, source, diagnostics, Options);
48+
}
49+
50+
var root = markupParser.ParseDocument().CreateRed();
4851
return RazorSyntaxTree.Create(root, source, diagnostics, Options);
4952
}
5053
}

0 commit comments

Comments
 (0)