diff --git a/src/Microsoft.AspNet.Razor/GeneratorResults.cs b/src/Microsoft.AspNet.Razor/GeneratorResults.cs
index 2ea36e30bf..ec02a3f935 100644
--- a/src/Microsoft.AspNet.Razor/GeneratorResults.cs
+++ b/src/Microsoft.AspNet.Razor/GeneratorResults.cs
@@ -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
{
+ ///
+ /// The results of parsing and generating code for a Razor document.
+ ///
public class GeneratorResults : ParserResults
{
- public GeneratorResults(ParserResults parserResults, CodeBuilderResult codeBuilderResult, CodeTree codeTree)
+ ///
+ /// Instantiates a new instance.
+ ///
+ /// The results of parsing a document.
+ /// The results of generating code for the document.
+ /// A for the document.
+ 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 parserErrors,
- CodeBuilderResult codeBuilderResult,
- CodeTree codeTree)
- : this(parserErrors.Count == 0, document, parserErrors, codeBuilderResult, codeTree)
+ ///
+ /// Instantiates a new instance.
+ ///
+ /// The for the syntax tree.
+ /// s for the document.
+ /// s encountered when parsing the document.
+ /// The results of generating code for the document.
+ /// A for the document.
+ public GeneratorResults([NotNull] Block document,
+ [NotNull] IEnumerable tagHelperDescriptors,
+ [NotNull] IList parserErrors,
+ [NotNull] CodeBuilderResult codeBuilderResult,
+ [NotNull] CodeTree codeTree)
+ : this(parserErrors.Count == 0, document, tagHelperDescriptors, parserErrors, codeBuilderResult, codeTree)
{
}
+ ///
+ /// Instantiates a new instance.
+ ///
+ /// true if parsing was successful, false otherwise.
+ /// The for the syntax tree.
+ /// s for the document.
+ /// s encountered when parsing the document.
+ /// The results of generating code for the document.
+ /// A for the document.
protected GeneratorResults(bool success,
- Block document,
- IList parserErrors,
- CodeBuilderResult codeBuilderResult,
- CodeTree codeTree)
- : base(success, document, parserErrors)
+ [NotNull] Block document,
+ [NotNull] IEnumerable tagHelperDescriptors,
+ [NotNull] IList 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; }
+ ///
+ /// The generated code for the document.
+ ///
+ public string GeneratedCode { get; }
- public IList DesignTimeLineMappings { get; private set; }
+ ///
+ /// s used to project code from a file during design time.
+ ///
+ public IList DesignTimeLineMappings { get; }
- public CodeTree CodeTree { get; private set; }
+ ///
+ /// A for the document.
+ ///
+ public CodeTree CodeTree { get; }
}
}
diff --git a/src/Microsoft.AspNet.Razor/Parser/ParserContext.cs b/src/Microsoft.AspNet.Razor/Parser/ParserContext.cs
index cd5d0ce808..fa0a9bbf4b 100644
--- a/src/Microsoft.AspNet.Razor/Parser/ParserContext.cs
+++ b/src/Microsoft.AspNet.Razor/Parser/ParserContext.cs
@@ -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(),
+ parserErrors: _errorSink.Errors.ToList());
}
[Conditional("DEBUG")]
diff --git a/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs b/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs
index 4d2a21d1ec..01a04ed8e3 100644
--- a/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs
+++ b/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs
@@ -170,9 +170,11 @@ namespace Microsoft.AspNet.Razor.Parser
rewriter.Rewrite(rewritingContext);
}
+ var descriptors = Enumerable.Empty();
+
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());
}
///
diff --git a/src/Microsoft.AspNet.Razor/ParserResults.cs b/src/Microsoft.AspNet.Razor/ParserResults.cs
index 19a8f0230e..97df423630 100644
--- a/src/Microsoft.AspNet.Razor/ParserResults.cs
+++ b/src/Microsoft.AspNet.Razor/ParserResults.cs
@@ -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
///
public class ParserResults
{
- public ParserResults(Block document, IList parserErrors)
- : this(parserErrors == null || parserErrors.Count == 0, document, parserErrors)
+ ///
+ /// Instantiates a new instance.
+ ///
+ /// The Razor syntax tree.
+ /// s that apply to the current Razor
+ /// document.
+ /// s encountered when parsing the current Razor
+ /// document.
+ public ParserResults([NotNull] Block document,
+ [NotNull] IEnumerable tagHelperDescriptors,
+ [NotNull] IList parserErrors)
+ : this(parserErrors == null || parserErrors.Count == 0, document, tagHelperDescriptors, parserErrors)
{
}
- protected ParserResults(bool success, Block document, IList errors)
+ ///
+ /// Instantiates a new instance.
+ ///
+ /// true if parsing was successful, false otherwise.
+ /// The Razor syntax tree.
+ /// s that apply to the current Razor
+ /// document.
+ /// s encountered when parsing the current Razor
+ /// document.
+ protected ParserResults(bool success,
+ [NotNull] Block document,
+ [NotNull] IEnumerable tagHelperDescriptors,
+ [NotNull] IList errors)
{
Success = success;
Document = document;
+ TagHelperDescriptors = tagHelperDescriptors;
ParserErrors = errors ?? new List();
}
@@ -37,5 +61,10 @@ namespace Microsoft.AspNet.Razor
/// The list of errors which occurred during parsing.
///
public IList ParserErrors { get; private set; }
+
+ ///
+ /// The s found for the current Razor document.
+ ///
+ public IEnumerable TagHelperDescriptors { get; private set; }
}
}
diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs
index 85dee97c23..ef5c9e36de 100644
--- a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs
@@ -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, // TagHelperDescriptors provided
+ IEnumerable, // 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(),
+ 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 tagHelperDescriptors,
+ IEnumerable 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
diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/TagHelperTestBase.cs b/test/Microsoft.AspNet.Razor.Test/Generator/TagHelperTestBase.cs
index 37cc1214f3..31ac2e2dcd 100644
--- a/test/Microsoft.AspNet.Razor.Test/Generator/TagHelperTestBase.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Generator/TagHelperTestBase.cs
@@ -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 tagHelperDescriptors = null,
Func hostConfig = null,
- IList expectedDesignTimePragmas = null)
+ IList expectedDesignTimePragmas = null,
+ Action 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);
}
diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/ParserVisitorExtensionsTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/ParserVisitorExtensionsTest.cs
index 31535af4a9..264c8be456 100644
--- a/test/Microsoft.AspNet.Razor.Test/Parser/ParserVisitorExtensionsTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Parser/ParserVisitorExtensionsTest.cs
@@ -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());
+ var results = new ParserResults(new BlockBuilder() { Type = BlockType.Comment }.Build(),
+ Enumerable.Empty(),
+ parserErrors: new List());
Assert.Throws("self", () => target.Visit(results));
}
@@ -35,7 +39,9 @@ namespace Microsoft.AspNet.Razor.Test.Parser
// Arrange
Mock targetMock = new Mock();
var root = new BlockBuilder() { Type = BlockType.Comment }.Build();
- var results = new ParserResults(root, new List());
+ var results = new ParserResults(root,
+ Enumerable.Empty(),
+ parserErrors: new List());
// 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(), 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(), errors);
// Act
targetMock.Object.Visit(results);