Modify functions, section and inherits to use extensible directives.
- Removed existing type names used to track `@functions`, `@section` and `@inherits`. - Updated parsing logic to reflect existing directive behaviors. - Added additional IR and syntax tree pass in order to fulfill the default directive expectations. - Updated tests to to expect new extensible directives parse structure. #894
This commit is contained in:
parent
1b3863044d
commit
2db4985c21
|
|
@ -0,0 +1,61 @@
|
|||
// 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;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
internal class DefaultDirectiveIRPass : IRazorIRPass
|
||||
{
|
||||
public RazorEngine Engine { get; set; }
|
||||
|
||||
public int Order => 150;
|
||||
|
||||
public DocumentIRNode Execute(RazorCodeDocument codeDocument, DocumentIRNode irDocument)
|
||||
{
|
||||
var walker = new DirectiveWalker();
|
||||
walker.VisitDefault(irDocument);
|
||||
|
||||
return irDocument;
|
||||
}
|
||||
|
||||
private class DirectiveWalker : RazorIRNodeWalker
|
||||
{
|
||||
private ClassDeclarationIRNode _classNode;
|
||||
|
||||
public override void VisitClass(ClassDeclarationIRNode node)
|
||||
{
|
||||
if (_classNode == null)
|
||||
{
|
||||
_classNode = node;
|
||||
}
|
||||
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
public override void VisitDirective(DirectiveIRNode node)
|
||||
{
|
||||
if (string.Equals(node.Name, CSharpCodeParser.FunctionsDirectiveDescriptor.Name, StringComparison.Ordinal))
|
||||
{
|
||||
foreach (var child in node.Children.Except(node.Tokens))
|
||||
{
|
||||
child.Parent = _classNode;
|
||||
_classNode.Children.Add(child);
|
||||
}
|
||||
}
|
||||
else if (string.Equals(node.Name, CSharpCodeParser.InheritsDirectiveDescriptor.Name, StringComparison.Ordinal))
|
||||
{
|
||||
var token = node.Tokens.FirstOrDefault();
|
||||
|
||||
if (token != null)
|
||||
{
|
||||
_classNode.BaseType = token.Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// 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.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
internal class DefaultDirectiveSyntaxTreePass : IRazorSyntaxTreePass
|
||||
{
|
||||
public RazorEngine Engine { get; set; }
|
||||
|
||||
public int Order => 75;
|
||||
|
||||
public RazorSyntaxTree Execute(RazorCodeDocument codeDocument, RazorSyntaxTree syntaxTree)
|
||||
{
|
||||
var errorSink = new ErrorSink();
|
||||
var sectionVerifier = new NestedSectionVerifier();
|
||||
sectionVerifier.Verify(syntaxTree, errorSink);
|
||||
|
||||
if (errorSink.Errors.Count > 0)
|
||||
{
|
||||
var combinedErrors = syntaxTree.Diagnostics.Concat(errorSink.Errors).ToList();
|
||||
syntaxTree = RazorSyntaxTree.Create(syntaxTree.Root, combinedErrors, syntaxTree.Options);
|
||||
}
|
||||
|
||||
return syntaxTree;
|
||||
}
|
||||
|
||||
private class NestedSectionVerifier : ParserVisitor
|
||||
{
|
||||
private int _nestedLevel;
|
||||
private ErrorSink _errorSink;
|
||||
|
||||
public void Verify(RazorSyntaxTree tree, ErrorSink errorSink)
|
||||
{
|
||||
_errorSink = errorSink;
|
||||
tree.Root.Accept(this);
|
||||
}
|
||||
|
||||
public override void VisitStartDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
if (_nestedLevel > 0)
|
||||
{
|
||||
var directiveStart = block.Children.First(child => !child.IsBlock && ((Span)child).Kind == SpanKind.Transition).Start;
|
||||
var errorLength = /* @ */ 1 + CSharpCodeParser.SectionDirectiveDescriptor.Name.Length;
|
||||
_errorSink.OnError(
|
||||
directiveStart,
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
errorLength);
|
||||
}
|
||||
|
||||
_nestedLevel++;
|
||||
}
|
||||
|
||||
public override void VisitEndDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
_nestedLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -153,18 +153,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
});
|
||||
}
|
||||
|
||||
public override void VisitTypeMemberSpan(TypeMemberChunkGenerator chunkGenerator, Span span)
|
||||
{
|
||||
var functionsNode = new CSharpStatementIRNode()
|
||||
{
|
||||
Content = span.Content,
|
||||
SourceRange = new MappingLocation(span.Start, span.Length),
|
||||
Parent = Class,
|
||||
};
|
||||
|
||||
Class.Children.Add(functionsNode);
|
||||
}
|
||||
|
||||
public override void VisitStatementSpan(StatementChunkGenerator chunkGenerator, Span span)
|
||||
{
|
||||
Builder.Add(new CSharpStatementIRNode()
|
||||
|
|
|
|||
|
|
@ -14,6 +14,30 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
private static readonly Func<CSharpSymbol, bool> IsValidStatementSpacingSymbol =
|
||||
IsSpacingToken(includeNewLines: true, includeComments: true);
|
||||
|
||||
internal static readonly DirectiveDescriptor SectionDirectiveDescriptor =
|
||||
DirectiveDescriptorBuilder
|
||||
.CreateRazorBlock(SyntaxConstants.CSharp.SectionKeyword)
|
||||
.AddMember()
|
||||
.Build();
|
||||
|
||||
internal static readonly DirectiveDescriptor FunctionsDirectiveDescriptor =
|
||||
DirectiveDescriptorBuilder
|
||||
.CreateCodeBlock(SyntaxConstants.CSharp.FunctionsKeyword)
|
||||
.Build();
|
||||
|
||||
internal static readonly DirectiveDescriptor InheritsDirectiveDescriptor =
|
||||
DirectiveDescriptorBuilder
|
||||
.Create(SyntaxConstants.CSharp.InheritsKeyword)
|
||||
.AddType()
|
||||
.Build();
|
||||
|
||||
internal static readonly IEnumerable<DirectiveDescriptor> DefaultDirectiveDescriptors = new[]
|
||||
{
|
||||
SectionDirectiveDescriptor,
|
||||
FunctionsDirectiveDescriptor,
|
||||
InheritsDirectiveDescriptor,
|
||||
};
|
||||
|
||||
internal static ISet<string> DefaultKeywords = new HashSet<string>()
|
||||
{
|
||||
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
|
||||
|
|
@ -35,6 +59,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
"class",
|
||||
};
|
||||
|
||||
private readonly ISet<string> CurrentKeywords = new HashSet<string>(DefaultKeywords);
|
||||
|
||||
private Dictionary<string, Action> _directiveParsers = new Dictionary<string, Action>(StringComparer.Ordinal);
|
||||
private Dictionary<CSharpKeyword, Action<bool>> _keywordParsers = new Dictionary<CSharpKeyword, Action<bool>>();
|
||||
|
||||
|
|
@ -263,7 +289,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Span.ChunkGenerator = new ExpressionChunkGenerator();
|
||||
Span.EditHandler = new ImplicitExpressionEditHandler(
|
||||
Language.TokenizeString,
|
||||
DefaultKeywords,
|
||||
CurrentKeywords,
|
||||
acceptTrailingDot: IsNested)
|
||||
{
|
||||
AcceptedCharacters = AcceptedCharacters.NonWhiteSpace
|
||||
|
|
@ -611,7 +637,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
|
||||
private void SectionBlock(string left, string right, bool caseSensitive)
|
||||
{
|
||||
ParseWithOtherParser(p => p.ParseSection(Tuple.Create(left, right), caseSensitive));
|
||||
ParseWithOtherParser(p => p.ParseRazorBlock(Tuple.Create(left, right), caseSensitive));
|
||||
}
|
||||
|
||||
private void NestedBlock()
|
||||
|
|
@ -1411,17 +1437,18 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
|
||||
private void SetupDirectives(IEnumerable<DirectiveDescriptor> directiveDescriptors)
|
||||
{
|
||||
foreach (var directiveDescriptor in directiveDescriptors)
|
||||
var allDirectives = directiveDescriptors.Concat(DefaultDirectiveDescriptors).ToList();
|
||||
|
||||
for (var i = 0; i < allDirectives.Count; i++)
|
||||
{
|
||||
var directiveDescriptor = allDirectives[i];
|
||||
CurrentKeywords.Add(directiveDescriptor.Name);
|
||||
MapDirectives(() => HandleDirective(directiveDescriptor), directiveDescriptor.Name);
|
||||
}
|
||||
|
||||
MapDirectives(TagHelperPrefixDirective, SyntaxConstants.CSharp.TagHelperPrefixKeyword);
|
||||
MapDirectives(AddTagHelperDirective, SyntaxConstants.CSharp.AddTagHelperKeyword);
|
||||
MapDirectives(RemoveTagHelperDirective, SyntaxConstants.CSharp.RemoveTagHelperKeyword);
|
||||
MapDirectives(InheritsDirective, SyntaxConstants.CSharp.InheritsKeyword);
|
||||
MapDirectives(FunctionsDirective, SyntaxConstants.CSharp.FunctionsKeyword);
|
||||
MapDirectives(SectionDirective, SyntaxConstants.CSharp.SectionKeyword);
|
||||
}
|
||||
|
||||
private void HandleDirective(DirectiveDescriptor descriptor)
|
||||
|
|
@ -1449,14 +1476,27 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Output(SpanKind.Markup, AcceptedCharacters.WhiteSpace);
|
||||
}
|
||||
|
||||
if (EndOfFile)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
CurrentLocation,
|
||||
LegacyResources.FormatUnexpectedEOFAfterDirective(descriptor.Name, tokenDescriptor.Kind.ToString().ToLowerInvariant()),
|
||||
length: 1);
|
||||
return;
|
||||
}
|
||||
|
||||
var outputKind = SpanKind.Markup;
|
||||
switch (tokenDescriptor.Kind)
|
||||
{
|
||||
case DirectiveTokenKind.Type:
|
||||
if (!NamespaceOrTypeName())
|
||||
{
|
||||
// Error logged for invalid type name, continue onto next piece.
|
||||
continue;
|
||||
Context.ErrorSink.OnError(
|
||||
CurrentLocation,
|
||||
LegacyResources.FormatDirectiveExpectsTypeName(descriptor.Name),
|
||||
CurrentSymbol.Content.Length);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
outputKind = SpanKind.Code;
|
||||
|
|
@ -1520,10 +1560,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
CurrentSymbol.Content.Length);
|
||||
}
|
||||
|
||||
Output(SpanKind.Markup, AcceptedCharacters.AllWhiteSpace);
|
||||
Output(SpanKind.Markup, AcceptedCharacters.WhiteSpace);
|
||||
break;
|
||||
case DirectiveDescriptorKind.RazorBlock:
|
||||
Output(SpanKind.Markup, AcceptedCharacters.WhiteSpace);
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true));
|
||||
Output(SpanKind.Markup, AcceptedCharacters.AllWhiteSpace);
|
||||
|
||||
ParseDirectiveBlock(descriptor, parseChildren: (startingBraceLocation) =>
|
||||
{
|
||||
|
|
@ -1534,7 +1575,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
IsNested = false;
|
||||
using (PushSpanConfig())
|
||||
{
|
||||
HtmlParser.ParseSection(Tuple.Create("{", "}"), caseSensitive: true);
|
||||
HtmlParser.ParseRazorBlock(Tuple.Create("{", "}"), caseSensitive: true);
|
||||
}
|
||||
Initialize(Span);
|
||||
IsNested = wasNested;
|
||||
|
|
@ -1542,7 +1583,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
});
|
||||
break;
|
||||
case DirectiveDescriptorKind.CodeBlock:
|
||||
Output(SpanKind.Markup, AcceptedCharacters.WhiteSpace);
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: true));
|
||||
Output(SpanKind.Markup, AcceptedCharacters.AllWhiteSpace);
|
||||
|
||||
ParseDirectiveBlock(descriptor, parseChildren: (startingBraceLocation) =>
|
||||
{
|
||||
|
|
@ -1588,7 +1630,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
editHandler.AutoCompleteString = "}";
|
||||
Context.ErrorSink.OnError(
|
||||
startingBraceLocation,
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(descriptor.Name, "{", "}"),
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(descriptor.Name, "}", "{"),
|
||||
length: 1 /* } */);
|
||||
}
|
||||
else
|
||||
|
|
@ -1622,186 +1664,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
lookupText => new RemoveTagHelperChunkGenerator(lookupText));
|
||||
}
|
||||
|
||||
protected virtual void SectionDirective()
|
||||
{
|
||||
var nested = Context.Builder.ActiveBlocks.Any(block => block.Type == BlockType.Section);
|
||||
var errorReported = false;
|
||||
|
||||
// Set the block and span type
|
||||
Context.Builder.CurrentBlock.Type = BlockType.Section;
|
||||
|
||||
// Verify we're on "section" and accept
|
||||
AssertDirective(SyntaxConstants.CSharp.SectionKeyword);
|
||||
var startLocation = CurrentLocation;
|
||||
AcceptAndMoveNext();
|
||||
|
||||
if (nested)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
startLocation,
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
Span.GetContent().Value.Length);
|
||||
errorReported = true;
|
||||
}
|
||||
|
||||
var whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));
|
||||
|
||||
// Get the section name
|
||||
var sectionName = string.Empty;
|
||||
if (!Required(CSharpSymbolType.Identifier,
|
||||
errorIfNotFound: true,
|
||||
errorBase: LegacyResources.FormatParseError_Unexpected_Character_At_Section_Name_Start))
|
||||
{
|
||||
if (!errorReported)
|
||||
{
|
||||
errorReported = true;
|
||||
}
|
||||
|
||||
PutCurrentBack();
|
||||
PutBack(whitespace);
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
|
||||
}
|
||||
else
|
||||
{
|
||||
Accept(whitespace);
|
||||
sectionName = CurrentSymbol.Content;
|
||||
AcceptAndMoveNext();
|
||||
}
|
||||
Context.Builder.CurrentBlock.ChunkGenerator = new SectionChunkGenerator(sectionName);
|
||||
|
||||
var errorLocation = CurrentLocation;
|
||||
whitespace = ReadWhile(IsSpacingToken(includeNewLines: true, includeComments: false));
|
||||
|
||||
// Get the starting brace
|
||||
var sawStartingBrace = At(CSharpSymbolType.LeftBrace);
|
||||
if (!sawStartingBrace)
|
||||
{
|
||||
if (!errorReported)
|
||||
{
|
||||
errorReported = true;
|
||||
Context.ErrorSink.OnError(
|
||||
errorLocation,
|
||||
LegacyResources.ParseError_MissingOpenBraceAfterSection,
|
||||
length: 1 /* { */);
|
||||
}
|
||||
|
||||
PutCurrentBack();
|
||||
PutBack(whitespace);
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: false, includeComments: false));
|
||||
Optional(CSharpSymbolType.NewLine);
|
||||
Output(SpanKind.MetaCode);
|
||||
CompleteBlock();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Accept(whitespace);
|
||||
}
|
||||
|
||||
var startingBraceLocation = CurrentLocation;
|
||||
|
||||
// Set up edit handler
|
||||
var editHandler = new AutoCompleteEditHandler(Language.TokenizeString, autoCompleteAtEndOfSpan: true);
|
||||
|
||||
Span.EditHandler = editHandler;
|
||||
Span.Accept(CurrentSymbol);
|
||||
|
||||
// Output Metacode then switch to section parser
|
||||
Output(SpanKind.MetaCode);
|
||||
SectionBlock("{", "}", caseSensitive: true);
|
||||
|
||||
Span.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
// Check for the terminating "}"
|
||||
if (!Optional(CSharpSymbolType.RightBrace))
|
||||
{
|
||||
editHandler.AutoCompleteString = "}";
|
||||
Context.ErrorSink.OnError(
|
||||
startingBraceLocation,
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(
|
||||
SyntaxConstants.CSharp.SectionKeyword,
|
||||
Language.GetSample(CSharpSymbolType.RightBrace),
|
||||
Language.GetSample(CSharpSymbolType.LeftBrace)),
|
||||
length: 1 /* } */);
|
||||
}
|
||||
else
|
||||
{
|
||||
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
|
||||
}
|
||||
CompleteBlock(insertMarkerIfNecessary: false, captureWhitespaceToEndOfLine: true);
|
||||
Output(SpanKind.MetaCode);
|
||||
return;
|
||||
}
|
||||
|
||||
protected virtual void FunctionsDirective()
|
||||
{
|
||||
// Set the block type
|
||||
Context.Builder.CurrentBlock.Type = BlockType.Functions;
|
||||
|
||||
// Verify we're on "functions" and accept
|
||||
AssertDirective(SyntaxConstants.CSharp.FunctionsKeyword);
|
||||
var block = new Block(CurrentSymbol);
|
||||
AcceptAndMoveNext();
|
||||
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: true, includeComments: false));
|
||||
|
||||
if (!At(CSharpSymbolType.LeftBrace))
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
CurrentLocation,
|
||||
LegacyResources.FormatParseError_Expected_X(Language.GetSample(CSharpSymbolType.LeftBrace)),
|
||||
length: 1 /* { */);
|
||||
CompleteBlock();
|
||||
Output(SpanKind.MetaCode);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
|
||||
}
|
||||
|
||||
// Capture start point and continue
|
||||
var blockStart = CurrentLocation;
|
||||
AcceptAndMoveNext();
|
||||
|
||||
// Output what we've seen and continue
|
||||
Output(SpanKind.MetaCode);
|
||||
|
||||
var editHandler = new AutoCompleteEditHandler(Language.TokenizeString);
|
||||
Span.EditHandler = editHandler;
|
||||
|
||||
Balance(BalancingModes.NoErrorOnFailure, CSharpSymbolType.LeftBrace, CSharpSymbolType.RightBrace, blockStart);
|
||||
Span.ChunkGenerator = new TypeMemberChunkGenerator();
|
||||
if (!At(CSharpSymbolType.RightBrace))
|
||||
{
|
||||
editHandler.AutoCompleteString = "}";
|
||||
Context.ErrorSink.OnError(
|
||||
blockStart,
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(block.Name, "}", "{"),
|
||||
length: 1 /* } */);
|
||||
CompleteBlock();
|
||||
Output(SpanKind.Code);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output(SpanKind.Code);
|
||||
Assert(CSharpSymbolType.RightBrace);
|
||||
Span.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
|
||||
AcceptAndMoveNext();
|
||||
CompleteBlock();
|
||||
Output(SpanKind.MetaCode);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void InheritsDirective()
|
||||
{
|
||||
// Verify we're on the right keyword and accept
|
||||
AssertDirective(SyntaxConstants.CSharp.InheritsKeyword);
|
||||
AcceptAndMoveNext();
|
||||
|
||||
InheritsDirectiveCore();
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
protected void AssertDirective(string directive)
|
||||
{
|
||||
|
|
@ -1809,13 +1671,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Debug.Assert(string.Equals(CurrentSymbol.Content, directive, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
protected void InheritsDirectiveCore()
|
||||
{
|
||||
BaseTypeDirective(
|
||||
LegacyResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName,
|
||||
baseType => new SetBaseTypeChunkGenerator(baseType));
|
||||
}
|
||||
|
||||
protected void BaseTypeDirective(string noTypeNameError, Func<string, SpanChunkGenerator> createChunkGenerator)
|
||||
{
|
||||
var keywordStartLocation = Span.Start;
|
||||
|
|
|
|||
|
|
@ -1577,7 +1577,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
return false;
|
||||
}
|
||||
|
||||
public void ParseSection(Tuple<string, string> nestingSequences, bool caseSensitive)
|
||||
public void ParseRazorBlock(Tuple<string, string> nestingSequences, bool caseSensitive)
|
||||
{
|
||||
if (Context == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,10 +69,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void VisitTypeMemberSpan(TypeMemberChunkGenerator chunkGenerator, Span span)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void VisitMarkupSpan(MarkupChunkGenerator chunkGenerator, Span span)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class SectionChunkGenerator : ParentChunkGenerator
|
||||
{
|
||||
public SectionChunkGenerator(string sectionName)
|
||||
{
|
||||
SectionName = sectionName;
|
||||
}
|
||||
|
||||
public string SectionName { get; }
|
||||
|
||||
public override void AcceptStart(ParserVisitor visitor, Block block)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AcceptEnd(ParserVisitor visitor, Block block)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
|
||||
{
|
||||
//var chunk = context.ChunkTreeBuilder.StartParentChunk<SectionChunk>(target);
|
||||
|
||||
//chunk.Name = SectionName;
|
||||
}
|
||||
|
||||
public override void GenerateEndParentChunk(Block target, ChunkGeneratorContext context)
|
||||
{
|
||||
//context.ChunkTreeBuilder.EndParentChunk();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as SectionChunkGenerator;
|
||||
return base.Equals(other) &&
|
||||
string.Equals(SectionName, other.SectionName, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return SectionName == null ? 0 : StringComparer.Ordinal.GetHashCode(SectionName);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Section:" + SectionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class SetBaseTypeChunkGenerator : SpanChunkGenerator
|
||||
{
|
||||
public SetBaseTypeChunkGenerator(string baseType)
|
||||
{
|
||||
BaseType = baseType;
|
||||
}
|
||||
|
||||
public string BaseType { get; }
|
||||
|
||||
public override void Accept(ParserVisitor visitor, Span span)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GenerateChunk(Span target, ChunkGeneratorContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Base:" + BaseType;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as SetBaseTypeChunkGenerator;
|
||||
return other != null &&
|
||||
string.Equals(BaseType, other.BaseType, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return BaseType.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class TypeMemberChunkGenerator : SpanChunkGenerator
|
||||
{
|
||||
public override void GenerateChunk(Span target, ChunkGeneratorContext context)
|
||||
{
|
||||
//context.ChunkTreeBuilder.AddTypeMemberChunk(target.Content, target);
|
||||
}
|
||||
|
||||
public override void Accept(ParserVisitor visitor, Span span)
|
||||
{
|
||||
visitor.VisitTypeMemberSpan(this, span);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "TypeMember";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -182,6 +182,9 @@
|
|||
<data name="DirectiveExpectsIdentifier" xml:space="preserve">
|
||||
<value>The '{0}' directive expects an identifier.</value>
|
||||
</data>
|
||||
<data name="DirectiveExpectsTypeName" xml:space="preserve">
|
||||
<value>The '{0}' directive expects a type name.</value>
|
||||
</data>
|
||||
<data name="EndBlock_Called_Without_Matching_StartBlock" xml:space="preserve">
|
||||
<value>"EndBlock" was called without a matching call to "StartBlock".</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -346,6 +346,22 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("DirectiveExpectsIdentifier"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The '{0}' directive expects a type name.
|
||||
/// </summary>
|
||||
internal static string DirectiveExpectsTypeName
|
||||
{
|
||||
get { return GetString("DirectiveExpectsTypeName"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The '{0}' directive expects a type name.
|
||||
/// </summary>
|
||||
internal static string FormatDirectiveExpectsTypeName(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("DirectiveExpectsTypeName"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// "EndBlock" was called without a matching call to "StartBlock".
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -35,8 +35,13 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
builder.Phases.Add(new DefaultRazorIRLoweringPhase());
|
||||
builder.Phases.Add(new DefaultRazorIRPhase());
|
||||
|
||||
// Syntax Tree passes
|
||||
builder.Features.Add(new DefaultDirectiveSyntaxTreePass());
|
||||
builder.Features.Add(new TagHelperBinderSyntaxTreePass());
|
||||
builder.Features.Add(new HtmlNodeOptimizationPass());
|
||||
|
||||
// IR Passes
|
||||
builder.Features.Add(new DefaultDirectiveIRPass());
|
||||
}
|
||||
|
||||
public abstract IReadOnlyList<IRazorEngineFeature> Features { get; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
// 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 Microsoft.AspNetCore.Razor.Evolution.Intermediate;
|
||||
using Xunit;
|
||||
using static Microsoft.AspNetCore.Razor.Evolution.Intermediate.RazorIRAssert;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
public class DefaultDirectiveIRPassTest
|
||||
{
|
||||
[Fact]
|
||||
public void Execute_MutatesIRDocument()
|
||||
{
|
||||
// Arrange
|
||||
var content =
|
||||
@"@inherits Hello<World[]>
|
||||
@functions {
|
||||
var value = true;
|
||||
}";
|
||||
var originalIRDocument = Lower(content);
|
||||
var pass = new DefaultDirectiveIRPass();
|
||||
|
||||
// Act
|
||||
var irDocument = pass.Execute(codeDocument: null, irDocument: originalIRDocument);
|
||||
|
||||
// Assert
|
||||
Assert.Same(originalIRDocument, irDocument);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_Inherits_SetsClassDeclarationBaseType()
|
||||
{
|
||||
// Arrange
|
||||
var content = "@inherits Hello<World[]>";
|
||||
var originalIRDocument = Lower(content);
|
||||
var pass = new DefaultDirectiveIRPass();
|
||||
|
||||
// Act
|
||||
var irDocument = pass.Execute(codeDocument: null, irDocument: originalIRDocument);
|
||||
|
||||
// Assert
|
||||
var @namespace = SingleChild<NamespaceDeclarationIRNode>(irDocument);
|
||||
var @class = SingleChild<ClassDeclarationIRNode>(@namespace);
|
||||
Assert.Equal(@class.BaseType, "Hello<World[]>");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_Functions_ExistsAtClassDeclarationAndMethodLevel()
|
||||
{
|
||||
// Arrange
|
||||
var content = "@functions { var value = true; }";
|
||||
var originalIRDocument = Lower(content);
|
||||
var pass = new DefaultDirectiveIRPass();
|
||||
|
||||
// Act
|
||||
var irDocument = pass.Execute(codeDocument: null, irDocument: originalIRDocument);
|
||||
|
||||
// Assert
|
||||
var @namespace = SingleChild<NamespaceDeclarationIRNode>(irDocument);
|
||||
var @class = SingleChild<ClassDeclarationIRNode>(@namespace);
|
||||
Children(@class,
|
||||
node => Assert.IsType<RazorMethodDeclarationIRNode>(node),
|
||||
node => CSharpStatement(" var value = true; ", node));
|
||||
var method = (RazorMethodDeclarationIRNode)@class.Children[0];
|
||||
Children(method,
|
||||
node => Html(string.Empty, node),
|
||||
node => Directive("functions", node,
|
||||
directiveChild => CSharpStatement(" var value = true; ", directiveChild)),
|
||||
node => Html(string.Empty, node));
|
||||
}
|
||||
|
||||
private static DocumentIRNode Lower(string content)
|
||||
{
|
||||
var sourceDocument = TestRazorSourceDocument.Create(content);
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var engine = RazorEngine.Create();
|
||||
|
||||
for (var i = 0; i < engine.Phases.Count; i++)
|
||||
{
|
||||
var phase = engine.Phases[i];
|
||||
phase.Execute(codeDocument);
|
||||
|
||||
if (phase is IRazorIRLoweringPhase)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var irDocument = codeDocument.GetIRDocument();
|
||||
Assert.NotNull(irDocument);
|
||||
return irDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
// 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 Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
public class DefaultDirectiveSyntaxTreePassTest
|
||||
{
|
||||
[Fact]
|
||||
public void Execute_DoesNotRecreateSyntaxTreeWhenNoErrors()
|
||||
{
|
||||
// Arrange
|
||||
var engine = RazorEngine.Create();
|
||||
var pass = new DefaultDirectiveSyntaxTreePass()
|
||||
{
|
||||
Engine = engine,
|
||||
};
|
||||
var content =
|
||||
@"
|
||||
@section Foo {
|
||||
}";
|
||||
var sourceDocument = TestRazorSourceDocument.Create(content);
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var originalTree = RazorSyntaxTree.Parse(sourceDocument);
|
||||
|
||||
// Act
|
||||
var outputTree = pass.Execute(codeDocument, originalTree);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(originalTree.Diagnostics);
|
||||
Assert.Same(originalTree, outputTree);
|
||||
Assert.Empty(outputTree.Diagnostics);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_LogsErrorsForNestedSections()
|
||||
{
|
||||
// Arrange
|
||||
var expectedErrors = new[] {
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
new SourceLocation(22, 2, 4),
|
||||
length: 8),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
new SourceLocation(49, 4, 4),
|
||||
length: 8),
|
||||
};
|
||||
var engine = RazorEngine.Create();
|
||||
var pass = new DefaultDirectiveSyntaxTreePass()
|
||||
{
|
||||
Engine = engine,
|
||||
};
|
||||
var content =
|
||||
@"
|
||||
@section Foo {
|
||||
@section Bar {
|
||||
}
|
||||
@section Baz {
|
||||
}
|
||||
}";
|
||||
var sourceDocument = TestRazorSourceDocument.Create(content);
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var originalTree = RazorSyntaxTree.Parse(sourceDocument);
|
||||
|
||||
// Act
|
||||
var outputTree = pass.Execute(codeDocument, originalTree);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(originalTree.Diagnostics);
|
||||
Assert.NotSame(originalTree, outputTree);
|
||||
Assert.Equal(expectedErrors, outputTree.Diagnostics);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_CombinesErrorsWhenNestedSections()
|
||||
{
|
||||
// Arrange
|
||||
var expectedErrors = new[] {
|
||||
new RazorError("Test Error", SourceLocation.Zero, 3),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
new SourceLocation(22, 2, 4),
|
||||
length: 8),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
new SourceLocation(49, 4, 4),
|
||||
length: 8),
|
||||
};
|
||||
var engine = RazorEngine.Create();
|
||||
var pass = new DefaultDirectiveSyntaxTreePass()
|
||||
{
|
||||
Engine = engine,
|
||||
};
|
||||
var content =
|
||||
@"
|
||||
@section Foo {
|
||||
@section Bar {
|
||||
}
|
||||
@section Baz {
|
||||
}
|
||||
}";
|
||||
var sourceDocument = TestRazorSourceDocument.Create(content);
|
||||
var codeDocument = RazorCodeDocument.Create(sourceDocument);
|
||||
var originalTree = RazorSyntaxTree.Parse(sourceDocument);
|
||||
var erroredOriginalTree = RazorSyntaxTree.Create(originalTree.Root, new[] { expectedErrors[0] }, originalTree.Options);
|
||||
|
||||
// Act
|
||||
var outputTree = pass.Execute(codeDocument, erroredOriginalTree);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(originalTree.Diagnostics);
|
||||
Assert.NotSame(originalTree, outputTree);
|
||||
Assert.Equal(expectedErrors, outputTree.Diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
var phase = engine.Phases[i];
|
||||
phase.Execute(codeDocument);
|
||||
|
||||
if (phase is IRazorIRLoweringPhase)
|
||||
if (phase is IRazorIRPhase)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,34 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
}
|
||||
}
|
||||
|
||||
public static void CSharpStatement(string expected, RazorIRNode node)
|
||||
{
|
||||
try
|
||||
{
|
||||
var statement = Assert.IsType<CSharpStatementIRNode>(node);
|
||||
Assert.Equal(expected, statement.Content);
|
||||
}
|
||||
catch (XunitException e)
|
||||
{
|
||||
throw new IRAssertException(node, node.Children, e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Directive(string expectedName, RazorIRNode node, params Action<RazorIRNode>[] childValidators)
|
||||
{
|
||||
try
|
||||
{
|
||||
var directive = Assert.IsType<DirectiveIRNode>(node);
|
||||
Assert.Equal(expectedName, directive.Name);
|
||||
}
|
||||
catch (XunitException e)
|
||||
{
|
||||
throw new IRAssertException(node, node.Children, e.Message, e);
|
||||
}
|
||||
|
||||
Children(node, childValidators);
|
||||
}
|
||||
|
||||
public static void Using(string expected, RazorIRNode node)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -47,26 +47,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
}
|
||||
}
|
||||
|
||||
internal class FunctionsBlock : Block
|
||||
{
|
||||
private const BlockType ThisBlockType = BlockType.Functions;
|
||||
|
||||
public FunctionsBlock(IParentChunkGenerator chunkGenerator, IReadOnlyList<SyntaxTreeNode> children)
|
||||
: base(ThisBlockType, children, chunkGenerator)
|
||||
{
|
||||
}
|
||||
|
||||
public FunctionsBlock(IParentChunkGenerator chunkGenerator, params SyntaxTreeNode[] children)
|
||||
: this(chunkGenerator, (IReadOnlyList<SyntaxTreeNode>)children)
|
||||
{
|
||||
}
|
||||
|
||||
public FunctionsBlock(params SyntaxTreeNode[] children)
|
||||
: this(ParentChunkGenerator.Null, children)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal class ExpressionBlock : Block
|
||||
{
|
||||
private const BlockType ThisBlockType = BlockType.Expression;
|
||||
|
|
@ -188,31 +168,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
}
|
||||
}
|
||||
|
||||
internal class SectionBlock : Block
|
||||
{
|
||||
private const BlockType ThisBlockType = BlockType.Section;
|
||||
|
||||
public SectionBlock(IParentChunkGenerator chunkGenerator, IReadOnlyList<SyntaxTreeNode> children)
|
||||
: base(ThisBlockType, children, chunkGenerator)
|
||||
{
|
||||
}
|
||||
|
||||
public SectionBlock(IParentChunkGenerator chunkGenerator, params SyntaxTreeNode[] children)
|
||||
: this(chunkGenerator, (IReadOnlyList<SyntaxTreeNode>)children)
|
||||
{
|
||||
}
|
||||
|
||||
public SectionBlock(params SyntaxTreeNode[] children)
|
||||
: this(ParentChunkGenerator.Null, children)
|
||||
{
|
||||
}
|
||||
|
||||
public SectionBlock(IReadOnlyList<SyntaxTreeNode> children)
|
||||
: this(ParentChunkGenerator.Null, children)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal class TemplateBlock : Block
|
||||
{
|
||||
private const BlockType ThisBlockType = BlockType.Template;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
|
|
@ -13,19 +14,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
{
|
||||
ParseBlockTest(
|
||||
"@functions{",
|
||||
new FunctionsBlock(
|
||||
Factory.CodeTransition("@")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.MetaCode("functions{")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.EmptyCSharp()
|
||||
.AsFunctionsBody()
|
||||
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)
|
||||
{
|
||||
AutoCompleteString = "}"
|
||||
})),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None)),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(CSharpCodeParser.FunctionsDirectiveDescriptor.Name, "}", "{"),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
}
|
||||
|
|
@ -34,12 +28,17 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
public void SectionDirectiveAutoCompleteAtEOF()
|
||||
{
|
||||
ParseBlockTest("@section Header {",
|
||||
new SectionBlock(new SectionChunkGenerator("Header"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Header {")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true)
|
||||
.Accepts(AcceptedCharacters.Any),
|
||||
new MarkupBlock()),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Header", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml())),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("section", "}", "{"),
|
||||
new SourceLocation(16, 0, 16),
|
||||
|
|
@ -67,23 +66,16 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
[Fact]
|
||||
public void FunctionsDirectiveAutoCompleteAtStartOfFile()
|
||||
{
|
||||
ParseBlockTest("@functions{" + Environment.NewLine
|
||||
+ "foo",
|
||||
new FunctionsBlock(
|
||||
Factory.CodeTransition("@")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.MetaCode("functions{")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(Environment.NewLine + "foo")
|
||||
.AsFunctionsBody()
|
||||
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)
|
||||
{
|
||||
AutoCompleteString = "}"
|
||||
})),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
ParseBlockTest("@functions{" + Environment.NewLine + "foo",
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(Environment.NewLine + "foo").AsStatement()),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -91,11 +83,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
{
|
||||
ParseBlockTest("@section Header {" + Environment.NewLine
|
||||
+ "<p>Foo</p>",
|
||||
new SectionBlock(new SectionChunkGenerator("Header"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Header {")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true)
|
||||
.Accepts(AcceptedCharacters.Any),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Header", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine),
|
||||
new MarkupTagBlock(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
|
|
@ -148,7 +149,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Factory.Span(SpanKind.Markup, "Header", markup: false)
|
||||
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true)
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
|
|
@ -181,7 +182,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Factory.Span(SpanKind.Markup, "Name", markup: false)
|
||||
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true)
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
|
|
@ -218,7 +219,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
.Accepts(AcceptedCharacters.NonWhiteSpace),
|
||||
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false)
|
||||
.Accepts(AcceptedCharacters.AllWhiteSpace)));
|
||||
.Accepts(AcceptedCharacters.WhiteSpace)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -288,7 +289,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace),
|
||||
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace)),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace)),
|
||||
expectedErorr);
|
||||
}
|
||||
|
||||
|
|
@ -315,7 +316,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace),
|
||||
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace)),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace)),
|
||||
expectedErorr);
|
||||
}
|
||||
|
||||
|
|
@ -350,7 +351,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
// Arrange
|
||||
var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build();
|
||||
var expectedErorr = new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("custom", "{", "}"),
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("custom", "}", "{"),
|
||||
new SourceLocation(14, 0, 14),
|
||||
length: 1);
|
||||
|
||||
|
|
@ -366,7 +367,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Factory.Span(SpanKind.Markup, "Hello", markup: false)
|
||||
.With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0]))
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true)
|
||||
.Accepts(AcceptedCharacters.None)),
|
||||
|
|
@ -682,101 +683,93 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
public void InheritsDirective()
|
||||
{
|
||||
ParseBlockTest("@inherits System.Web.WebPages.WebPage",
|
||||
new DirectiveBlock(
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("System.Web.WebPages.WebPage")
|
||||
.AsBaseType("System.Web.WebPages.WebPage")));
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "System.Web.WebPages.WebPage", markup: false)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InheritsDirectiveSupportsArrays()
|
||||
{
|
||||
ParseBlockTest("@inherits string[[]][]",
|
||||
new DirectiveBlock(
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("string[[]][]")
|
||||
.AsBaseType("string[[]][]")));
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "string[[]][]", markup: false)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InheritsDirectiveSupportsNestedGenerics()
|
||||
{
|
||||
ParseBlockTest("@inherits System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>",
|
||||
new DirectiveBlock(
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>")
|
||||
.AsBaseType("System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>")));
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>", markup: false)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InheritsDirectiveSupportsTypeKeywords()
|
||||
{
|
||||
ParseBlockTest("@inherits string",
|
||||
new DirectiveBlock(
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("string")
|
||||
.AsBaseType("string")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InheritsDirectiveSupportsVSTemplateTokens()
|
||||
{
|
||||
ParseBlockTest("@inherits $rootnamespace$.MyBase",
|
||||
new DirectiveBlock(
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("$rootnamespace$.MyBase")
|
||||
.AsBaseType("$rootnamespace$.MyBase")));
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "string", markup: false)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FunctionsDirective()
|
||||
{
|
||||
ParseBlockTest("@functions { foo(); bar(); }",
|
||||
new FunctionsBlock(
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.FunctionsKeyword + " {")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" foo(); bar(); ")
|
||||
.AsFunctionsBody()
|
||||
.AutoCompleteWith(autoCompleteString: null),
|
||||
Factory.MetaCode("}")
|
||||
.Accepts(AcceptedCharacters.None)));
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" foo(); bar(); ").AsStatement(),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyFunctionsDirective()
|
||||
{
|
||||
ParseBlockTest("@functions { }",
|
||||
new FunctionsBlock(
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.FunctionsKeyword + " {")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" ")
|
||||
.AsFunctionsBody()
|
||||
.AutoCompleteWith(autoCompleteString: null),
|
||||
Factory.MetaCode("}")
|
||||
.Accepts(AcceptedCharacters.None)));
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" ").AsStatement(),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SectionDirective()
|
||||
{
|
||||
ParseBlockTest("@section Header { <p>F{o}o</p> }",
|
||||
new SectionBlock(new SectionChunkGenerator("Header"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Header {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true)
|
||||
.Accepts(AcceptedCharacters.Any),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Header", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
|
|||
|
|
@ -299,15 +299,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
public void ParseBlockReportsErrorIfClassBlockUnterminatedAtEOF()
|
||||
{
|
||||
ParseBlockTest("functions { var foo = bar; if(foo != null) { bar(); } ",
|
||||
new FunctionsBlock(
|
||||
Factory.MetaCode("functions {").Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" var foo = bar; if(foo != null) { bar(); } ")
|
||||
.AsFunctionsBody()
|
||||
.AutoCompleteWith("}")),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", '}', '{'),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" var foo = bar; if(foo != null) { bar(); } ").AsStatement()),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", '}', '{'),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
|
|
@ -14,49 +15,52 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section" + Environment.NewLine,
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator(string.Empty),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section" + Environment.NewLine))),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None)),
|
||||
Factory.Markup(Environment.NewLine)),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Unexpected_Character_At_Section_Name_Start(
|
||||
LegacyResources.ErrorComponent_EndOfFile),
|
||||
new SourceLocation(8 + Environment.NewLine.Length, 1, 0),
|
||||
length: 1));
|
||||
LegacyResources.FormatDirectiveExpectsIdentifier(CSharpCodeParser.SectionDirectiveDescriptor.Name),
|
||||
new SourceLocation(8, 0, 8),
|
||||
length: Environment.NewLine.Length));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseSectionBlockCapturesWhitespaceToEndOfLineInSectionStatementMissingOpenBrace()
|
||||
{
|
||||
ParseDocumentTest("@section Foo " + Environment.NewLine
|
||||
+ " ",
|
||||
ParseDocumentTest("@section Foo " + Environment.NewLine + " ",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo " + Environment.NewLine)),
|
||||
Factory.Markup(" ")),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " " + Environment.NewLine + " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace)),
|
||||
Factory.EmptyHtml()),
|
||||
new RazorError(
|
||||
LegacyResources.ParseError_MissingOpenBraceAfterSection,
|
||||
new SourceLocation(12, 0, 12),
|
||||
LegacyResources.FormatUnexpectedEOFAfterDirective(CSharpCodeParser.SectionDirectiveDescriptor.Name, "{"),
|
||||
new SourceLocation(25 + Environment.NewLine.Length, 0, 25 + Environment.NewLine.Length),
|
||||
length: 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseSectionBlockCapturesWhitespaceToEndOfLineInSectionStatementMissingName()
|
||||
{
|
||||
ParseDocumentTest("@section " + Environment.NewLine
|
||||
+ " ",
|
||||
ParseDocumentTest("@section " + Environment.NewLine + " ",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator(string.Empty),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section " + Environment.NewLine)),
|
||||
Factory.Markup(" ")),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace)),
|
||||
Factory.Markup(Environment.NewLine + " ")),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Unexpected_Character_At_Section_Name_Start(
|
||||
LegacyResources.ErrorComponent_EndOfFile),
|
||||
new SourceLocation(21 + Environment.NewLine.Length, 1, 4),
|
||||
length: 1));
|
||||
LegacyResources.FormatDirectiveExpectsIdentifier(CSharpCodeParser.SectionDirectiveDescriptor.Name),
|
||||
new SourceLocation(17, 0, 17),
|
||||
length: Environment.NewLine.Length));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -79,19 +83,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section 9 { <p>Foo</p> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator(string.Empty),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section ")),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace)),
|
||||
Factory.Markup("9 { "),
|
||||
new MarkupTagBlock(
|
||||
Factory.Markup("<p>")),
|
||||
Factory.Markup("Foo"),
|
||||
new MarkupTagBlock(
|
||||
Factory.Markup("</p>")),
|
||||
Factory.Markup(" }")),
|
||||
Factory.Markup(" }")),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Unexpected_Character_At_Section_Name_Start(
|
||||
LegacyResources.FormatErrorComponent_Character("9")),
|
||||
LegacyResources.FormatDirectiveExpectsIdentifier(CSharpCodeParser.SectionDirectiveDescriptor.Name),
|
||||
new SourceLocation(9, 0, 9),
|
||||
length: 1));
|
||||
}
|
||||
|
|
@ -102,9 +106,13 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo-bar { <p>Foo</p> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo")),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First()))),
|
||||
Factory.Markup("-bar { "),
|
||||
new MarkupTagBlock(
|
||||
Factory.Markup("<p>")),
|
||||
|
|
@ -113,7 +121,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Factory.Markup("</p>")),
|
||||
Factory.Markup(" }")),
|
||||
new RazorError(
|
||||
LegacyResources.ParseError_MissingOpenBraceAfterSection,
|
||||
LegacyResources.FormatUnexpectedDirectiveLiteral(CSharpCodeParser.SectionDirectiveDescriptor.Name, "{"),
|
||||
new SourceLocation(12, 0, 12),
|
||||
length: 1));
|
||||
}
|
||||
|
|
@ -124,16 +132,26 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo { @section bar { <p>Foo</p> } }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new SectionBlock(new SectionChunkGenerator("bar"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section bar {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "bar", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -148,8 +166,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
Factory.EmptyHtml()),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Sections_Cannot_Be_Nested(LegacyResources.SectionExample_CS),
|
||||
new SourceLocation(16, 0, 16),
|
||||
7));
|
||||
new SourceLocation(15, 0, 15),
|
||||
8));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -158,13 +176,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo {",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true),
|
||||
new MarkupBlock())),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml()))),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("section", "}", "{"),
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF(CSharpCodeParser.SectionDirectiveDescriptor.Name, "}", "{"),
|
||||
new SourceLocation(13, 0, 13),
|
||||
length: 1));
|
||||
}
|
||||
|
|
@ -179,10 +203,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo {" + postStartBrace,
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(postStartBrace)))),
|
||||
new RazorError(
|
||||
|
|
@ -197,10 +226,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo { <p>Foo{}</p>",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -227,10 +261,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
spaces),
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Test"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode($"section Test{newLine}{{")
|
||||
.AutoCompleteWith("}", atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Test", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, Environment.NewLine, CSharpSymbolType.NewLine).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(newLine),
|
||||
new StatementBlock(
|
||||
|
|
@ -256,12 +295,18 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo " + Environment.NewLine,
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo " + Environment.NewLine))),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " " + Environment.NewLine, markup: false).Accepts(AcceptedCharacters.AllWhiteSpace)),
|
||||
Factory.EmptyHtml()),
|
||||
new RazorError(
|
||||
LegacyResources.ParseError_MissingOpenBraceAfterSection,
|
||||
new SourceLocation(12, 0, 12),
|
||||
LegacyResources.FormatUnexpectedEOFAfterDirective(CSharpCodeParser.SectionDirectiveDescriptor.Name, "{"),
|
||||
new SourceLocation(18 + Environment.NewLine.Length, 0, 18 + Environment.NewLine.Length),
|
||||
length: 1));
|
||||
}
|
||||
|
||||
|
|
@ -279,10 +324,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
+ "}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(string.Format("section foo {0}{0}{0}{0}{0}{0}{{", Environment.NewLine))
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " " + string.Format("{0}{0}{0}{0}{0}{0}", Environment.NewLine), markup: false).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -301,10 +351,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo { <p>Foo</p> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -323,10 +378,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo{ <p>Foo</p> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo{")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -345,10 +404,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo { <script>(function foo() { return 1; })();</script> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -367,10 +431,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo { I really want to render a close brace, so here I go: @(\"}\") }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" I really want to render a close brace, so here I go: "),
|
||||
new ExpressionBlock(
|
||||
|
|
@ -392,10 +461,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
+ "}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine),
|
||||
new StatementBlock(
|
||||
|
|
@ -414,10 +488,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
+ "}}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine),
|
||||
new StatementBlock(
|
||||
|
|
@ -434,10 +513,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section foo {something}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup("something")),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
|
||||
|
|
@ -450,10 +534,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section s {<!-- -->}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("s"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section s {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "s", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup("<!-- -->")),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
|
||||
|
|
@ -468,10 +557,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section s {<!-- > \" '-->}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("s"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section s {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "s", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup("<!-- > \" '-->")),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
|
||||
|
|
@ -485,10 +579,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
"@section s {" + Environment.NewLine + "<a" + Environment.NewLine + "<!-- > \" '-->}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("s"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section s {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "s", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -505,10 +604,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
"@section s { <? xml bleh ?>}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("s"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section s {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "s", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" <? xml bleh ?>")),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
|
||||
|
|
@ -527,10 +631,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
"@section s {<span foo='@@' />}",
|
||||
new MarkupBlock(
|
||||
factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("s"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
factory.CodeTransition(),
|
||||
factory.MetaCode("section s {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
factory.Span(SpanKind.Code, "s", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<span"),
|
||||
|
|
@ -549,10 +658,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
"@section s {<span foo='@DateTime.Now @@' />}",
|
||||
new MarkupBlock(
|
||||
factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("s"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
factory.CodeTransition(),
|
||||
factory.MetaCode("section s {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
factory.Span(SpanKind.Code, "s", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<span"),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
|
|
@ -12,36 +13,33 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
public void ParseInheritsStatementMarksInheritsSpanAsCanGrowIfMissingTrailingSpace()
|
||||
{
|
||||
ParseBlockTest("inherits",
|
||||
new DirectiveBlock(
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.Any)
|
||||
),
|
||||
new RazorError(
|
||||
LegacyResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName,
|
||||
new SourceLocation(0, 0, 0), 8));
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None)),
|
||||
new RazorError(
|
||||
LegacyResources.FormatUnexpectedEOFAfterDirective(CSharpCodeParser.InheritsDirectiveDescriptor.Name, "type"),
|
||||
new SourceLocation(8, 0, 8), 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InheritsBlockAcceptsMultipleGenericArguments()
|
||||
{
|
||||
ParseBlockTest("inherits Foo.Bar<Biz<Qux>, string, int>.Baz",
|
||||
new DirectiveBlock(
|
||||
Factory.MetaCode("inherits ").Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("Foo.Bar<Biz<Qux>, string, int>.Baz")
|
||||
.AsBaseType("Foo.Bar<Biz<Qux>, string, int>.Baz")
|
||||
));
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo.Bar<Biz<Qux>, string, int>.Baz", markup: false)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InheritsBlockOutputsErrorIfInheritsNotFollowedByTypeButAcceptsEntireLineAsCode()
|
||||
{
|
||||
ParseBlockTest("inherits " + Environment.NewLine
|
||||
+ "foo",
|
||||
new DirectiveBlock(
|
||||
Factory.MetaCode("inherits ").Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" " + Environment.NewLine)
|
||||
.AsBaseType(string.Empty)
|
||||
),
|
||||
new RazorError(LegacyResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, 0, 0, 0, 8));
|
||||
ParseBlockTest("inherits " + Environment.NewLine + "foo",
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor),
|
||||
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace)),
|
||||
new RazorError(LegacyResources.FormatDirectiveExpectsTypeName(CSharpCodeParser.InheritsDirectiveDescriptor.Name), 24, 0, 24, 2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -143,29 +141,27 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
{
|
||||
const string code = " foo(); \"bar}baz\" ";
|
||||
ParseBlockTest("functions {" + code + "} zoop",
|
||||
new FunctionsBlock(
|
||||
Factory.MetaCode("functions {").Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(code)
|
||||
.AsFunctionsBody()
|
||||
.AutoCompleteWith(autoCompleteString: null),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
|
||||
));
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(code).AsStatement(),
|
||||
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseBlockDoesNoErrorRecoveryForFunctionsBlock()
|
||||
{
|
||||
ParseBlockTest("functions { { { { { } zoop",
|
||||
new FunctionsBlock(
|
||||
Factory.MetaCode("functions {").Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" { { { { } zoop")
|
||||
.AsFunctionsBody()
|
||||
.AutoCompleteWith("}")
|
||||
),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.FunctionsDirectiveDescriptor),
|
||||
Factory.MetaCode("functions").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
Factory.Code(" { { { { } zoop").AsStatement()),
|
||||
new RazorError(
|
||||
LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("functions", "}", "{"),
|
||||
new SourceLocation(10, 0, 10),
|
||||
length: 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
|
|
@ -108,10 +109,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
+ "}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo {")
|
||||
.AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine + " "),
|
||||
BlockFactory.MarkupTagBlock("<html>"),
|
||||
|
|
@ -468,10 +474,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest(@"@section Foo { <script>foo<bar baz='@boz'></script> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo {")
|
||||
.AutoCompleteWith(autoCompleteString: null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
BlockFactory.MarkupTagBlock("<script>"),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
|
|
@ -280,6 +281,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
[Fact]
|
||||
public void SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine()
|
||||
{
|
||||
var sectionDescriptor = CSharpCodeParser.SectionDirectiveDescriptor;
|
||||
ParseDocumentTest("@section foo {" + Environment.NewLine
|
||||
+ " <ul>" + Environment.NewLine
|
||||
+ " @foreach(var p in Products) {" + Environment.NewLine
|
||||
|
|
@ -289,9 +291,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
+ "}",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section foo {").AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(Environment.NewLine + " "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -386,9 +394,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section Foo { <foo>@@bar</foo> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo {").AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
@ -408,9 +422,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
ParseDocumentTest("@section Foo { <foo>@@@@@bar</foo> }",
|
||||
new MarkupBlock(
|
||||
Factory.EmptyHtml(),
|
||||
new SectionBlock(new SectionChunkGenerator("Foo"),
|
||||
new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor),
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode("section Foo {").AutoCompleteWith(null, atEndOfSpan: true),
|
||||
Factory.MetaCode("section").Accepts(AcceptedCharacters.None),
|
||||
Factory.Span(SpanKind.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.WhiteSpace),
|
||||
Factory.Span(SpanKind.Code, "Foo", CSharpSymbolType.Identifier)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace)
|
||||
.With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())),
|
||||
Factory.Span(SpanKind.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharacters.AllWhiteSpace),
|
||||
Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharacters.None),
|
||||
new MarkupBlock(
|
||||
Factory.Markup(" "),
|
||||
new MarkupTagBlock(
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
|
||||
var parser = new RazorParser(options);
|
||||
|
||||
return parser.Parse((ITextDocument)reader);
|
||||
var tree = parser.Parse((ITextDocument)reader);
|
||||
var defaultDirectivePass = new DefaultDirectiveSyntaxTreePass();
|
||||
tree = defaultDirectivePass.Execute(codeDocument: null, syntaxTree: tree);
|
||||
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -313,11 +313,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
.With(new ExpressionChunkGenerator());
|
||||
}
|
||||
|
||||
public SpanConstructor AsFunctionsBody()
|
||||
{
|
||||
return _self.With(new TypeMemberChunkGenerator());
|
||||
}
|
||||
|
||||
public SpanConstructor AsNamespaceImport(string ns)
|
||||
{
|
||||
return _self.With(new AddImportChunkGenerator(ns));
|
||||
|
|
@ -328,13 +323,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
return _self.With(SpanChunkGenerator.Null);
|
||||
}
|
||||
|
||||
public SpanConstructor AsBaseType(string baseType)
|
||||
{
|
||||
return _self
|
||||
.With(new SetBaseTypeChunkGenerator(baseType))
|
||||
.Accepts(AcceptedCharacters.AnyExceptNewline);
|
||||
}
|
||||
|
||||
public SpanConstructor AsAddTagHelper(string lookupText)
|
||||
{
|
||||
return _self
|
||||
|
|
|
|||
|
|
@ -75,8 +75,10 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
{
|
||||
Assert.Collection(
|
||||
features,
|
||||
feature => Assert.IsType<DefaultDirectiveSyntaxTreePass>(feature),
|
||||
feature => Assert.IsType<TagHelperBinderSyntaxTreePass>(feature),
|
||||
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature));
|
||||
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
|
||||
feature => Assert.IsType<DefaultDirectiveIRPass>(feature));
|
||||
}
|
||||
|
||||
private static void AssertDefaultPhases(IReadOnlyList<IRazorEnginePhase> phases)
|
||||
|
|
|
|||
Loading…
Reference in New Issue