Quick fixes from MVC
We're close to hooking up new Razor to MVC. This is a set of enabling 'quick fix' changes to resolve some blockers to using Razor.Evolution in the product. Main issues: - Types not public enough - anything in the .Legacy namespace is still slated from 'improvement' - Wrong references. We don't want .Workspaces in MVC, so moving the heavy lifting of TagHelper discovery to CodeAnalysis.Razor.
This commit is contained in:
parent
3d5cfc8b8b
commit
03b63d97a2
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
_namespace.AddAfter<UsingStatementIRNode>(node);
|
||||
}
|
||||
|
||||
internal override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
{
|
||||
_class.Insert(0, node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal override void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
public override void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
{
|
||||
// As a special case the TagHelperIRNode (which must be the parent) is the one that carries
|
||||
// the location. The execute node won't have one, but the instrumentation goes around the call
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
Context.Writer.WriteEndMethodInvocation(endLine: false);
|
||||
}
|
||||
|
||||
internal override void VisitTagHelper(TagHelperIRNode node)
|
||||
public override void VisitTagHelper(TagHelperIRNode node)
|
||||
{
|
||||
var initialTagHelperRenderingContext = Context.TagHelperRenderingContext;
|
||||
Context.TagHelperRenderingContext = new TagHelperRenderingContext();
|
||||
|
|
@ -209,12 +209,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
Context.TagHelperRenderingContext = initialTagHelperRenderingContext;
|
||||
}
|
||||
|
||||
internal override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
public override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal override void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
public override void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
{
|
||||
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
.WriteEndMethodInvocation();
|
||||
}
|
||||
|
||||
internal override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
{
|
||||
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
|
||||
var tagHelperRenderingContext = Context.TagHelperRenderingContext;
|
||||
|
|
@ -312,7 +312,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
}
|
||||
}
|
||||
|
||||
internal override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
{
|
||||
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
Context.Writer.WriteEndMethodInvocation(endLine: false);
|
||||
}
|
||||
|
||||
internal override void VisitTagHelper(TagHelperIRNode node)
|
||||
public override void VisitTagHelper(TagHelperIRNode node)
|
||||
{
|
||||
var initialTagHelperRenderingContext = Context.TagHelperRenderingContext;
|
||||
Context.TagHelperRenderingContext = new TagHelperRenderingContext();
|
||||
|
|
@ -277,7 +277,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
Context.TagHelperRenderingContext = initialTagHelperRenderingContext;
|
||||
}
|
||||
|
||||
internal override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
public override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
{
|
||||
// Call into the tag helper scope manager to start a new tag helper scope.
|
||||
// Also capture the value as the current execution context.
|
||||
|
|
@ -311,7 +311,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
Context.Writer.WriteEndMethodInvocation();
|
||||
}
|
||||
|
||||
internal override void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
public override void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
{
|
||||
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
|
||||
|
||||
|
|
@ -328,7 +328,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
tagHelperVariableName);
|
||||
}
|
||||
|
||||
internal override void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
Context.Writer
|
||||
.WriteStartInstanceMethodInvocation(
|
||||
|
|
@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
.WriteEndMethodInvocation();
|
||||
}
|
||||
|
||||
internal override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
var attributeValueStyleParameter = $"global::{typeof(HtmlAttributeValueStyle).FullName}.{node.ValueStyle}";
|
||||
var isConditionalAttributeValue = node.Children.Any(child => child is CSharpAttributeValueIRNode);
|
||||
|
|
@ -409,7 +409,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
}
|
||||
}
|
||||
|
||||
internal override void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
public override void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
{
|
||||
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
|
||||
var propertyValueAccessor = GetTagHelperPropertyAccessor(tagHelperVariableName, node.AttributeName, node.Descriptor);
|
||||
|
|
@ -426,7 +426,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
.WriteEndMethodInvocation();
|
||||
}
|
||||
|
||||
internal override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
{
|
||||
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
|
||||
var tagHelperRenderingContext = Context.TagHelperRenderingContext;
|
||||
|
|
@ -528,7 +528,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
.WriteEndMethodInvocation();
|
||||
}
|
||||
|
||||
internal override void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
public override void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
{
|
||||
Context.Writer
|
||||
.Write("await ")
|
||||
|
|
@ -568,7 +568,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
"End" /* ORIGINAL: ScopeManagerEndMethodName */);
|
||||
}
|
||||
|
||||
internal override void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
Context.Writer
|
||||
.Write("private static readonly global::")
|
||||
|
|
@ -596,7 +596,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
}
|
||||
}
|
||||
|
||||
internal override void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
public override void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
{
|
||||
Context.Writer
|
||||
.Write("private static readonly global::")
|
||||
|
|
@ -613,7 +613,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
.WriteEndMethodInvocation();
|
||||
}
|
||||
|
||||
internal override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
{
|
||||
Context.Writer.WriteLineHiddenDirective();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
public interface ITagHelperFeature : IRazorEngineFeature
|
||||
{
|
||||
ITagHelperDescriptorResolver Resolver { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class AddPreallocatedTagHelperHtmlAttributeIRNode : RazorIRNode
|
||||
public class AddPreallocatedTagHelperHtmlAttributeIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class AddTagHelperHtmlAttributeIRNode : RazorIRNode
|
||||
public class AddTagHelperHtmlAttributeIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class CreateTagHelperIRNode : RazorIRNode
|
||||
public class CreateTagHelperIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
|
||||
public string TagHelperTypeName { get; set; }
|
||||
|
||||
internal TagHelperDescriptor Descriptor { get; set; }
|
||||
public TagHelperDescriptor Descriptor { get; set; }
|
||||
|
||||
public override void Accept(RazorIRNodeVisitor visitor)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class DeclarePreallocatedTagHelperAttributeIRNode : RazorIRNode
|
||||
public class DeclarePreallocatedTagHelperAttributeIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class DeclarePreallocatedTagHelperHtmlAttributeIRNode : RazorIRNode
|
||||
public class DeclarePreallocatedTagHelperHtmlAttributeIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class DeclareTagHelperFieldsIRNode : RazorIRNode
|
||||
public class DeclareTagHelperFieldsIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class ExecuteTagHelpersIRNode : RazorIRNode
|
||||
public class ExecuteTagHelpersIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class InitializeTagHelperStructureIRNode : RazorIRNode
|
||||
public class InitializeTagHelperStructureIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
|
|
|
|||
|
|
@ -94,57 +94,57 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
public virtual void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitTagHelper(TagHelperIRNode node)
|
||||
public virtual void VisitTagHelper(TagHelperIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
public virtual void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
public virtual void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
public virtual void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
public virtual void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
public virtual void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public virtual void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public virtual void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
public virtual void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
public virtual void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
{
|
||||
VisitDefault(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,57 +95,57 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
public virtual TResult VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitTagHelper(TagHelperIRNode node)
|
||||
public virtual TResult VisitTagHelper(TagHelperIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
public virtual TResult VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
public virtual TResult VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
public virtual TResult VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
public virtual TResult VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
public virtual TResult VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public virtual TResult VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public virtual TResult VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
public virtual TResult VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
||||
internal virtual TResult VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
public virtual TResult VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
{
|
||||
return VisitDefault(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,10 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class SetPreallocatedTagHelperPropertyIRNode : RazorIRNode
|
||||
public class SetPreallocatedTagHelperPropertyIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class SetTagHelperPropertyIRNode : RazorIRNode
|
||||
public class SetTagHelperPropertyIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
||||
{
|
||||
internal class TagHelperIRNode : RazorIRNode
|
||||
public class TagHelperIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
/// <summary>
|
||||
/// Used to manage <see cref="RazorError"/>s encountered during the Razor parsing phase.
|
||||
/// </summary>
|
||||
internal class ErrorSink
|
||||
public class ErrorSink
|
||||
{
|
||||
private readonly List<RazorError> _errors;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal enum HtmlAttributeValueStyle
|
||||
public enum HtmlAttributeValueStyle
|
||||
{
|
||||
DoubleQuotes,
|
||||
SingleQuotes,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
|||
/// <summary>
|
||||
/// Contract used to resolve <see cref="TagHelperDescriptor"/>s.
|
||||
/// </summary>
|
||||
internal interface ITagHelperDescriptorResolver
|
||||
public interface ITagHelperDescriptorResolver
|
||||
{
|
||||
IEnumerable<TagHelperDescriptor> Resolve(ErrorSink errorSink);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Microsoft.Extensions.Internal;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class RazorError : IEquatable<RazorError>
|
||||
public class RazorError : IEquatable<RazorError>
|
||||
{
|
||||
internal static readonly RazorError[] EmptyArray = new RazorError[0];
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
using System.Runtime.CompilerServices;
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Evolution.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
VisitDefault(node);
|
||||
}
|
||||
|
||||
internal override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
if (node.Children.Count != 1 || !(node.Children.First() is HtmlContentIRNode))
|
||||
{
|
||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
node.Parent.Children[nodeIndex] = addPreAllocatedAttribute;
|
||||
}
|
||||
|
||||
internal override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
{
|
||||
if (!node.Descriptor.IsStringProperty ||
|
||||
node.Children.Count != 1 ||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
|
||||
public RazorSyntaxTree Execute(RazorCodeDocument codeDocument, RazorSyntaxTree syntaxTree)
|
||||
{
|
||||
var resolver = Engine.Features.OfType<TagHelperFeature>().FirstOrDefault()?.Resolver;
|
||||
var resolver = Engine.Features.OfType<ITagHelperFeature>().FirstOrDefault()?.Resolver;
|
||||
if (resolver == null)
|
||||
{
|
||||
// No resolver, nothing to do.
|
||||
|
|
|
|||
|
|
@ -1,19 +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 Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
internal class TagHelperFeature : IRazorEngineFeature
|
||||
{
|
||||
public TagHelperFeature(ITagHelperDescriptorResolver resolver)
|
||||
{
|
||||
Resolver = resolver;
|
||||
}
|
||||
|
||||
public RazorEngine Engine { get; set; }
|
||||
|
||||
public ITagHelperDescriptorResolver Resolver { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
|
||||
|
|
@ -11,18 +10,9 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
internal class DefaultTagHelperResolver : TagHelperResolver
|
||||
{
|
||||
private static readonly Version SupportedVCTHMvcVersion = new Version(1, 1);
|
||||
private readonly string ViewComponentAssembly;
|
||||
|
||||
public DefaultTagHelperResolver(bool designTime) : this(designTime, ViewComponentTypes.Assembly)
|
||||
{
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal DefaultTagHelperResolver(bool designTime, string viewComponentAssembly)
|
||||
public DefaultTagHelperResolver(bool designTime)
|
||||
{
|
||||
DesignTime = designTime;
|
||||
ViewComponentAssembly = viewComponentAssembly;
|
||||
}
|
||||
|
||||
public bool DesignTime { get; }
|
||||
|
|
@ -40,15 +30,8 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
|
||||
private void VisitTagHelpers(Compilation compilation, List<TagHelperDescriptor> results, ErrorSink errors)
|
||||
{
|
||||
var @interface = compilation.GetTypeByMetadataName(TagHelperTypes.ITagHelper);
|
||||
if (@interface == null)
|
||||
{
|
||||
// If ITagHelper isn't defined, then we couldn't possibly find anything.
|
||||
return;
|
||||
}
|
||||
|
||||
var types = new List<INamedTypeSymbol>();
|
||||
var visitor = new TagHelperVisitor(@interface, types);
|
||||
var visitor = TagHelperTypeVisitor.Create(compilation, types);
|
||||
|
||||
VisitCompilation(visitor, compilation);
|
||||
|
||||
|
|
@ -63,20 +46,8 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
|
||||
private void VisitViewComponents(Compilation compilation, List<TagHelperDescriptor> results, ErrorSink errors)
|
||||
{
|
||||
var mvcViewFeaturesAssembly = compilation.References
|
||||
.Select(reference => compilation.GetAssemblyOrModuleSymbol(reference))
|
||||
.OfType<IAssemblySymbol>()
|
||||
.FirstOrDefault(assembly => string.Equals(assembly.Identity.Name, ViewComponentAssembly, StringComparison.Ordinal));
|
||||
|
||||
if (mvcViewFeaturesAssembly == null || mvcViewFeaturesAssembly.Identity.Version < SupportedVCTHMvcVersion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var viewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute);
|
||||
var nonViewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute);
|
||||
var types = new List<INamedTypeSymbol>();
|
||||
var visitor = new ViewComponentVisitor(viewComponentAttributeSymbol, viewComponentAttributeSymbol, types);
|
||||
var visitor = ViewComponentTypeVisitor.Create(compilation, types);
|
||||
|
||||
VisitCompilation(visitor, compilation);
|
||||
|
||||
|
|
@ -109,116 +80,5 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visits top-level types and finds interface implementations.
|
||||
internal class TagHelperVisitor : SymbolVisitor
|
||||
{
|
||||
private INamedTypeSymbol _interface;
|
||||
private List<INamedTypeSymbol> _results;
|
||||
|
||||
public TagHelperVisitor(INamedTypeSymbol @interface, List<INamedTypeSymbol> results)
|
||||
{
|
||||
_interface = @interface;
|
||||
_results = results;
|
||||
}
|
||||
|
||||
public override void VisitNamedType(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (IsTagHelper(symbol))
|
||||
{
|
||||
_results.Add(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitNamespace(INamespaceSymbol symbol)
|
||||
{
|
||||
foreach (var member in symbol.GetMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsTagHelper(INamedTypeSymbol symbol)
|
||||
{
|
||||
return symbol.DeclaredAccessibility == Accessibility.Public &&
|
||||
!symbol.IsAbstract &&
|
||||
!symbol.IsGenericType &&
|
||||
symbol.AllInterfaces.Contains(_interface);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ViewComponentVisitor : SymbolVisitor
|
||||
{
|
||||
private INamedTypeSymbol _viewComponentAttribute;
|
||||
private INamedTypeSymbol _nonViewComponentAttribute;
|
||||
private List<INamedTypeSymbol> _results;
|
||||
|
||||
public ViewComponentVisitor(
|
||||
INamedTypeSymbol viewComponentAttribute,
|
||||
INamedTypeSymbol nonViewComponentAttribute,
|
||||
List<INamedTypeSymbol> results)
|
||||
{
|
||||
_viewComponentAttribute = viewComponentAttribute;
|
||||
_nonViewComponentAttribute = nonViewComponentAttribute;
|
||||
_results = results;
|
||||
}
|
||||
|
||||
public override void VisitNamedType(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (IsViewComponent(symbol))
|
||||
{
|
||||
_results.Add(symbol);
|
||||
}
|
||||
|
||||
if (symbol.DeclaredAccessibility != Accessibility.Public)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var member in symbol.GetTypeMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitNamespace(INamespaceSymbol symbol)
|
||||
{
|
||||
foreach (var member in symbol.GetMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsViewComponent(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (symbol.DeclaredAccessibility != Accessibility.Public ||
|
||||
symbol.IsAbstract ||
|
||||
symbol.IsGenericType ||
|
||||
AttributeIsDefined(symbol, _nonViewComponentAttribute))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix) ||
|
||||
AttributeIsDefined(symbol, _viewComponentAttribute);
|
||||
}
|
||||
|
||||
private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var attribute = type.GetAttributes().Where(a => a.AttributeClass == queryAttribute).FirstOrDefault();
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return AttributeIsDefined(type.BaseType, queryAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Razor is a markup syntax for adding server-side logic to web pages. This package contains the Razor design-time infrastructure.</Description>
|
||||
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
|
||||
|
|
@ -10,10 +8,9 @@
|
|||
<PackageTags>aspnetcore;cshtml;razor</PackageTags>
|
||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="1.3.0" />
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Razor.Evolution\Microsoft.AspNetCore.Razor.Evolution.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CodeAnalysis.Razor\Microsoft.CodeAnalysis.Razor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// 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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public class DefaultMetadataReferenceFeature : IMetadataReferenceFeature
|
||||
{
|
||||
public RazorEngine Engine { get; set; }
|
||||
|
||||
public IReadOnlyList<MetadataReference> References { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -223,14 +223,14 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
var whitespaceError = Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace(
|
||||
var whitespaceError = Resources.FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeNameNullWhitespace(
|
||||
TagHelperTypes.RestrictChildrenAttribute,
|
||||
tagHelperName);
|
||||
errorSink.OnError(SourceLocation.Zero, whitespaceError, length: 0);
|
||||
}
|
||||
else if (TryValidateName(
|
||||
name,
|
||||
invalidCharacter => Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName(
|
||||
invalidCharacter => Resources.FormatTagHelperDescriptorFactory_InvalidRestrictChildrenAttributeName(
|
||||
TagHelperTypes.RestrictChildrenAttribute,
|
||||
name,
|
||||
tagHelperName,
|
||||
|
|
@ -372,15 +372,15 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
}
|
||||
else if (string.IsNullOrWhiteSpace(parentTag))
|
||||
{
|
||||
var error = Workspaces.Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(
|
||||
Workspaces.Resources.TagHelperDescriptorFactory_ParentTag);
|
||||
var error = Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(
|
||||
Resources.TagHelperDescriptorFactory_ParentTag);
|
||||
errorSink.OnError(SourceLocation.Zero, error, length: 0);
|
||||
return false;
|
||||
}
|
||||
else if (!TryValidateName(
|
||||
parentTag,
|
||||
invalidCharacter => Workspaces.Resources.FormatHtmlTargetElementAttribute_InvalidName(
|
||||
Workspaces.Resources.TagHelperDescriptorFactory_ParentTag.ToLower(),
|
||||
invalidCharacter => Resources.FormatHtmlTargetElementAttribute_InvalidName(
|
||||
Resources.TagHelperDescriptorFactory_ParentTag.ToLower(),
|
||||
parentTag,
|
||||
invalidCharacter),
|
||||
errorSink))
|
||||
|
|
@ -414,18 +414,18 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
}
|
||||
|
||||
var targetName = targetingAttributes ?
|
||||
Workspaces.Resources.TagHelperDescriptorFactory_Attribute :
|
||||
Workspaces.Resources.TagHelperDescriptorFactory_Tag;
|
||||
Resources.TagHelperDescriptorFactory_Attribute :
|
||||
Resources.TagHelperDescriptorFactory_Tag;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
var error = Workspaces.Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(targetName);
|
||||
var error = Resources.FormatHtmlTargetElementAttribute_NameCannotBeNullOrWhitespace(targetName);
|
||||
errorSink.OnError(SourceLocation.Zero, error, length: 0);
|
||||
return false;
|
||||
}
|
||||
else if (!TryValidateName(
|
||||
name,
|
||||
invalidCharacter => Workspaces.Resources.FormatHtmlTargetElementAttribute_InvalidName(
|
||||
invalidCharacter => Resources.FormatHtmlTargetElementAttribute_InvalidName(
|
||||
targetName.ToLower(),
|
||||
name,
|
||||
invalidCharacter),
|
||||
|
|
@ -509,7 +509,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
// Specified HtmlAttributeNameAttribute.Name though property has no public setter.
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNotNullOrEmpty(
|
||||
GetFullName(type),
|
||||
property.Name,
|
||||
TagHelperTypes.HtmlAttributeNameAttribute,
|
||||
|
|
@ -591,13 +591,13 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
string nameOrPrefix;
|
||||
if (attributeDescriptor.IsIndexer)
|
||||
{
|
||||
nameOrPrefix = Workspaces.Resources.TagHelperDescriptorFactory_Prefix;
|
||||
nameOrPrefix = Resources.TagHelperDescriptorFactory_Prefix;
|
||||
}
|
||||
else if (string.IsNullOrEmpty(attributeDescriptor.Name))
|
||||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameNullOrEmpty(
|
||||
GetFullName(parentType),
|
||||
attributeDescriptor.PropertyName),
|
||||
length: 0);
|
||||
|
|
@ -606,7 +606,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
}
|
||||
else
|
||||
{
|
||||
nameOrPrefix = Workspaces.Resources.TagHelperDescriptorFactory_Name;
|
||||
nameOrPrefix = Resources.TagHelperDescriptorFactory_Name;
|
||||
}
|
||||
|
||||
return ValidateTagHelperAttributeNameOrPrefix(
|
||||
|
|
@ -639,7 +639,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
// Provide a single error if the entire name is whitespace, not an error per character.
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixWhitespace(
|
||||
GetFullName(parentType),
|
||||
propertyName,
|
||||
nameOrPrefix),
|
||||
|
|
@ -654,7 +654,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixStart(
|
||||
GetFullName(parentType),
|
||||
propertyName,
|
||||
nameOrPrefix,
|
||||
|
|
@ -672,7 +672,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameOrPrefixCharacter(
|
||||
GetFullName(parentType),
|
||||
propertyName,
|
||||
nameOrPrefix,
|
||||
|
|
@ -749,7 +749,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
isInvalid = true;
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributePrefixNotNull(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributePrefixNotNull(
|
||||
GetFullName(parentType),
|
||||
property.Name,
|
||||
TagHelperTypes.HtmlAttributeNameAttribute,
|
||||
|
|
@ -764,7 +764,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
isInvalid = true;
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameAttribute(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributeNameAttribute(
|
||||
GetFullName(parentType),
|
||||
property.Name,
|
||||
TagHelperTypes.HtmlAttributeNameAttribute,
|
||||
|
|
@ -784,7 +784,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
isInvalid = true;
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidAttributePrefixNull(
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidAttributePrefixNull(
|
||||
GetFullName(parentType),
|
||||
property.Name,
|
||||
TagHelperTypes.HtmlAttributeNameAttribute,
|
||||
|
|
@ -973,7 +973,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeCharacter(Current, _requiredAttributes),
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeCharacter(Current, _requiredAttributes),
|
||||
length: 0);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1055,7 +1055,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_PartialRequiredAttributeOperator(_requiredAttributes, op),
|
||||
Resources.FormatTagHelperDescriptorFactory_PartialRequiredAttributeOperator(_requiredAttributes, op),
|
||||
length: 0);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1064,7 +1064,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeOperator(Current, _requiredAttributes),
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeOperator(Current, _requiredAttributes),
|
||||
length: 0);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1089,7 +1089,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeMismatchedQuotes(_requiredAttributes, quote),
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeMismatchedQuotes(_requiredAttributes, quote),
|
||||
length: 0);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1164,7 +1164,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_CouldNotFindMatchingEndBrace(_requiredAttributes),
|
||||
Resources.FormatTagHelperDescriptorFactory_CouldNotFindMatchingEndBrace(_requiredAttributes),
|
||||
length: 0);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1172,7 +1172,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeCharacter(Current, _requiredAttributes),
|
||||
Resources.FormatTagHelperDescriptorFactory_InvalidRequiredAttributeCharacter(Current, _requiredAttributes),
|
||||
length: 0);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1192,7 +1192,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
errorSink.OnError(
|
||||
SourceLocation.Zero,
|
||||
Workspaces.Resources.FormatTagHelperDescriptorFactory_CouldNotFindMatchingEndBrace(_requiredAttributes),
|
||||
Resources.FormatTagHelperDescriptorFactory_CouldNotFindMatchingEndBrace(_requiredAttributes),
|
||||
length: 0);
|
||||
|
||||
return false;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public class DefaultTagHelperFeature : ITagHelperFeature
|
||||
{
|
||||
private RazorEngine _engine;
|
||||
private IMetadataReferenceFeature _referenceFeature;
|
||||
|
||||
public RazorEngine Engine
|
||||
{
|
||||
get
|
||||
{
|
||||
return _engine;
|
||||
}
|
||||
set
|
||||
{
|
||||
_engine = value;
|
||||
OnInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
public ITagHelperDescriptorResolver Resolver { get; private set; }
|
||||
|
||||
private void OnInitialized()
|
||||
{
|
||||
_referenceFeature = Engine.Features.OfType<IMetadataReferenceFeature>().FirstOrDefault();
|
||||
Resolver = new InnerResolver(_referenceFeature);
|
||||
}
|
||||
|
||||
private class InnerResolver : ITagHelperDescriptorResolver
|
||||
{
|
||||
private readonly IMetadataReferenceFeature _referenceFeature;
|
||||
|
||||
public InnerResolver(IMetadataReferenceFeature referenceFeature)
|
||||
{
|
||||
_referenceFeature = referenceFeature;
|
||||
}
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(ErrorSink errorSink)
|
||||
{
|
||||
var compilation = CSharpCompilation.Create("__TagHelpers", references: _referenceFeature.References);
|
||||
return TagHelpers.GetTagHelpers(compilation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public interface IMetadataReferenceFeature : IRazorEngineFeature
|
||||
{
|
||||
IReadOnlyList<MetadataReference> References { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
<Import Project="..\..\build\common.props" />
|
||||
<PropertyGroup>
|
||||
<Description>Razor is a markup syntax for adding server-side logic to web pages. This package contains the Razor design-time infrastructure.</Description>
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="1.3.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.3.0" />
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Razor.Evolution\Microsoft.AspNetCore.Razor.Evolution.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// 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.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Remote.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.RazorExtension, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// <auto-generated />
|
||||
namespace Microsoft.CodeAnalysis.Razor.Workspaces
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.Razor.Workspaces
|
|||
internal static class Resources
|
||||
{
|
||||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("Microsoft.CodeAnalysis.Razor.Workspaces.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
= new ResourceManager("Microsoft.CodeAnalysis.Razor.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// {0} cannot be null or an empty string.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// <auto-generated />
|
||||
namespace Microsoft.CodeAnalysis.Razor.Workspaces
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
|
@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.Razor.Workspaces
|
|||
internal static class ViewComponentResources
|
||||
{
|
||||
private static readonly ResourceManager _resourceManager
|
||||
= new ResourceManager("Microsoft.CodeAnalysis.Razor.Workspaces.ViewComponentResources", typeof(ViewComponentResources).GetTypeInfo().Assembly);
|
||||
= new ResourceManager("Microsoft.CodeAnalysis.Razor.ViewComponentResources", typeof(ViewComponentResources).GetTypeInfo().Assembly);
|
||||
|
||||
/// <summary>
|
||||
/// View component '{0}' must have exactly one public method named '{1}' or '{2}'.
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// 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.Collections.Generic;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
// Visits top-level types and finds interface implementations.
|
||||
internal class TagHelperTypeVisitor : SymbolVisitor
|
||||
{
|
||||
private INamedTypeSymbol _interface;
|
||||
private List<INamedTypeSymbol> _results;
|
||||
|
||||
public static TagHelperTypeVisitor Create(Compilation compilation, List<INamedTypeSymbol> results)
|
||||
{
|
||||
var @interface = compilation.GetTypeByMetadataName(TagHelperTypes.ITagHelper);
|
||||
return new TagHelperTypeVisitor(@interface, results);
|
||||
}
|
||||
|
||||
public TagHelperTypeVisitor(INamedTypeSymbol @interface, List<INamedTypeSymbol> results)
|
||||
{
|
||||
_interface = @interface;
|
||||
_results = results;
|
||||
}
|
||||
|
||||
public override void VisitNamedType(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (IsTagHelper(symbol))
|
||||
{
|
||||
_results.Add(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitNamespace(INamespaceSymbol symbol)
|
||||
{
|
||||
foreach (var member in symbol.GetMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsTagHelper(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (_interface == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
symbol.DeclaredAccessibility == Accessibility.Public &&
|
||||
!symbol.IsAbstract &&
|
||||
!symbol.IsGenericType &&
|
||||
symbol.AllInterfaces.Contains(_interface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// 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;
|
||||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public static class TagHelpers
|
||||
{
|
||||
public static IReadOnlyList<TagHelperDescriptor> GetTagHelpers(Compilation compilation)
|
||||
{
|
||||
var results = new List<TagHelperDescriptor>();
|
||||
var errors = new ErrorSink();
|
||||
|
||||
VisitTagHelpers(compilation, results, errors);
|
||||
VisitViewComponents(compilation, results, errors);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void VisitTagHelpers(Compilation compilation, List<TagHelperDescriptor> results, ErrorSink errors)
|
||||
{
|
||||
var types = new List<INamedTypeSymbol>();
|
||||
var visitor = TagHelperTypeVisitor.Create(compilation, types);
|
||||
|
||||
VisitCompilation(visitor, compilation);
|
||||
|
||||
var factory = new DefaultTagHelperDescriptorFactory(compilation, designTime: false);
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
var descriptors = factory.CreateDescriptors(type, errors);
|
||||
results.AddRange(descriptors);
|
||||
}
|
||||
}
|
||||
|
||||
private static void VisitViewComponents(Compilation compilation, List<TagHelperDescriptor> results, ErrorSink errors)
|
||||
{
|
||||
var types = new List<INamedTypeSymbol>();
|
||||
var visitor = ViewComponentTypeVisitor.Create(compilation, types);
|
||||
|
||||
VisitCompilation(visitor, compilation);
|
||||
|
||||
var factory = new ViewComponentTagHelperDescriptorFactory(compilation);
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
var descriptor = factory.CreateDescriptor(type);
|
||||
|
||||
results.Add(descriptor);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.OnError(SourceLocation.Zero, ex.Message, length: 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void VisitCompilation(SymbolVisitor visitor, Compilation compilation)
|
||||
{
|
||||
visitor.Visit(compilation.Assembly.GlobalNamespace);
|
||||
|
||||
foreach (var reference in compilation.References)
|
||||
{
|
||||
if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
|
||||
{
|
||||
visitor.Visit(assembly.GlobalNamespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ using System.Collections.Immutable;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Evolution;
|
||||
using Microsoft.CodeAnalysis.Razor.Workspaces;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
internal class ViewComponentTypeVisitor : SymbolVisitor
|
||||
{
|
||||
private static readonly Version SupportedVCTHMvcVersion = new Version(1, 1);
|
||||
|
||||
private INamedTypeSymbol _viewComponentAttribute;
|
||||
private INamedTypeSymbol _nonViewComponentAttribute;
|
||||
private List<INamedTypeSymbol> _results;
|
||||
|
||||
public static ViewComponentTypeVisitor Create(Compilation compilation, List<INamedTypeSymbol> results)
|
||||
{
|
||||
var enabled = false;
|
||||
foreach (var reference in compilation.References)
|
||||
{
|
||||
var symbol = compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol;
|
||||
if (symbol != null)
|
||||
{
|
||||
if (string.Equals(symbol.Identity.Name, ViewComponentTypes.Assembly, StringComparison.Ordinal) &&
|
||||
symbol.Identity.Version > ViewComponentTypes.AssemblyVersion)
|
||||
{
|
||||
enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var vcAttribute = enabled ? compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute) : null;
|
||||
var nonVCAttribute = enabled ? compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute) : null;
|
||||
return new ViewComponentTypeVisitor(vcAttribute, nonVCAttribute, results);
|
||||
}
|
||||
|
||||
public ViewComponentTypeVisitor(
|
||||
INamedTypeSymbol viewComponentAttribute,
|
||||
INamedTypeSymbol nonViewComponentAttribute,
|
||||
List<INamedTypeSymbol> results)
|
||||
{
|
||||
_viewComponentAttribute = viewComponentAttribute;
|
||||
_nonViewComponentAttribute = nonViewComponentAttribute;
|
||||
_results = results;
|
||||
}
|
||||
|
||||
public override void VisitNamedType(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (IsViewComponent(symbol))
|
||||
{
|
||||
_results.Add(symbol);
|
||||
}
|
||||
|
||||
if (symbol.DeclaredAccessibility != Accessibility.Public)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var member in symbol.GetTypeMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitNamespace(INamespaceSymbol symbol)
|
||||
{
|
||||
foreach (var member in symbol.GetMembers())
|
||||
{
|
||||
Visit(member);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsViewComponent(INamedTypeSymbol symbol)
|
||||
{
|
||||
if (_viewComponentAttribute == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (symbol.DeclaredAccessibility != Accessibility.Public ||
|
||||
symbol.IsAbstract ||
|
||||
symbol.IsGenericType ||
|
||||
AttributeIsDefined(symbol, _nonViewComponentAttribute))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix) ||
|
||||
AttributeIsDefined(symbol, _viewComponentAttribute);
|
||||
}
|
||||
|
||||
private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var attribute = type.GetAttributes().Where(a => a.AttributeClass == queryAttribute).FirstOrDefault();
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return AttributeIsDefined(type.BaseType, queryAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,16 @@
|
|||
// 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.CodeAnalysis.Razor
|
||||
{
|
||||
internal static class ViewComponentTypes
|
||||
{
|
||||
public const string Assembly = "Microsoft.AspNetCore.Mvc.ViewFeatures";
|
||||
|
||||
public static readonly Version AssemblyVersion = new Version(1, 1, 0, 0);
|
||||
|
||||
public const string ViewComponentSuffix = "ViewComponent";
|
||||
|
||||
public const string ViewComponentAttribute = "Microsoft.AspNetCore.Mvc.ViewComponentAttribute";
|
||||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.CodeAnalysis.Razor.Workspaces;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
|
|
@ -1421,7 +1421,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
|||
builder =>
|
||||
{
|
||||
builder.Features.Add(new ApiSetsIRTestAdapter());
|
||||
builder.Features.Add(new TagHelperFeature(new TestTagHelperDescriptorResolver(descriptors)));
|
||||
builder.AddTagHelpers(descriptors);
|
||||
});
|
||||
var document = CreateCodeDocument();
|
||||
|
||||
|
|
@ -1439,7 +1439,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
|||
builder =>
|
||||
{
|
||||
builder.Features.Add(new ApiSetsIRTestAdapter());
|
||||
builder.Features.Add(new TagHelperFeature(new TestTagHelperDescriptorResolver(descriptors)));
|
||||
builder.AddTagHelpers(descriptors);
|
||||
});
|
||||
var document = CreateCodeDocument();
|
||||
|
||||
|
|
|
|||
|
|
@ -87,47 +87,47 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
|||
WriteContentNode(node, node.Content);
|
||||
}
|
||||
|
||||
internal override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.UsedTagHelperTypeNames.ToArray());
|
||||
}
|
||||
|
||||
internal override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
public override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.TagName, string.Format("{0}.{1}", nameof(TagMode), node.TagMode));
|
||||
}
|
||||
|
||||
internal override void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
public override void VisitCreateTagHelper(CreateTagHelperIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.TagHelperTypeName);
|
||||
}
|
||||
|
||||
internal override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.AttributeName, node.PropertyName, string.Format("HtmlAttributeValueStyle.{0}", node.ValueStyle));
|
||||
}
|
||||
|
||||
internal override void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
public override void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.VariableName, node.Name, node.Value, string.Format("HtmlAttributeValueStyle.{0}", node.ValueStyle));
|
||||
}
|
||||
|
||||
internal override void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
public override void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.VariableName, node.AttributeName, node.PropertyName);
|
||||
}
|
||||
|
||||
internal override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.Name, string.Format("{0}.{1}", nameof(HtmlAttributeValueStyle), node.ValueStyle));
|
||||
}
|
||||
|
||||
internal override void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.VariableName, node.Name, node.Value, string.Format("{0}.{1}", nameof(HtmlAttributeValueStyle), node.ValueStyle));
|
||||
}
|
||||
|
||||
internal override void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
public override void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.VariableName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
{
|
||||
builder?.Invoke(b);
|
||||
|
||||
b.Features.Add(new TagHelperFeature(new TestTagHelperDescriptorResolver(tagHelpers)));
|
||||
b.AddTagHelpers(tagHelpers);
|
||||
});
|
||||
|
||||
for (var i = 0; i < engine.Phases.Count; i++)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
|
|
@ -9,14 +10,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
{
|
||||
public static IRazorEngineBuilder AddTagHelpers(this IRazorEngineBuilder builder, params TagHelperDescriptor[] tagHelpers)
|
||||
{
|
||||
var resolver = (TestTagHelperDescriptorResolver)builder.Features.OfType<TagHelperFeature>().FirstOrDefault()?.Resolver;
|
||||
if (resolver == null)
|
||||
return AddTagHelpers(builder, (IEnumerable<TagHelperDescriptor>)tagHelpers);
|
||||
}
|
||||
|
||||
public static IRazorEngineBuilder AddTagHelpers(this IRazorEngineBuilder builder, IEnumerable<TagHelperDescriptor> tagHelpers)
|
||||
{
|
||||
var feature = (TestTagHelperFeature)builder.Features.OfType<ITagHelperFeature>().FirstOrDefault();
|
||||
if (feature == null)
|
||||
{
|
||||
resolver = new TestTagHelperDescriptorResolver();
|
||||
builder.Features.Add(new TagHelperFeature(resolver));
|
||||
feature = new TestTagHelperFeature();
|
||||
builder.Features.Add(feature);
|
||||
}
|
||||
|
||||
resolver.TagHelpers.AddRange(tagHelpers);
|
||||
feature.TagHelpers.AddRange(tagHelpers);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
|
|
@ -81,9 +82,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
// Arrange
|
||||
var engine = RazorEngine.Create(builder =>
|
||||
{
|
||||
|
||||
var tagHelperFeature = new TagHelperFeature(resolver: null);
|
||||
builder.Features.Add(tagHelperFeature);
|
||||
builder.Features.Add(Mock.Of<ITagHelperFeature>());
|
||||
});
|
||||
var pass = new TagHelperBinderSyntaxTreePass()
|
||||
{
|
||||
|
|
@ -107,9 +106,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
// Arrange
|
||||
var engine = RazorEngine.Create(builder =>
|
||||
{
|
||||
var resolver = new TestTagHelperDescriptorResolver();
|
||||
var tagHelperFeature = new TagHelperFeature(resolver);
|
||||
builder.Features.Add(tagHelperFeature);
|
||||
builder.Features.Add(new TestTagHelperFeature());
|
||||
});
|
||||
|
||||
var pass = new TagHelperBinderSyntaxTreePass()
|
||||
|
|
@ -136,9 +133,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
// Arrange
|
||||
var engine = RazorEngine.Create(builder =>
|
||||
{
|
||||
var resolver = new TestTagHelperDescriptorResolver();
|
||||
var tagHelperFeature = new TagHelperFeature(resolver);
|
||||
builder.Features.Add(tagHelperFeature);
|
||||
builder.Features.Add(new TestTagHelperFeature());
|
||||
});
|
||||
|
||||
var pass = new TagHelperBinderSyntaxTreePass()
|
||||
|
|
@ -173,8 +168,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
var engine = RazorEngine.Create(builder =>
|
||||
{
|
||||
var resolver = new ErrorLoggingTagHelperDescriptorResolver(resolverError);
|
||||
var tagHelperFeature = new TagHelperFeature(resolver);
|
||||
builder.Features.Add(tagHelperFeature);
|
||||
builder.Features.Add(Mock.Of<ITagHelperFeature>(f => f.Resolver == resolver));
|
||||
});
|
||||
|
||||
var pass = new TagHelperBinderSyntaxTreePass()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// 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 System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
{
|
||||
public class TestTagHelperFeature : ITagHelperFeature
|
||||
{
|
||||
public TestTagHelperFeature()
|
||||
{
|
||||
Resolver = new TestTagHelperDescriptorResolver();
|
||||
}
|
||||
|
||||
public TestTagHelperFeature(IEnumerable<TagHelperDescriptor> tagHelpers)
|
||||
{
|
||||
Resolver = new TestTagHelperDescriptorResolver(tagHelpers);
|
||||
}
|
||||
|
||||
public RazorEngine Engine { get; set; }
|
||||
|
||||
public List<TagHelperDescriptor> TagHelpers => ((TestTagHelperDescriptorResolver)Resolver).TagHelpers;
|
||||
|
||||
public ITagHelperDescriptorResolver Resolver { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.CodeAnalysis.Razor.Workspaces.Test;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor.Workspaces
|
||||
{
|
||||
public class TagHelperTypeVisitorTest
|
||||
{
|
||||
private static Compilation Compilation { get; } = TestCompilation.Create();
|
||||
|
||||
private static INamedTypeSymbol ITagHelperSymbol { get; } = Compilation.GetTypeByMetadataName(TagHelperTypes.ITagHelper);
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_PlainTagHelper_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new TagHelperTypeVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_InheritedTagHelper_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new TagHelperTypeVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_AbstractTagHelper_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new TagHelperTypeVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_GenericTagHelper_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new TagHelperTypeVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericTagHelper<>).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_InternalTagHelper_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new TagHelperTypeVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isTagHelper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public class Invalid_NestedPublicTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_NestedPublicViewComponent
|
||||
{
|
||||
public string Invoke(string foo) => null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Invalid_AbstractTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Invalid_GenericTagHelper<T> : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
internal class Invalid_InternalTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_PlainTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_InheritedTagHelper : Valid_PlainTagHelper
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor.Workspaces.Test
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public static class TestCompilation
|
||||
{
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
// 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.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor
|
||||
{
|
||||
public class ViewComponentTypeVisitorTest
|
||||
{
|
||||
private static Compilation Compilation { get; } = TestCompilation.Create();
|
||||
|
||||
// In practice MVC will provide a marker attribute for ViewComponents. To prevent a circular reference between MVC and Razor
|
||||
// we can use a test class as a marker.
|
||||
private static INamedTypeSymbol TestViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestViewComponentAttribute).FullName);
|
||||
private static INamedTypeSymbol TestNonViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestNonViewComponentAttribute).FullName);
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_PlainViewComponent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_DecoratedViewComponent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_DecoratedVC).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_InheritedViewComponent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedVC).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_AbstractViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_GenericViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericViewComponent<>).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_InternalViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_DecoratedNonViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_DecoratedViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_InheritedNonViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new ViewComponentTypeVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InheritedViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
public abstract class Invalid_AbstractViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
public class Invalid_GenericViewComponent<T>
|
||||
{
|
||||
}
|
||||
|
||||
internal class Invalid_InternalViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_PlainViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
[TestViewComponent]
|
||||
public class Valid_DecoratedVC
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_InheritedVC : Valid_DecoratedVC
|
||||
{
|
||||
}
|
||||
|
||||
[TestNonViewComponent]
|
||||
public class Invalid_DecoratedViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
[TestViewComponent]
|
||||
public class Invalid_InheritedViewComponent : Invalid_DecoratedViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
public class TestViewComponentAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
public class TestNonViewComponentAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,334 +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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.CodeAnalysis.Razor.Workspaces.Test;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor.Workspaces
|
||||
{
|
||||
public class DefaultTagHelperResolverTest
|
||||
{
|
||||
private static Compilation Compilation { get; } = TestCompilation.Create();
|
||||
|
||||
private static INamedTypeSymbol ITagHelperSymbol { get; } = Compilation.GetTypeByMetadataName(TagHelperTypes.ITagHelper);
|
||||
|
||||
// In practice MVC will provide a marker attribute for ViewComponents. To prevent a circular reference between MVC and Razor
|
||||
// we can use a test class as a marker.
|
||||
private static INamedTypeSymbol TestViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestViewComponentAttribute).FullName);
|
||||
private static INamedTypeSymbol TestNonViewComponentAttributeSymbol { get; } = Compilation.GetTypeByMetadataName(typeof(TestNonViewComponentAttribute).FullName);
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_PlainTagHelper_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.TagHelperVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_InheritedTagHelper_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.TagHelperVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_AbstractTagHelper_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.TagHelperVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_GenericTagHelper_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.TagHelperVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericTagHelper<>).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsTagHelper_InternalTagHelper_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.TagHelperVisitor(ITagHelperSymbol, new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalTagHelper).FullName);
|
||||
|
||||
// Act
|
||||
var isTagHelper = testVisitor.IsTagHelper(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isTagHelper);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_NestedTagHelpersAreNotFound()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new DefaultTagHelperResolver(designTime: false);
|
||||
var expectedTypeName = typeof(DefaultTagHelperResolver).FullName + "." + nameof(Invalid_NestedPublicTagHelper);
|
||||
|
||||
// Act
|
||||
var descriptors = resolver.GetTagHelpers(Compilation);
|
||||
|
||||
// Assert
|
||||
var matchingDescriptors = descriptors
|
||||
.Where(descriptor => string.Equals(descriptor.TypeName, expectedTypeName, StringComparison.Ordinal));
|
||||
Assert.Empty(matchingDescriptors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_PlainViewComponent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_PlainViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_DecoratedViewComponent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_DecoratedVC).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_InheritedViewComponent_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Valid_InheritedVC).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.True(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_AbstractViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_AbstractViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_GenericViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_GenericViewComponent<>).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_InternalViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InternalViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTagHelpers_NestedViewComponentTagHelpersAreFound()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new DefaultTagHelperResolver(
|
||||
designTime: false,
|
||||
viewComponentAssembly: typeof(DefaultTagHelperResolverTest).Assembly.GetName().Name);
|
||||
var expectedTypeName = "__Generated__" + nameof(Valid_NestedPublicViewComponent) + "TagHelper";
|
||||
|
||||
// Act
|
||||
var descriptors = resolver.GetTagHelpers(Compilation);
|
||||
|
||||
// Assert
|
||||
Assert.Single(descriptors, descriptor => string.Equals(descriptor.TypeName, expectedTypeName, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_DecoratedNonViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_DecoratedViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsViewComponent_InheritedNonViewComponent_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var testVisitor = new DefaultTagHelperResolver.ViewComponentVisitor(
|
||||
TestViewComponentAttributeSymbol,
|
||||
TestNonViewComponentAttributeSymbol,
|
||||
new List<INamedTypeSymbol>());
|
||||
var tagHelperSymbol = Compilation.GetTypeByMetadataName(typeof(Invalid_InheritedViewComponent).FullName);
|
||||
|
||||
// Act
|
||||
var isViewComponent = testVisitor.IsViewComponent(tagHelperSymbol);
|
||||
|
||||
// Assert
|
||||
Assert.False(isViewComponent);
|
||||
}
|
||||
|
||||
public class Invalid_NestedPublicTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_NestedPublicViewComponent
|
||||
{
|
||||
public string Invoke(string foo) => null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Invalid_AbstractTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Invalid_GenericTagHelper<T> : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
internal class Invalid_InternalTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_PlainTagHelper : TagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_InheritedTagHelper : Valid_PlainTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
public abstract class Invalid_AbstractViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
public class Invalid_GenericViewComponent<T>
|
||||
{
|
||||
}
|
||||
|
||||
internal class Invalid_InternalViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_PlainViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
[TestViewComponent]
|
||||
public class Valid_DecoratedVC
|
||||
{
|
||||
}
|
||||
|
||||
public class Valid_InheritedVC : Valid_DecoratedVC
|
||||
{
|
||||
}
|
||||
|
||||
[TestNonViewComponent]
|
||||
public class Invalid_DecoratedViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
[TestViewComponent]
|
||||
public class Invalid_InheritedViewComponent : Invalid_DecoratedViewComponent
|
||||
{
|
||||
}
|
||||
|
||||
public class TestViewComponentAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
public class TestNonViewComponentAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue