From 6cb42ff3814a474bb41b782d48959ffbf905f8e6 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Mon, 29 Sep 2014 17:35:17 -0700 Subject: [PATCH] Add @addtaghelper directive. - Also added some infrastructure pieces for it such as the ITagHelperDescriptorResolver and the default implementation TagHelperDescriptorResolver which will be filled out in a later commit. - Reworked some extensibility points to allow accessibility of the descriptor resolvers per offline discussions. #111 --- .../CodeBuilder/CSharp/CSharpCodeBuilder.cs | 2 +- .../CSharpDesignTimeHelpersVisitor.cs | 40 ++++++++++++- .../Compiler/CodeBuilder/ChunkVisitor.cs | 5 ++ .../Compiler/CodeBuilder/CodeVisitor.cs | 3 + .../Chunks/TagHelpers/AddTagHelperChunk.cs | 16 +++++ .../Compiler/CodeTree/CodeTreeBuilder.cs | 8 +++ .../TagHelpers/AddTagHelperCodeGenerator.cs | 42 +++++++++++++ .../Parser/CSharpCodeParser.Directives.cs | 59 +++++++++++++++++++ .../Parser/RazorParser.cs | 30 ++++------ .../Parser/SyntaxConstants.cs | 1 + .../TagHelperRegistrationVisitor.cs | 49 +++++++++++++++ .../Properties/RazorResources.Designer.cs | 32 ++++++++++ src/Microsoft.AspNet.Razor/RazorEngineHost.cs | 7 +++ .../RazorResources.resx | 6 ++ .../RazorTemplateEngine.cs | 8 ++- .../ITagHelperDescriptorResolver.cs | 14 +++++ .../TagHelpers/TagHelperDescriptorResolver.cs | 18 ++++++ 17 files changed, 317 insertions(+), 23 deletions(-) create mode 100644 src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/Chunks/TagHelpers/AddTagHelperChunk.cs create mode 100644 src/Microsoft.AspNet.Razor/Generator/TagHelpers/AddTagHelperCodeGenerator.cs create mode 100644 src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperRegistrationVisitor.cs create mode 100644 src/Microsoft.AspNet.Razor/TagHelpers/ITagHelperDescriptorResolver.cs create mode 100644 src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorResolver.cs diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeBuilder.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeBuilder.cs index 3cb2ee5cc..4556ac2f1 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeBuilder.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeBuilder.cs @@ -56,7 +56,7 @@ public override CodeBuilderResult Build() new CSharpHelperVisitor(csharpCodeVisitor, writer, Context).Accept(Tree.Chunks); new CSharpTypeMemberVisitor(csharpCodeVisitor, writer, Context).Accept(Tree.Chunks); - new CSharpDesignTimeHelpersVisitor(writer, Context).AcceptTree(Tree); + new CSharpDesignTimeHelpersVisitor(csharpCodeVisitor, writer, Context).AcceptTree(Tree); new CSharpTagHelperFieldDeclarationVisitor(writer, Context).Accept(Tree.Chunks); BuildConstructor(writer); diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpDesignTimeHelpersVisitor.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpDesignTimeHelpersVisitor.cs index 358aa28a8..c65a1b9f2 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpDesignTimeHelpersVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpDesignTimeHelpersVisitor.cs @@ -1,17 +1,31 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Diagnostics; +using System.Globalization; + namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { public class CSharpDesignTimeHelpersVisitor : CodeVisitor { + private const string TagHelperDirectiveSyntaxHelper = "__tagHelperDirectiveSyntaxHelper"; internal const string InheritsHelper = "__inheritsHelper"; internal const string DesignTimeHelperMethodName = "__RazorDesignTimeHelpers__"; + private static readonly string ObjectTypeString = typeof(object).ToString(); private const int DisableVariableNamingWarnings = 219; - public CSharpDesignTimeHelpersVisitor(CSharpCodeWriter writer, CodeBuilderContext context) - : base(writer, context) { } + private CSharpCodeVisitor _csharpCodeVisitor; + private bool _initializedTagHelperDirectiveSyntaxHelper; + + public CSharpDesignTimeHelpersVisitor([NotNull] CSharpCodeVisitor csharpCodeVisitor, + [NotNull] CSharpCodeWriter writer, + [NotNull] CodeBuilderContext context) + + : base(writer, context) + { + _csharpCodeVisitor = csharpCodeVisitor; + } public void AcceptTree(CodeTree tree) { @@ -43,5 +57,27 @@ protected override void Visit(SetBaseTypeChunk chunk) } } } + + protected override void Visit(AddTagHelperChunk chunk) + { + // We should always be in design time mode because of the calling AcceptTree method verification. + Debug.Assert(Context.Host.DesignTimeMode); + + if (!_initializedTagHelperDirectiveSyntaxHelper) + { + _initializedTagHelperDirectiveSyntaxHelper = true; + Writer.WriteVariableDeclaration(ObjectTypeString, TagHelperDirectiveSyntaxHelper, "null"); + } + + Writer.WriteStartAssignment(TagHelperDirectiveSyntaxHelper); + + _csharpCodeVisitor.CreateExpressionCodeMapping( + string.Format( + CultureInfo.InvariantCulture, + "\"{0}\"", chunk.LookupText), + chunk); + + Writer.WriteLine(";"); + } } } diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/ChunkVisitor.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/ChunkVisitor.cs index 4d2a9389f..6d655453f 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/ChunkVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/ChunkVisitor.cs @@ -57,6 +57,10 @@ public virtual void Accept(Chunk chunk) { Visit((TagHelperChunk)chunk); } + else if(chunk is AddTagHelperChunk) + { + Visit((AddTagHelperChunk)chunk); + } else if(chunk is SetLayoutChunk) { Visit((SetLayoutChunk)chunk); @@ -115,6 +119,7 @@ public virtual void Accept(Chunk chunk) protected abstract void Visit(ExpressionChunk chunk); protected abstract void Visit(StatementChunk chunk); protected abstract void Visit(TagHelperChunk chunk); + protected abstract void Visit(AddTagHelperChunk chunk); protected abstract void Visit(UsingChunk chunk); protected abstract void Visit(ChunkBlock chunk); protected abstract void Visit(DynamicCodeAttributeChunk chunk); diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CodeVisitor.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CodeVisitor.cs index 5e964489c..618524f25 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CodeVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CodeVisitor.cs @@ -32,6 +32,9 @@ protected override void Visit(DynamicCodeAttributeChunk chunk) protected override void Visit(TagHelperChunk chunk) { } + protected override void Visit(AddTagHelperChunk chunk) + { + } protected override void Visit(LiteralCodeAttributeChunk chunk) { } diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/Chunks/TagHelpers/AddTagHelperChunk.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/Chunks/TagHelpers/AddTagHelperChunk.cs new file mode 100644 index 000000000..54d02c424 --- /dev/null +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/Chunks/TagHelpers/AddTagHelperChunk.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Razor.Generator.Compiler +{ + /// + /// A that is used to lookup s. + /// + public class AddTagHelperChunk : Chunk + { + /// + /// Arbitrary text used to lookup s. + /// + public string LookupText { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/CodeTreeBuilder.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/CodeTreeBuilder.cs index 1dcb51a21..0a0d92093 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/CodeTreeBuilder.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeTree/CodeTreeBuilder.cs @@ -39,6 +39,14 @@ public void AddChunk(Chunk chunk, SyntaxTreeNode association, bool topLevel = fa } } + public void AddAddTagHelperChunk(string lookupText, SyntaxTreeNode association) + { + AddChunk(new AddTagHelperChunk + { + LookupText = lookupText + }, association); + } + public void AddLiteralChunk(string literal, SyntaxTreeNode association) { // If the previous chunk was also a LiteralChunk, append the content of the current node to the previous one. diff --git a/src/Microsoft.AspNet.Razor/Generator/TagHelpers/AddTagHelperCodeGenerator.cs b/src/Microsoft.AspNet.Razor/Generator/TagHelpers/AddTagHelperCodeGenerator.cs new file mode 100644 index 000000000..be48f3089 --- /dev/null +++ b/src/Microsoft.AspNet.Razor/Generator/TagHelpers/AddTagHelperCodeGenerator.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Razor.Parser.SyntaxTree; + +namespace Microsoft.AspNet.Razor.Generator +{ + /// + /// A that is responsible for generating s. + /// + public class AddTagHelperCodeGenerator : SpanCodeGenerator + { + /// + /// Instantiates a new . + /// + /// + /// Arbitrary text used to lookup s. + /// + public AddTagHelperCodeGenerator(string lookupText) + { + LookupText = lookupText; + } + + /// + /// Arbitrary text used to lookup s. + /// + public string LookupText { get; private set; } + + /// + /// Generates a . + /// + /// + /// The responsible for this . + /// + /// A instance that contains information about + /// the current code generation process. + public override void GenerateCode(Span target, CodeGeneratorContext context) + { + context.CodeTreeBuilder.AddAddTagHelperChunk(LookupText, target); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.Directives.cs b/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.Directives.cs index 5fba093cc..bf5da2ba6 100644 --- a/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.Directives.cs +++ b/src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.Directives.cs @@ -19,6 +19,7 @@ public partial class CSharpCodeParser { private void SetupDirectives() { + MapDirectives(AddTagHelperDirective, SyntaxConstants.CSharp.AddTagHelper); MapDirectives(InheritsDirective, SyntaxConstants.CSharp.InheritsKeyword); MapDirectives(FunctionsDirective, SyntaxConstants.CSharp.FunctionsKeyword); MapDirectives(SectionDirective, SyntaxConstants.CSharp.SectionKeyword); @@ -27,6 +28,14 @@ private void SetupDirectives() MapDirectives(SessionStateDirective, SyntaxConstants.CSharp.SessionStateKeyword); } + protected virtual void AddTagHelperDirective() + { + TagHelperDirective(SyntaxConstants.CSharp.AddTagHelper, (lookupText) => + { + return new AddTagHelperCodeGenerator(lookupText); + }); + } + protected virtual void LayoutDirective() { AssertDirective(SyntaxConstants.CSharp.LayoutKeyword); @@ -498,5 +507,55 @@ protected void BaseTypeDirective(string noTypeNameError, Func codeGeneratorBuilder) + { + AssertDirective(keyword); + + // Accept the directive name + AcceptAndMoveNext(); + + // Set the block type + Context.CurrentBlock.Type = BlockType.Directive; + + var foundWhitespace = At(CSharpSymbolType.WhiteSpace); + AcceptWhile(CSharpSymbolType.WhiteSpace); + // If we found whitespace then any content placed within the whitespace MAY cause a destructive change + // to the document. We can't accept it. + Output(SpanKind.MetaCode, foundWhitespace ? AcceptedCharacters.None : AcceptedCharacters.Any); + + if (EndOfFile || At(CSharpSymbolType.NewLine)) + { + Context.OnError(CurrentLocation, RazorResources.FormatParseError_DirectiveMustHaveValue(keyword)); + } + else + { + // Need to grab the current location before we accept until the end of the line. + var startLocation = CurrentLocation; + + // Parse to the end of the line + AcceptUntil(CSharpSymbolType.NewLine); + + // Pull out the value minus the spaces at the end + var rawValue = Span.GetContent().Value.TrimEnd(); + + // We expect the directive to be surrounded in quotes. + if (!rawValue.StartsWith("\"", StringComparison.OrdinalIgnoreCase) || + !rawValue.EndsWith("\"", StringComparison.OrdinalIgnoreCase)) + { + Context.OnError(startLocation, + RazorResources.FormatParseError_DirectiveMustBeSurroundedByQuotes(keyword)); + } + else + { + // Set up code generation + Span.CodeGenerator = codeGeneratorBuilder(rawValue.Trim('"')); + } + } + + // Output the span and finish the block + CompleteBlock(); + Output(SpanKind.Code); + } } } diff --git a/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs b/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs index 8d1a42d58..55a794e68 100644 --- a/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs +++ b/src/Microsoft.AspNet.Razor/Parser/RazorParser.cs @@ -17,25 +17,16 @@ namespace Microsoft.AspNet.Razor.Parser { public class RazorParser { - public RazorParser(ParserBase codeParser, ParserBase markupParser) - { - if (codeParser == null) - { - throw new ArgumentNullException("codeParser"); - } - if (markupParser == null) - { - throw new ArgumentNullException("markupParser"); - } + private ITagHelperDescriptorResolver _tagHelperDescriptorResolver; + public RazorParser([NotNull] ITagHelperDescriptorResolver tagHelperDescriptorResolver, + [NotNull] ParserBase codeParser, + [NotNull] ParserBase markupParser) + { + _tagHelperDescriptorResolver = tagHelperDescriptorResolver; MarkupParser = markupParser; CodeParser = codeParser; - // TODO: As part of https://github.com/aspnet/Razor/issues/111 and - // https://github.com/aspnet/Razor/issues/112 pull the provider from some sort of tag helper locator - // object. - var provider = new TagHelperDescriptorProvider(Enumerable.Empty()); - Optimizers = new List() { // TODO: Modify the below WhiteSpaceRewriter & ConditionalAttributeCollapser to handle @@ -45,8 +36,6 @@ public RazorParser(ParserBase codeParser, ParserBase markupParser) new WhiteSpaceRewriter(MarkupParser.BuildSpan), // Collapse conditional attributes where the entire value is literal new ConditionalAttributeCollapser(MarkupParser.BuildSpan), - // Enables tag helpers - new TagHelperParseTreeRewriter(provider), }; } @@ -153,6 +142,13 @@ private ParserResults ParseCore(ITextDocument input) current = rewriter.Rewrite(current); } + var tagHelperRegistrationVisitor = new TagHelperRegistrationVisitor(_tagHelperDescriptorResolver); + var tagHelperProvider = tagHelperRegistrationVisitor.CreateProvider(current); + + var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(tagHelperProvider); + // Rewrite the document to utilize tag helpers + current = tagHelperParseTreeRewriter.Rewrite(current); + // Link the leaf nodes into a chain Span prev = null; foreach (Span node in current.Flatten()) diff --git a/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs b/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs index 3f879e704..67b6580ba 100644 --- a/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs +++ b/src/Microsoft.AspNet.Razor/Parser/SyntaxConstants.cs @@ -18,6 +18,7 @@ public static class SyntaxConstants public static class CSharp { public static readonly int UsingKeywordLength = 5; + public static readonly string AddTagHelper = "addtaghelper"; public static readonly string InheritsKeyword = "inherits"; public static readonly string FunctionsKeyword = "functions"; public static readonly string SectionKeyword = "section"; diff --git a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperRegistrationVisitor.cs b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperRegistrationVisitor.cs new file mode 100644 index 000000000..0b28d34ba --- /dev/null +++ b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperRegistrationVisitor.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNet.Razor.Generator; +using Microsoft.AspNet.Razor.Parser.SyntaxTree; +using Microsoft.AspNet.Razor.TagHelpers; + +namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal +{ + public class TagHelperRegistrationVisitor : ParserVisitor + { + private HashSet _descriptors; + private ITagHelperDescriptorResolver _descriptorResolver; + + public TagHelperRegistrationVisitor(ITagHelperDescriptorResolver descriptorResolver) + { + _descriptorResolver = descriptorResolver; + } + + public TagHelperDescriptorProvider CreateProvider(Block root) + { + _descriptors = new HashSet(TagHelperDescriptorComparer.Default); + + // This will recurse through the syntax tree. + VisitBlock(root); + + return new TagHelperDescriptorProvider(_descriptors); + } + + public override void VisitSpan(Span span) + { + // We're only interested in spans with AddTagHelperCodeGenerator's. + if (span.CodeGenerator is AddTagHelperCodeGenerator) + { + var addGenerator = (AddTagHelperCodeGenerator)span.CodeGenerator; + + // Lookup all the descriptors associated with the "LookupText". + var descriptors = _descriptorResolver.Resolve(addGenerator.LookupText); + + // Add all the found descriptors to our HashSet. Duplicates are handled by the HashSet. + foreach (var descriptor in descriptors) + { + _descriptors.Add(descriptor); + } + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs b/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs index 34467e11d..ad2a6af7a 100644 --- a/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs +++ b/src/Microsoft.AspNet.Razor/Properties/RazorResources.Designer.cs @@ -1494,6 +1494,38 @@ internal static string FormatTagHelpers_AttributesThatAreNotStringsMustNotContai return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpers_AttributesThatAreNotStringsMustNotContainAtSymbols"), p0); } + /// + /// Directive '{0}' must have a value. + /// + internal static string ParseError_DirectiveMustHaveValue + { + get { return GetString("ParseError_DirectiveMustHaveValue"); } + } + + /// + /// Directive '{0}' must have a value. + /// + internal static string FormatParseError_DirectiveMustHaveValue(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("ParseError_DirectiveMustHaveValue"), p0); + } + + /// + /// Directive '{0}'s value must be surrounded in double quotes. + /// + internal static string ParseError_DirectiveMustBeSurroundedByQuotes + { + get { return GetString("ParseError_DirectiveMustBeSurroundedByQuotes"); } + } + + /// + /// Directive '{0}'s value must be surrounded in double quotes. + /// + internal static string FormatParseError_DirectiveMustBeSurroundedByQuotes(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("ParseError_DirectiveMustBeSurroundedByQuotes"), p0); + } + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNet.Razor/RazorEngineHost.cs b/src/Microsoft.AspNet.Razor/RazorEngineHost.cs index 39d4edcdb..ca38205e8 100644 --- a/src/Microsoft.AspNet.Razor/RazorEngineHost.cs +++ b/src/Microsoft.AspNet.Razor/RazorEngineHost.cs @@ -8,6 +8,7 @@ using Microsoft.AspNet.Razor.Generator.Compiler; using Microsoft.AspNet.Razor.Generator.Compiler.CSharp; using Microsoft.AspNet.Razor.Parser; +using Microsoft.AspNet.Razor.TagHelpers; namespace Microsoft.AspNet.Razor { @@ -160,6 +161,12 @@ public virtual ParserBase CreateMarkupParser() return null; } + // TODO: Document this as part of https://github.com/aspnet/Razor/issues/99 + public virtual ITagHelperDescriptorResolver CreateTagHelperDescriptorResolver() + { + return new TagHelperDescriptorResolver(); + } + /// /// Gets an instance of the code parser and is provided an opportunity to decorate or replace it /// diff --git a/src/Microsoft.AspNet.Razor/RazorResources.resx b/src/Microsoft.AspNet.Razor/RazorResources.resx index 6fafd8e7b..e45435b9c 100644 --- a/src/Microsoft.AspNet.Razor/RazorResources.resx +++ b/src/Microsoft.AspNet.Razor/RazorResources.resx @@ -415,4 +415,10 @@ Instead, wrap the contents of the block in "{{}}": TagHelper attributes that do not expect strings must not have @ symbols within them. Found attribute '{0}' with an invalid value. + + Directive '{0}' must have a value. + + + Directive '{0}'s value must be surrounded in double quotes. + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/RazorTemplateEngine.cs b/src/Microsoft.AspNet.Razor/RazorTemplateEngine.cs index 20e1654e8..91040a0e7 100644 --- a/src/Microsoft.AspNet.Razor/RazorTemplateEngine.cs +++ b/src/Microsoft.AspNet.Razor/RazorTemplateEngine.cs @@ -269,10 +269,12 @@ protected internal virtual RazorCodeGenerator CreateCodeGenerator(string classNa protected internal virtual RazorParser CreateParser() { - ParserBase codeParser = Host.CodeLanguage.CreateCodeParser(); - ParserBase markupParser = Host.CreateMarkupParser(); + var codeParser = Host.CodeLanguage.CreateCodeParser(); + var markupParser = Host.CreateMarkupParser(); + var tagHelperDescriptorResolver = Host.CreateTagHelperDescriptorResolver(); - return new RazorParser(Host.DecorateCodeParser(codeParser), + return new RazorParser(tagHelperDescriptorResolver, + Host.DecorateCodeParser(codeParser), Host.DecorateMarkupParser(markupParser)) { DesignTimeMode = Host.DesignTimeMode diff --git a/src/Microsoft.AspNet.Razor/TagHelpers/ITagHelperDescriptorResolver.cs b/src/Microsoft.AspNet.Razor/TagHelpers/ITagHelperDescriptorResolver.cs new file mode 100644 index 000000000..a479278f0 --- /dev/null +++ b/src/Microsoft.AspNet.Razor/TagHelpers/ITagHelperDescriptorResolver.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.Razor.TagHelpers +{ + // TODO: Document this class as part of https://github.com/aspnet/Razor/issues/99 + + public interface ITagHelperDescriptorResolver + { + IEnumerable Resolve(string lookupText); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorResolver.cs b/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorResolver.cs new file mode 100644 index 000000000..9b8f5901c --- /dev/null +++ b/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorResolver.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.AspNet.Razor.TagHelpers +{ + // TODO: Implement this class as part of https://github.com/aspnet/Razor/issues/99 + + public class TagHelperDescriptorResolver : ITagHelperDescriptorResolver + { + public IEnumerable Resolve(string lookupText) + { + return Enumerable.Empty(); + } + } +} \ No newline at end of file