Better support for _Imports.razor (dotnet/aspnetcore-tooling#357)
* Better support for _Imports.razor
* Special case component imports when generating code
* Prevent a future VS crash
* Rebased and updated
* update
* Removed unnecessary newline
\n\nCommit migrated from abbfe00bdc
This commit is contained in:
parent
784596aba6
commit
730f3cdc6b
|
|
@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.Razor.Language {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file.
|
||||
/// Looks up a localized string similar to The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor file.
|
||||
/// </summary>
|
||||
internal static string PageDirectiveCannotBeImported {
|
||||
get {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@
|
|||
<value>TypeName</value>
|
||||
</data>
|
||||
<data name="PageDirectiveCannotBeImported" xml:space="preserve">
|
||||
<value>The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor cshtml file</value>
|
||||
<value>The '@{0}' directive specified in {1} file will not be imported. The directive must appear at the top of each Razor file</value>
|
||||
</data>
|
||||
<data name="PageDirective_Description" xml:space="preserve">
|
||||
<value>Mark the page as a routable component.</value>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
public static readonly RazorDiagnosticDescriptor UnsupportedTagHelperDirective = new RazorDiagnosticDescriptor(
|
||||
$"{DiagnosticPrefix}9978",
|
||||
() =>
|
||||
"The directives @addTagHelper, @removeTagHelper and @tagHelperPrefix are not valid in a component document." +
|
||||
"The directives @addTagHelper, @removeTagHelper and @tagHelperPrefix are not valid in a component document. " +
|
||||
"Use '@using <namespace>' directive instead.",
|
||||
RazorDiagnosticSeverity.Error);
|
||||
|
||||
|
|
@ -321,5 +321,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
{
|
||||
return RazorDiagnostic.Create(ChildContentHasInvalidParameterOnComponent, source ?? SourceSpan.Undefined, attribute, element);
|
||||
}
|
||||
|
||||
public static readonly RazorDiagnosticDescriptor UnsupportedComponentImportContent =
|
||||
new RazorDiagnosticDescriptor(
|
||||
$"{DiagnosticPrefix}10003",
|
||||
() => "Markup, code and block directives are not valid in component imports.",
|
||||
RazorDiagnosticSeverity.Error);
|
||||
|
||||
public static RazorDiagnostic Create_UnsupportedComponentImportContent(SourceSpan? source)
|
||||
{
|
||||
return RazorDiagnostic.Create(UnsupportedComponentImportContent, source ?? SourceSpan.Undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,47 +70,63 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
}
|
||||
|
||||
@namespace.Content = computedNamespace;
|
||||
|
||||
@class.BaseType = ComponentsApi.ComponentBase.FullTypeName;
|
||||
@class.ClassName = computedClass;
|
||||
@class.Modifiers.Clear();
|
||||
@class.Modifiers.Add("public");
|
||||
|
||||
var documentNode = codeDocument.GetDocumentIntermediateNode();
|
||||
var typeParamReferences = documentNode.FindDirectiveReferences(ComponentTypeParamDirective.Directive);
|
||||
for (var i = 0; i < typeParamReferences.Count; i++)
|
||||
if (FileKinds.IsComponentImport(codeDocument.GetFileKind()))
|
||||
{
|
||||
var typeParamNode = (DirectiveIntermediateNode)typeParamReferences[i].Node;
|
||||
if (typeParamNode.HasDiagnostics)
|
||||
// We don't want component imports to be considered as real component.
|
||||
// But we still want to generate code for it so we can get diagnostics.
|
||||
@class.BaseType = typeof(object).FullName;
|
||||
|
||||
method.ReturnType = "void";
|
||||
method.MethodName = "Execute";
|
||||
method.Modifiers.Clear();
|
||||
method.Modifiers.Add("protected");
|
||||
|
||||
method.Parameters.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@class.BaseType = ComponentsApi.ComponentBase.FullTypeName;
|
||||
|
||||
var documentNode = codeDocument.GetDocumentIntermediateNode();
|
||||
var typeParamReferences = documentNode.FindDirectiveReferences(ComponentTypeParamDirective.Directive);
|
||||
for (var i = 0; i < typeParamReferences.Count; i++)
|
||||
{
|
||||
continue;
|
||||
var typeParamNode = (DirectiveIntermediateNode)typeParamReferences[i].Node;
|
||||
if (typeParamNode.HasDiagnostics)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@class.TypeParameters.Add(new TypeParameter() { ParameterName = typeParamNode.Tokens.First().Content, });
|
||||
}
|
||||
|
||||
@class.TypeParameters.Add(new TypeParameter() { ParameterName = typeParamNode.Tokens.First().Content, });
|
||||
method.ReturnType = "void";
|
||||
method.MethodName = ComponentsApi.ComponentBase.BuildRenderTree;
|
||||
method.Modifiers.Clear();
|
||||
method.Modifiers.Add("protected");
|
||||
method.Modifiers.Add("override");
|
||||
|
||||
method.Parameters.Clear();
|
||||
method.Parameters.Add(new MethodParameter()
|
||||
{
|
||||
ParameterName = "builder",
|
||||
TypeName = ComponentsApi.RenderTreeBuilder.FullTypeName,
|
||||
});
|
||||
|
||||
// We need to call the 'base' method as the first statement.
|
||||
var callBase = new CSharpCodeIntermediateNode();
|
||||
callBase.Annotations.Add(BuildRenderTreeBaseCallAnnotation, true);
|
||||
callBase.Children.Add(new IntermediateToken
|
||||
{
|
||||
Kind = TokenKind.CSharp,
|
||||
Content = $"base.{ComponentsApi.ComponentBase.BuildRenderTree}(builder);"
|
||||
});
|
||||
method.Children.Insert(0, callBase);
|
||||
}
|
||||
|
||||
method.ReturnType = "void";
|
||||
method.MethodName = ComponentsApi.ComponentBase.BuildRenderTree;
|
||||
method.Modifiers.Clear();
|
||||
method.Modifiers.Add("protected");
|
||||
method.Modifiers.Add("override");
|
||||
|
||||
method.Parameters.Clear();
|
||||
method.Parameters.Add(new MethodParameter()
|
||||
{
|
||||
ParameterName = "builder",
|
||||
TypeName = ComponentsApi.RenderTreeBuilder.FullTypeName,
|
||||
});
|
||||
|
||||
// We need to call the 'base' method as the first statement.
|
||||
var callBase = new CSharpCodeIntermediateNode();
|
||||
callBase.Annotations.Add(BuildRenderTreeBaseCallAnnotation, true);
|
||||
callBase.Children.Add(new IntermediateToken
|
||||
{
|
||||
Kind = TokenKind.CSharp,
|
||||
Content = $"base.{ComponentsApi.ComponentBase.BuildRenderTree}(builder);"
|
||||
});
|
||||
method.Children.Insert(0, callBase);
|
||||
}
|
||||
|
||||
internal static bool IsBuildRenderTreeBaseCall(CSharpCodeIntermediateNode node)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(FileKinds.Component, Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Component, FileKinds.ComponentImport);
|
||||
builder.Features.Add(new ComponentInjectDirectivePass());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(FileKinds.Component, Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Component, FileKinds.ComponentImport);
|
||||
builder.Features.Add(new ComponentLayoutDirectivePass());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
attributeNode.Children.Add(new IntermediateToken()
|
||||
{
|
||||
Kind = TokenKind.CSharp,
|
||||
Content = $"[{ComponentsApi.LayoutAttribute.FullTypeName}(typeof({token.Content}))]" + Environment.NewLine,
|
||||
Content = $"[{ComponentsApi.LayoutAttribute.FullTypeName}(typeof({token.Content}))]",
|
||||
});
|
||||
|
||||
// Insert the new attribute on top of the class
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(FileKinds.Component, Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Component, FileKinds.ComponentImport);
|
||||
builder.Features.Add(new ComponentPageDirectivePass());
|
||||
return builder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
for (var i = 0; i < directives.Count; i++)
|
||||
{
|
||||
var directive = directives[i];
|
||||
if (directive.Node.IsImported())
|
||||
if (FileKinds.IsComponentImport(codeDocument.GetFileKind()) || directive.Node.IsImported())
|
||||
{
|
||||
directive.Node.Diagnostics.Add(ComponentDiagnosticFactory.CreatePageDirective_CannotBeImported(directive.Node.Source.Value));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(FileKinds.Component, Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Component, FileKinds.ComponentImport);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,21 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
{
|
||||
internal class DefaultRazorDirectiveFeature : RazorEngineFeatureBase, IRazorDirectiveFeature, IConfigureRazorParserOptionsFeature
|
||||
{
|
||||
public ICollection<DirectiveDescriptor> Directives { get; } = new List<DirectiveDescriptor>();
|
||||
// To maintain backwards compatibility, adding to this list will default to legacy file kind.
|
||||
public ICollection<DirectiveDescriptor> Directives
|
||||
{
|
||||
get
|
||||
{
|
||||
ICollection<DirectiveDescriptor> result;
|
||||
if (!DirectivesByFileKind.TryGetValue(FileKinds.Legacy, out result))
|
||||
{
|
||||
result = new List<DirectiveDescriptor>();
|
||||
DirectivesByFileKind.Add(FileKinds.Legacy, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, ICollection<DirectiveDescriptor>> DirectivesByFileKind { get; } = new Dictionary<string, ICollection<DirectiveDescriptor>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
|
|
@ -24,22 +38,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
options.Directives.Clear();
|
||||
|
||||
foreach (var directive in Directives)
|
||||
{
|
||||
options.Directives.Add(directive);
|
||||
}
|
||||
|
||||
if (options.FileKind != null && DirectivesByFileKind.TryGetValue(options.FileKind, out var directives))
|
||||
var fileKind = options.FileKind ?? FileKinds.Legacy;
|
||||
if (DirectivesByFileKind.TryGetValue(fileKind, out var directives))
|
||||
{
|
||||
foreach (var directive in directives)
|
||||
{
|
||||
// Replace any non-file-kind-specific directives
|
||||
var replaces = options.Directives.Where(d => string.Equals(d.Directive, directive.Directive, StringComparison.Ordinal)).ToArray();
|
||||
foreach (var replace in replaces)
|
||||
{
|
||||
options.Directives.Remove(replace);
|
||||
}
|
||||
|
||||
options.Directives.Add(directive);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,17 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
// We need to decide up front if this document is a "component" file. This will affect how
|
||||
// lowering behaves.
|
||||
LoweringVisitor visitor;
|
||||
if (FileKinds.IsComponent(codeDocument.GetFileKind()) &&
|
||||
if (FileKinds.IsComponentImport(codeDocument.GetFileKind()) &&
|
||||
syntaxTree.Options.FeatureFlags.AllowComponentFileKind)
|
||||
{
|
||||
visitor = new ComponentImportFileKindVisitor(document, builder, syntaxTree.Options.FeatureFlags)
|
||||
{
|
||||
SourceDocument = syntaxTree.Source,
|
||||
};
|
||||
|
||||
visitor.Visit(syntaxTree.Root);
|
||||
}
|
||||
else if (FileKinds.IsComponent(codeDocument.GetFileKind()) &&
|
||||
syntaxTree.Options.FeatureFlags.AllowComponentFileKind)
|
||||
{
|
||||
visitor = new ComponentFileKindVisitor(document, builder, syntaxTree.Options.FeatureFlags)
|
||||
|
|
@ -1856,6 +1866,58 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
}
|
||||
}
|
||||
|
||||
private class ComponentImportFileKindVisitor : LoweringVisitor
|
||||
{
|
||||
public ComponentImportFileKindVisitor(
|
||||
DocumentIntermediateNode document,
|
||||
IntermediateNodeBuilder builder,
|
||||
RazorParserFeatureFlags featureFlags)
|
||||
: base(document, builder, featureFlags)
|
||||
{
|
||||
}
|
||||
|
||||
public override void DefaultVisit(SyntaxNode node)
|
||||
{
|
||||
base.DefaultVisit(node);
|
||||
}
|
||||
|
||||
public override void VisitMarkupElement(MarkupElementSyntax node)
|
||||
{
|
||||
_document.Diagnostics.Add(
|
||||
ComponentDiagnosticFactory.Create_UnsupportedComponentImportContent(BuildSourceSpanFromNode(node)));
|
||||
}
|
||||
|
||||
public override void VisitMarkupCommentBlock(MarkupCommentBlockSyntax node)
|
||||
{
|
||||
_document.Diagnostics.Add(
|
||||
ComponentDiagnosticFactory.Create_UnsupportedComponentImportContent(BuildSourceSpanFromNode(node)));
|
||||
}
|
||||
|
||||
public override void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
|
||||
{
|
||||
_document.Diagnostics.Add(
|
||||
ComponentDiagnosticFactory.Create_UnsupportedComponentImportContent(BuildSourceSpanFromNode(node)));
|
||||
}
|
||||
|
||||
public override void VisitCSharpImplicitExpression(CSharpImplicitExpressionSyntax node)
|
||||
{
|
||||
_document.Diagnostics.Add(
|
||||
ComponentDiagnosticFactory.Create_UnsupportedComponentImportContent(BuildSourceSpanFromNode(node)));
|
||||
}
|
||||
|
||||
public override void VisitCSharpExplicitExpression(CSharpExplicitExpressionSyntax node)
|
||||
{
|
||||
_document.Diagnostics.Add(
|
||||
ComponentDiagnosticFactory.Create_UnsupportedComponentImportContent(BuildSourceSpanFromNode(node)));
|
||||
}
|
||||
|
||||
public override void VisitCSharpStatement(CSharpStatementSyntax node)
|
||||
{
|
||||
_document.Diagnostics.Add(
|
||||
ComponentDiagnosticFactory.Create_UnsupportedComponentImportContent(BuildSourceSpanFromNode(node)));
|
||||
}
|
||||
}
|
||||
|
||||
private class ImportsVisitor : LoweringVisitor
|
||||
{
|
||||
public ImportsVisitor(DocumentIntermediateNode document, IntermediateNodeBuilder builder, RazorParserFeatureFlags featureFlags)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
// The imports come logically before the main razor file and are in the order they
|
||||
// should be processed.
|
||||
DirectiveVisitor visitor = null;
|
||||
if (FileKinds.IsComponent(codeDocument.GetFileKind()))
|
||||
var parserOptions = codeDocument.GetParserOptions();
|
||||
if (FileKinds.IsComponent(codeDocument.GetFileKind()) &&
|
||||
(parserOptions == null || parserOptions.FeatureFlags.AllowComponentFileKind))
|
||||
{
|
||||
codeDocument.TryComputeNamespaceAndClass(out var currentNamespace, out var _);
|
||||
visitor = new ComponentDirectiveVisitor(codeDocument.Source.FilePath, descriptors, currentNamespace);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Legacy, FileKinds.Component);
|
||||
builder.Features.Add(new FunctionsDirectivePass());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Legacy, FileKinds.Component, FileKinds.ComponentImport);
|
||||
builder.Features.Add(new ImplementsDirectivePass());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Legacy, FileKinds.Component, FileKinds.ComponentImport);
|
||||
builder.Features.Add(new InheritsDirectivePass());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.AddDirective(Directive, FileKinds.Legacy, FileKinds.Component);
|
||||
builder.Features.Add(new SectionDirectivePass());
|
||||
builder.AddTargetExtension(new SectionTargetExtension());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,23 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return string.Equals(fileKind, FileKinds.ComponentImport, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static string GetComponentFileKindFromFilePath(string filePath)
|
||||
{
|
||||
if (filePath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
if (string.Equals(ComponentMetadata.ImportsFileName, Path.GetFileName(filePath), StringComparison.Ordinal))
|
||||
{
|
||||
return FileKinds.ComponentImport;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FileKinds.Component;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFileKindFromFilePath(string filePath)
|
||||
{
|
||||
if (filePath == null)
|
||||
|
|
|
|||
|
|
@ -166,35 +166,38 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
/// Adds the specified <see cref="DirectiveDescriptor"/> for the provided file kind.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="RazorProjectEngineBuilder"/>.</param>
|
||||
/// <param name="fileKind">The file kind, for which to register the directive. See <see cref="FileKinds"/>.</param>
|
||||
/// <param name="directive">The <see cref="DirectiveDescriptor"/> to add.</param>
|
||||
/// <param name="fileKinds">The file kinds, for which to register the directive. See <see cref="FileKinds"/>.</param>
|
||||
/// <returns>The <see cref="RazorProjectEngineBuilder"/>.</returns>
|
||||
public static RazorProjectEngineBuilder AddDirective(this RazorProjectEngineBuilder builder, string fileKind, DirectiveDescriptor directive)
|
||||
public static RazorProjectEngineBuilder AddDirective(this RazorProjectEngineBuilder builder, DirectiveDescriptor directive, params string[] fileKinds)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (fileKind == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(fileKind));
|
||||
}
|
||||
|
||||
if (directive == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(directive));
|
||||
}
|
||||
|
||||
var directiveFeature = GetDirectiveFeature(builder);
|
||||
|
||||
if (!directiveFeature.DirectivesByFileKind.TryGetValue(fileKind, out var directives))
|
||||
if (fileKinds == null)
|
||||
{
|
||||
directives = new List<DirectiveDescriptor>();
|
||||
directiveFeature.DirectivesByFileKind.Add(fileKind, directives);
|
||||
throw new ArgumentNullException(nameof(fileKinds));
|
||||
}
|
||||
|
||||
directives.Add(directive);
|
||||
var directiveFeature = GetDirectiveFeature(builder);
|
||||
|
||||
foreach (var fileKind in fileKinds)
|
||||
{
|
||||
if (!directiveFeature.DirectivesByFileKind.TryGetValue(fileKind, out var directives))
|
||||
{
|
||||
directives = new List<DirectiveDescriptor>();
|
||||
directiveFeature.DirectivesByFileKind.Add(fileKind, directives);
|
||||
}
|
||||
|
||||
directives.Add(directive);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Components;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
|
@ -286,6 +287,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
{
|
||||
var outputPath = Path.Combine(projectDirectory, outputs[i]);
|
||||
var fileKind = fileKinds.Count > 0 ? fileKinds[i] : "mvc";
|
||||
if (Language.FileKinds.IsComponent(fileKind))
|
||||
{
|
||||
fileKind = Language.FileKinds.GetComponentFileKindFromFilePath(sources[i]);
|
||||
}
|
||||
|
||||
items[i] = new SourceItem(sources[i], outputs[i], relativePath[i], fileKind);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
{
|
||||
AdditionalSyntaxTrees = new List<SyntaxTree>();
|
||||
AdditionalRazorItems = new List<RazorProjectItem>();
|
||||
ImportItems = new List<RazorProjectItem>();
|
||||
|
||||
BaseCompilation = DefaultBaseCompilation;
|
||||
Configuration = RazorConfiguration.Default;
|
||||
|
|
@ -72,6 +73,8 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
|
||||
internal List<RazorProjectItem> AdditionalRazorItems { get; }
|
||||
|
||||
internal List<RazorProjectItem> ImportItems { get; }
|
||||
|
||||
internal List<SyntaxTree> AdditionalSyntaxTrees { get; }
|
||||
|
||||
internal virtual CSharpCompilation BaseCompilation { get; }
|
||||
|
|
@ -118,6 +121,8 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
// Turn off checksums, we're testing code generation.
|
||||
b.Features.Add(new SuppressChecksum());
|
||||
|
||||
b.Features.Add(new TestImportProjectFeature(ImportItems));
|
||||
|
||||
if (LineEnding != null)
|
||||
{
|
||||
b.Phases.Insert(0, new ForceLineEndingPhase(LineEnding));
|
||||
|
|
@ -135,7 +140,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
});
|
||||
}
|
||||
|
||||
internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent)
|
||||
internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent, string fileKind = null)
|
||||
{
|
||||
var fullPath = WorkingDirectory + PathSeparator + cshtmlRelativePath;
|
||||
|
||||
|
|
@ -156,7 +161,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
physicalPath: fullPath,
|
||||
relativePhysicalPath: cshtmlRelativePath,
|
||||
basePath: WorkingDirectory,
|
||||
fileKind: FileKind)
|
||||
fileKind: fileKind ?? FileKind)
|
||||
{
|
||||
Content = cshtmlContent.TrimStart(),
|
||||
};
|
||||
|
|
@ -167,7 +172,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
return CompileToCSharp(DefaultFileName, cshtmlContent, throwOnFailure);
|
||||
}
|
||||
|
||||
protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true)
|
||||
protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true, string fileKind = null)
|
||||
{
|
||||
if (DeclarationOnly && DesignTime)
|
||||
{
|
||||
|
|
@ -197,7 +202,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
}
|
||||
|
||||
// Result of generating declarations
|
||||
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent);
|
||||
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
|
||||
codeDocument = projectEngine.ProcessDeclarationOnly(projectItem);
|
||||
var declaration = new CompileToCSharpResult
|
||||
{
|
||||
|
|
@ -243,7 +248,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
// This will include the built-in components.
|
||||
var projectEngine = CreateProjectEngine(Configuration, BaseCompilation.References.ToArray());
|
||||
|
||||
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent);
|
||||
var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
|
||||
|
||||
RazorCodeDocument codeDocument;
|
||||
if (DeclarationOnly)
|
||||
|
|
@ -456,5 +461,22 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
|
|||
codeDocument.Items[key] = LineEnding;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestImportProjectFeature : IImportProjectFeature
|
||||
{
|
||||
private List<RazorProjectItem> _imports;
|
||||
|
||||
public TestImportProjectFeature(List<RazorProjectItem> imports)
|
||||
{
|
||||
_imports = imports;
|
||||
}
|
||||
|
||||
public RazorProjectEngine ProjectEngine { get; set; }
|
||||
|
||||
public IReadOnlyList<RazorProjectItem> GetImports(RazorProjectItem projectItem)
|
||||
{
|
||||
return _imports;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue