Add found TagHelperDescriptors on a Razor page to GeneratorResults.
- Ultimately this enables tooling to inspect what TagHelperDescriptors were found on a document and construct HTML schema based off of them. - Added XML doc on the classes I touched that didn't have docs. - Added [NotNull] to the result construct parameters. - Added tests to validate that TagHelperDescriptors flow when found after parsing a Razor document. #215
This commit is contained in:
parent
06a2f72bb3
commit
cc0d5dd324
|
|
@ -4,43 +4,84 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Razor
|
||||
{
|
||||
/// <summary>
|
||||
/// The results of parsing and generating code for a Razor document.
|
||||
/// </summary>
|
||||
public class GeneratorResults : ParserResults
|
||||
{
|
||||
public GeneratorResults(ParserResults parserResults, CodeBuilderResult codeBuilderResult, CodeTree codeTree)
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="GeneratorResults"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="parserResults">The results of parsing a document.</param>
|
||||
/// <param name="codeBuilderResult">The results of generating code for the document.</param>
|
||||
/// <param name="codeTree">A <see cref="CodeTree"/> for the document.</param>
|
||||
public GeneratorResults([NotNull] ParserResults parserResults,
|
||||
[NotNull] CodeBuilderResult codeBuilderResult,
|
||||
[NotNull] CodeTree codeTree)
|
||||
: this(parserResults.Document,
|
||||
parserResults.TagHelperDescriptors,
|
||||
parserResults.ParserErrors,
|
||||
codeBuilderResult,
|
||||
codeTree)
|
||||
{
|
||||
}
|
||||
|
||||
public GeneratorResults(Block document,
|
||||
IList<RazorError> parserErrors,
|
||||
CodeBuilderResult codeBuilderResult,
|
||||
CodeTree codeTree)
|
||||
: this(parserErrors.Count == 0, document, parserErrors, codeBuilderResult, codeTree)
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="GeneratorResults"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="document">The <see cref="Block"/> for the syntax tree.</param>
|
||||
/// <param name="tagHelperDescriptors"><see cref="TagHelperDescriptor"/>s for the document.</param>
|
||||
/// <param name="parserErrors"><see cref="RazorError"/>s encountered when parsing the document.</param>
|
||||
/// <param name="codeBuilderResult">The results of generating code for the document.</param>
|
||||
/// <param name="codeTree">A <see cref="CodeTree"/> for the document.</param>
|
||||
public GeneratorResults([NotNull] Block document,
|
||||
[NotNull] IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
|
||||
[NotNull] IList<RazorError> parserErrors,
|
||||
[NotNull] CodeBuilderResult codeBuilderResult,
|
||||
[NotNull] CodeTree codeTree)
|
||||
: this(parserErrors.Count == 0, document, tagHelperDescriptors, parserErrors, codeBuilderResult, codeTree)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="GeneratorResults"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="success"><c>true</c> if parsing was successful, <c>false</c> otherwise.</param>
|
||||
/// <param name="document">The <see cref="Block"/> for the syntax tree.</param>
|
||||
/// <param name="tagHelperDescriptors"><see cref="TagHelperDescriptor"/>s for the document.</param>
|
||||
/// <param name="parserErrors"><see cref="RazorError"/>s encountered when parsing the document.</param>
|
||||
/// <param name="codeBuilderResult">The results of generating code for the document.</param>
|
||||
/// <param name="codeTree">A <see cref="CodeTree"/> for the document.</param>
|
||||
protected GeneratorResults(bool success,
|
||||
Block document,
|
||||
IList<RazorError> parserErrors,
|
||||
CodeBuilderResult codeBuilderResult,
|
||||
CodeTree codeTree)
|
||||
: base(success, document, parserErrors)
|
||||
[NotNull] Block document,
|
||||
[NotNull] IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
|
||||
[NotNull] IList<RazorError> parserErrors,
|
||||
[NotNull] CodeBuilderResult codeBuilderResult,
|
||||
[NotNull] CodeTree codeTree)
|
||||
: base(success, document, tagHelperDescriptors, parserErrors)
|
||||
{
|
||||
GeneratedCode = codeBuilderResult.Code;
|
||||
DesignTimeLineMappings = codeBuilderResult.DesignTimeLineMappings;
|
||||
CodeTree = codeTree;
|
||||
}
|
||||
|
||||
public string GeneratedCode { get; private set; }
|
||||
/// <summary>
|
||||
/// The generated code for the document.
|
||||
/// </summary>
|
||||
public string GeneratedCode { get; }
|
||||
|
||||
public IList<LineMapping> DesignTimeLineMappings { get; private set; }
|
||||
/// <summary>
|
||||
/// <see cref="LineMapping"/>s used to project code from a file during design time.
|
||||
/// </summary>
|
||||
public IList<LineMapping> DesignTimeLineMappings { get; }
|
||||
|
||||
public CodeTree CodeTree { get; private set; }
|
||||
/// <summary>
|
||||
/// A <see cref="Generator.Compiler.CodeTree"/> for the document.
|
||||
/// </summary>
|
||||
public CodeTree CodeTree { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Globalization;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
using Microsoft.AspNet.Razor.Utils;
|
||||
|
||||
|
|
@ -225,7 +226,11 @@ namespace Microsoft.AspNet.Razor.Parser
|
|||
throw new InvalidOperationException(RazorResources.ParserContext_CannotCompleteTree_OutstandingBlocks);
|
||||
}
|
||||
|
||||
return new ParserResults(_blockStack.Pop().Build(), _errorSink.Errors.ToList());
|
||||
return new ParserResults(_blockStack.Pop().Build(),
|
||||
// TagHelperDescriptors are not found by default. The RazorParser is responsible
|
||||
// for identifying TagHelperDescriptors and rebuilding ParserResults.
|
||||
tagHelperDescriptors: Enumerable.Empty<TagHelperDescriptor>(),
|
||||
parserErrors: _errorSink.Errors.ToList());
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
|
|
|
|||
|
|
@ -170,9 +170,11 @@ namespace Microsoft.AspNet.Razor.Parser
|
|||
rewriter.Rewrite(rewritingContext);
|
||||
}
|
||||
|
||||
var descriptors = Enumerable.Empty<TagHelperDescriptor>();
|
||||
|
||||
if (TagHelperDescriptorResolver != null)
|
||||
{
|
||||
var descriptors = GetTagHelperDescriptors(rewritingContext.SyntaxTree, rewritingContext.ErrorSink);
|
||||
descriptors = GetTagHelperDescriptors(rewritingContext.SyntaxTree, rewritingContext.ErrorSink);
|
||||
var tagHelperProvider = new TagHelperDescriptorProvider(descriptors);
|
||||
|
||||
var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider);
|
||||
|
|
@ -195,7 +197,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
|||
}
|
||||
|
||||
// Return the new result
|
||||
return new ParserResults(syntaxTree, errorSink.Errors.ToList());
|
||||
return new ParserResults(syntaxTree, descriptors, errorSink.Errors.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Razor
|
||||
{
|
||||
|
|
@ -11,15 +12,38 @@ namespace Microsoft.AspNet.Razor
|
|||
/// </summary>
|
||||
public class ParserResults
|
||||
{
|
||||
public ParserResults(Block document, IList<RazorError> parserErrors)
|
||||
: this(parserErrors == null || parserErrors.Count == 0, document, parserErrors)
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="ParserResults"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="document">The Razor syntax tree.</param>
|
||||
/// <param name="tagHelperDescriptors"><see cref="TagHelperDescriptor"/>s that apply to the current Razor
|
||||
/// document.</param>
|
||||
/// <param name="parserErrors"><see cref="RazorError"/>s encountered when parsing the current Razor
|
||||
/// document.</param>
|
||||
public ParserResults([NotNull] Block document,
|
||||
[NotNull] IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
|
||||
[NotNull] IList<RazorError> parserErrors)
|
||||
: this(parserErrors == null || parserErrors.Count == 0, document, tagHelperDescriptors, parserErrors)
|
||||
{
|
||||
}
|
||||
|
||||
protected ParserResults(bool success, Block document, IList<RazorError> errors)
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="ParserResults"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="success"><c>true</c> if parsing was successful, <c>false</c> otherwise.</param>
|
||||
/// <param name="document">The Razor syntax tree.</param>
|
||||
/// <param name="tagHelperDescriptors"><see cref="TagHelperDescriptor"/>s that apply to the current Razor
|
||||
/// document.</param>
|
||||
/// <param name="errors"><see cref="RazorError"/>s encountered when parsing the current Razor
|
||||
/// document.</param>
|
||||
protected ParserResults(bool success,
|
||||
[NotNull] Block document,
|
||||
[NotNull] IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
|
||||
[NotNull] IList<RazorError> errors)
|
||||
{
|
||||
Success = success;
|
||||
Document = document;
|
||||
TagHelperDescriptors = tagHelperDescriptors;
|
||||
ParserErrors = errors ?? new List<RazorError>();
|
||||
}
|
||||
|
||||
|
|
@ -37,5 +61,10 @@ namespace Microsoft.AspNet.Razor
|
|||
/// The list of errors which occurred during parsing.
|
||||
/// </summary>
|
||||
public IList<RazorError> ParserErrors { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TagHelperDescriptor"/>s found for the current Razor document.
|
||||
/// </summary>
|
||||
public IEnumerable<TagHelperDescriptor> TagHelperDescriptors { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if ASPNETCORE50
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
|
@ -63,6 +64,98 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
}
|
||||
}
|
||||
|
||||
public static TheoryData TagHelperDescriptorFlowTestData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<string, // Test name
|
||||
string, // Baseline name
|
||||
IEnumerable<TagHelperDescriptor>, // TagHelperDescriptors provided
|
||||
IEnumerable<TagHelperDescriptor>, // Expected TagHelperDescriptors
|
||||
bool> // Design time mode.
|
||||
{
|
||||
{
|
||||
"SingleTagHelper",
|
||||
"SingleTagHelper",
|
||||
PAndInputTagHelperDescriptors,
|
||||
PAndInputTagHelperDescriptors,
|
||||
false
|
||||
},
|
||||
{
|
||||
"SingleTagHelper",
|
||||
"SingleTagHelper.DesignTime",
|
||||
PAndInputTagHelperDescriptors,
|
||||
PAndInputTagHelperDescriptors,
|
||||
true
|
||||
},
|
||||
{
|
||||
"BasicTagHelpers",
|
||||
"BasicTagHelpers",
|
||||
PAndInputTagHelperDescriptors,
|
||||
PAndInputTagHelperDescriptors,
|
||||
false
|
||||
},
|
||||
{
|
||||
"BasicTagHelpers",
|
||||
"BasicTagHelpers.DesignTime",
|
||||
PAndInputTagHelperDescriptors,
|
||||
PAndInputTagHelperDescriptors,
|
||||
true
|
||||
},
|
||||
{
|
||||
"BasicTagHelpers.RemoveTagHelper",
|
||||
"BasicTagHelpers.RemoveTagHelper",
|
||||
PAndInputTagHelperDescriptors,
|
||||
Enumerable.Empty<TagHelperDescriptor>(),
|
||||
false
|
||||
},
|
||||
{
|
||||
"ContentBehaviorTagHelpers",
|
||||
"ContentBehaviorTagHelpers",
|
||||
ContentBehaviorTagHelperDescriptors,
|
||||
ContentBehaviorTagHelperDescriptors,
|
||||
false
|
||||
},
|
||||
{
|
||||
"ComplexTagHelpers",
|
||||
"ComplexTagHelpers",
|
||||
PAndInputTagHelperDescriptors,
|
||||
PAndInputTagHelperDescriptors,
|
||||
false
|
||||
},
|
||||
{
|
||||
"ComplexTagHelpers",
|
||||
"ComplexTagHelpers.DesignTime",
|
||||
PAndInputTagHelperDescriptors,
|
||||
PAndInputTagHelperDescriptors,
|
||||
true
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TagHelperDescriptorFlowTestData))]
|
||||
public void TagHelpers_RenderingOutputFlowsFoundTagHelperDescriptors(
|
||||
string testName,
|
||||
string baselineName,
|
||||
IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
|
||||
IEnumerable<TagHelperDescriptor> expectedTagHelperDescriptors,
|
||||
bool designTimeMode)
|
||||
{
|
||||
RunTagHelperTest(
|
||||
testName,
|
||||
baseLineName: baselineName,
|
||||
tagHelperDescriptors: tagHelperDescriptors,
|
||||
onResults: (results) =>
|
||||
{
|
||||
Assert.Equal(expectedTagHelperDescriptors,
|
||||
results.TagHelperDescriptors,
|
||||
TagHelperDescriptorComparer.Default);
|
||||
},
|
||||
designTimeMode: designTimeMode);
|
||||
}
|
||||
|
||||
public static TheoryData DesignTimeTagHelperTestData
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||
using Microsoft.AspNet.Razor.Parser;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Test.Generator
|
||||
{
|
||||
|
|
@ -17,7 +19,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
bool designTimeMode = false,
|
||||
IEnumerable<TagHelperDescriptor> tagHelperDescriptors = null,
|
||||
Func<RazorEngineHost, RazorEngineHost> hostConfig = null,
|
||||
IList<LineMapping> expectedDesignTimePragmas = null)
|
||||
IList<LineMapping> expectedDesignTimePragmas = null,
|
||||
Action<GeneratorResults> onResults = null)
|
||||
{
|
||||
RunTest(name: testName,
|
||||
baselineName: baseLineName,
|
||||
|
|
@ -27,6 +30,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
{
|
||||
return new TagHelperTemplateEngine(engine, tagHelperDescriptors);
|
||||
},
|
||||
onResults: onResults,
|
||||
hostConfig: hostConfig,
|
||||
expectedDesignTimePragmas: expectedDesignTimePragmas);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
#if !ASPNETCORE50
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Razor.Parser;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -17,7 +19,9 @@ namespace Microsoft.AspNet.Razor.Test.Parser
|
|||
public void VisitThrowsOnNullVisitor()
|
||||
{
|
||||
ParserVisitor target = null;
|
||||
var results = new ParserResults(new BlockBuilder() { Type = BlockType.Comment }.Build(), new List<RazorError>());
|
||||
var results = new ParserResults(new BlockBuilder() { Type = BlockType.Comment }.Build(),
|
||||
Enumerable.Empty<TagHelperDescriptor>(),
|
||||
parserErrors: new List<RazorError>());
|
||||
|
||||
Assert.Throws<ArgumentNullException>("self", () => target.Visit(results));
|
||||
}
|
||||
|
|
@ -35,7 +39,9 @@ namespace Microsoft.AspNet.Razor.Test.Parser
|
|||
// Arrange
|
||||
Mock<ParserVisitor> targetMock = new Mock<ParserVisitor>();
|
||||
var root = new BlockBuilder() { Type = BlockType.Comment }.Build();
|
||||
var results = new ParserResults(root, new List<RazorError>());
|
||||
var results = new ParserResults(root,
|
||||
Enumerable.Empty<TagHelperDescriptor>(),
|
||||
parserErrors: new List<RazorError>());
|
||||
|
||||
// Act
|
||||
targetMock.Object.Visit(results);
|
||||
|
|
@ -54,7 +60,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser
|
|||
new RazorError("Foo", 1, 0, 1),
|
||||
new RazorError("Bar", 2, 0, 2)
|
||||
};
|
||||
var results = new ParserResults(root, errors);
|
||||
var results = new ParserResults(root, Enumerable.Empty<TagHelperDescriptor>(), errors);
|
||||
|
||||
// Act
|
||||
targetMock.Object.Visit(results);
|
||||
|
|
@ -74,7 +80,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser
|
|||
new RazorError("Foo", 1, 0, 1),
|
||||
new RazorError("Bar", 2, 0, 2)
|
||||
};
|
||||
var results = new ParserResults(root, errors);
|
||||
var results = new ParserResults(root, Enumerable.Empty<TagHelperDescriptor>(), errors);
|
||||
|
||||
// Act
|
||||
targetMock.Object.Visit(results);
|
||||
|
|
|
|||
Loading…
Reference in New Issue