Begin integrating with real Razor compiler
This commit is contained in:
parent
a03cb48c7a
commit
3ccdc1d16f
|
|
@ -1,3 +1,2 @@
|
||||||
@inherits Microsoft.Blazor.Components.BlazorComponent
|
<h1>Hello, world!</h1>
|
||||||
<h1>Hello, world!</h1>
|
|
||||||
Hello from the Razor component.
|
Hello from the Razor component.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.Blazor.Build.Core.RazorCompilation.Engine
|
||||||
|
{
|
||||||
|
internal static class BlazorCodeDocItems
|
||||||
|
{
|
||||||
|
public static object ClassName = new object();
|
||||||
|
public static object Namespace = new object();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// 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.Language.CodeGeneration;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.Blazor.Build.Core.RazorCompilation.Engine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Directs a <see cref="DocumentWriter"/> to use <see cref="BlazorIntermediateNodeWriter"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal class BlazorCodeTarget : CodeTarget
|
||||||
|
{
|
||||||
|
public override IntermediateNodeWriter CreateNodeWriter()
|
||||||
|
=> new BlazorIntermediateNodeWriter();
|
||||||
|
|
||||||
|
public override TExtension GetExtension<TExtension>()
|
||||||
|
=> throw new NotImplementedException();
|
||||||
|
|
||||||
|
public override bool HasExtension<TExtension>()
|
||||||
|
=> throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// 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.Language.CodeGeneration;
|
||||||
|
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||||
|
|
||||||
|
namespace Microsoft.Blazor.Build.Core.RazorCompilation.Engine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Generates the C# code corresponding to Razor source document contents.
|
||||||
|
/// </summary>
|
||||||
|
internal class BlazorIntermediateNodeWriter : IntermediateNodeWriter
|
||||||
|
{
|
||||||
|
public override void BeginWriterScope(CodeRenderingContext context, string writer)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(BeginWriterScope));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EndWriterScope(CodeRenderingContext context)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(EndWriterScope));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteCSharpCode(CodeRenderingContext context, CSharpCodeIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteCSharpCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteCSharpCodeAttributeValue(CodeRenderingContext context, CSharpCodeAttributeValueIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteCSharpCodeAttributeValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteCSharpExpression(CodeRenderingContext context, CSharpExpressionIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteCSharpExpression));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteCSharpExpressionAttributeValue(CodeRenderingContext context, CSharpExpressionAttributeValueIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteCSharpExpressionAttributeValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteHtmlAttribute(CodeRenderingContext context, HtmlAttributeIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteHtmlAttribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteHtmlAttributeValue(CodeRenderingContext context, HtmlAttributeValueIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteHtmlAttributeValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteHtmlContent(CodeRenderingContext context, HtmlContentIntermediateNode node)
|
||||||
|
{
|
||||||
|
context.CodeWriter.Write("/* HTML content */");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteUsingDirective(CodeRenderingContext context, UsingDirectiveIntermediateNode node)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException(nameof(WriteUsingDirective));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
// 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.Language;
|
||||||
|
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
||||||
|
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.Blazor.Build.Core.RazorCompilation.Engine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="RazorEngine"/> phase that builds the C# document corresponding to
|
||||||
|
/// a <see cref="RazorCodeDocument"/> for a Blazor component.
|
||||||
|
/// </summary>
|
||||||
|
internal class BlazorLoweringPhase : IRazorCSharpLoweringPhase
|
||||||
|
{
|
||||||
|
private readonly RazorCodeGenerationOptions _codegenOptions;
|
||||||
|
|
||||||
|
public BlazorLoweringPhase(RazorCodeGenerationOptions codegenOptions)
|
||||||
|
{
|
||||||
|
_codegenOptions = codegenOptions
|
||||||
|
?? throw new ArgumentNullException(nameof(codegenOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RazorEngine Engine { get; set; }
|
||||||
|
|
||||||
|
public void Execute(RazorCodeDocument codeDocument)
|
||||||
|
{
|
||||||
|
var writer = BlazorComponentDocumentWriter.Create(_codegenOptions);
|
||||||
|
var documentNode = codeDocument.GetDocumentIntermediateNode();
|
||||||
|
var csharpDoc = writer.WriteDocument(codeDocument, documentNode);
|
||||||
|
codeDocument.SetCSharpDocument(csharpDoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates <see cref="DocumentWriter"/> instances that are configured to use
|
||||||
|
/// <see cref="BlazorCodeTarget"/>.
|
||||||
|
/// </summary>
|
||||||
|
private class BlazorComponentDocumentWriter : DocumentWriter
|
||||||
|
{
|
||||||
|
public static DocumentWriter Create(RazorCodeGenerationOptions options)
|
||||||
|
=> Instance.Create(new BlazorCodeTarget(), options);
|
||||||
|
|
||||||
|
private static BlazorComponentDocumentWriter Instance
|
||||||
|
= new BlazorComponentDocumentWriter();
|
||||||
|
|
||||||
|
public override RazorCSharpDocument WriteDocument(
|
||||||
|
RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
|
||||||
|
=> throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// 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.Language;
|
||||||
|
using Microsoft.Blazor.Components;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.Blazor.Build.Core.RazorCompilation.Engine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Wraps <see cref="RazorEngine"/>, configuring it to compile Blazor components.
|
||||||
|
/// </summary>
|
||||||
|
internal class BlazorRazorEngine
|
||||||
|
{
|
||||||
|
private readonly RazorEngine _engine;
|
||||||
|
private readonly RazorCodeGenerationOptions _codegenOptions;
|
||||||
|
|
||||||
|
public BlazorRazorEngine()
|
||||||
|
{
|
||||||
|
_codegenOptions = RazorCodeGenerationOptions.CreateDefault();
|
||||||
|
|
||||||
|
_engine = RazorEngine.Create(configure =>
|
||||||
|
{
|
||||||
|
configure.SetBaseType(typeof(BlazorComponent).FullName);
|
||||||
|
|
||||||
|
configure.Phases.Remove(
|
||||||
|
configure.Phases.OfType<IRazorCSharpLoweringPhase>().Single());
|
||||||
|
configure.Phases.Add(new BlazorLoweringPhase(_codegenOptions));
|
||||||
|
|
||||||
|
configure.ConfigureClass((codeDoc, classNode) =>
|
||||||
|
{
|
||||||
|
configure.SetNamespace((string)codeDoc.Items[BlazorCodeDocItems.Namespace]);
|
||||||
|
classNode.ClassName = (string)codeDoc.Items[BlazorCodeDocItems.ClassName];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Process(RazorCodeDocument document)
|
||||||
|
=> _engine.Process(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
|
using Microsoft.Blazor.Build.Core.RazorCompilation.Engine;
|
||||||
|
using Microsoft.Blazor.Components;
|
||||||
|
using Microsoft.Blazor.RenderTree;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
@ -35,7 +39,7 @@ namespace Microsoft.Blazor.Build.Core.RazorCompilation
|
||||||
TextWriter verboseOutput)
|
TextWriter verboseOutput)
|
||||||
=> inputPaths.SelectMany(path =>
|
=> inputPaths.SelectMany(path =>
|
||||||
{
|
{
|
||||||
using (var reader = File.OpenText(path))
|
using (var reader = File.OpenRead(path))
|
||||||
{
|
{
|
||||||
return CompileSingleFile(inputRootPath, path, reader, baseNamespace, resultOutput, verboseOutput);
|
return CompileSingleFile(inputRootPath, path, reader, baseNamespace, resultOutput, verboseOutput);
|
||||||
}
|
}
|
||||||
|
|
@ -53,14 +57,14 @@ namespace Microsoft.Blazor.Build.Core.RazorCompilation
|
||||||
public IEnumerable<RazorCompilerDiagnostic> CompileSingleFile(
|
public IEnumerable<RazorCompilerDiagnostic> CompileSingleFile(
|
||||||
string inputRootPath,
|
string inputRootPath,
|
||||||
string inputFilePath,
|
string inputFilePath,
|
||||||
TextReader inputFileReader,
|
Stream inputFileContents,
|
||||||
string baseNamespace,
|
string baseNamespace,
|
||||||
TextWriter resultOutput,
|
TextWriter resultOutput,
|
||||||
TextWriter verboseOutput)
|
TextWriter verboseOutput)
|
||||||
{
|
{
|
||||||
if (inputFileReader == null)
|
if (inputFileContents == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(inputFileReader));
|
throw new ArgumentNullException(nameof(inputFileContents));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultOutput == null)
|
if (resultOutput == null)
|
||||||
|
|
@ -86,12 +90,20 @@ namespace Microsoft.Blazor.Build.Core.RazorCompilation
|
||||||
? baseNamespace
|
? baseNamespace
|
||||||
: $"{baseNamespace}.{itemNamespace}";
|
: $"{baseNamespace}.{itemNamespace}";
|
||||||
|
|
||||||
resultOutput.WriteLine($"namespace {combinedNamespace} {{");
|
var engine = new BlazorRazorEngine();
|
||||||
resultOutput.WriteLine($"public class {itemClassName}");
|
|
||||||
resultOutput.WriteLine("{");
|
var sourceDoc = RazorSourceDocument.ReadFrom(inputFileContents, inputFilePath);
|
||||||
resultOutput.WriteLine("}");
|
var codeDoc = RazorCodeDocument.Create(sourceDoc);
|
||||||
resultOutput.WriteLine("}");
|
codeDoc.Items[BlazorCodeDocItems.Namespace] = combinedNamespace;
|
||||||
resultOutput.WriteLine();
|
codeDoc.Items[BlazorCodeDocItems.ClassName] = itemClassName;
|
||||||
|
engine.Process(codeDoc);
|
||||||
|
var csharpDocument = codeDoc.GetCSharpDocument();
|
||||||
|
var generatedCode = csharpDocument.GeneratedCode;
|
||||||
|
generatedCode = generatedCode.Replace(
|
||||||
|
"public async override global::System.Threading.Tasks.Task ExecuteAsync()",
|
||||||
|
$"public override void {nameof(BlazorComponent.BuildRenderTree)}({typeof(RenderTreeBuilder).FullName} builder)");
|
||||||
|
|
||||||
|
resultOutput.WriteLine(generatedCode);
|
||||||
|
|
||||||
return Enumerable.Empty<RazorCompilerDiagnostic>();
|
return Enumerable.Empty<RazorCompilerDiagnostic>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Microsoft.Blazor.Browser.JS\Microsoft.Blazor.Browser.JS.csproj" />
|
<ProjectReference Include="..\Microsoft.Blazor.Browser.JS\Microsoft.Blazor.Browser.JS.csproj" />
|
||||||
<ProjectReference Include="..\Microsoft.Blazor.Mono\Microsoft.Blazor.Mono.csproj" />
|
<ProjectReference Include="..\Microsoft.Blazor.Mono\Microsoft.Blazor.Mono.csproj" />
|
||||||
|
<ProjectReference Include="..\Microsoft.Blazor\Microsoft.Blazor.csproj" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Composite" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Composite" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="2.0.0" />
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.Blazor.Build.Core.RazorCompilation;
|
using Microsoft.Blazor.Build.Core.RazorCompilation;
|
||||||
|
using Microsoft.Blazor.Components;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -95,10 +96,17 @@ namespace Microsoft.Blazor.Build.Test
|
||||||
{
|
{
|
||||||
CSharpSyntaxTree.ParseText(csharpResult.Code)
|
CSharpSyntaxTree.ParseText(csharpResult.Code)
|
||||||
};
|
};
|
||||||
var references = new[]
|
var referenceAssembliesContainingTypes = new[]
|
||||||
{
|
{
|
||||||
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)
|
typeof(System.Runtime.AssemblyTargetedPatchBandAttribute), // System.Runtime
|
||||||
|
typeof(BlazorComponent)
|
||||||
};
|
};
|
||||||
|
var references = referenceAssembliesContainingTypes
|
||||||
|
.SelectMany(type => type.Assembly.GetReferencedAssemblies().Concat(new[] { type.Assembly.GetName() }))
|
||||||
|
.Distinct()
|
||||||
|
.Select(Assembly.Load)
|
||||||
|
.Select(assembly => MetadataReference.CreateFromFile(assembly.Location))
|
||||||
|
.ToList();
|
||||||
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
|
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
|
||||||
var assemblyName = "TestAssembly" + Guid.NewGuid().ToString("N");
|
var assemblyName = "TestAssembly" + Guid.NewGuid().ToString("N");
|
||||||
var compilation = CSharpCompilation.Create(assemblyName,
|
var compilation = CSharpCompilation.Create(assemblyName,
|
||||||
|
|
@ -126,12 +134,12 @@ namespace Microsoft.Blazor.Build.Test
|
||||||
using (var resultWriter = new StreamWriter(resultStream))
|
using (var resultWriter = new StreamWriter(resultStream))
|
||||||
using (var verboseLogStream = new MemoryStream())
|
using (var verboseLogStream = new MemoryStream())
|
||||||
using (var verboseWriter = new StreamWriter(verboseLogStream))
|
using (var verboseWriter = new StreamWriter(verboseLogStream))
|
||||||
using (var inputReader = new StringReader(cshtmlContent))
|
using (var inputContents = new MemoryStream(Encoding.UTF8.GetBytes(cshtmlContent)))
|
||||||
{
|
{
|
||||||
var diagnostics = new RazorCompiler().CompileSingleFile(
|
var diagnostics = new RazorCompiler().CompileSingleFile(
|
||||||
cshtmlRootPath,
|
cshtmlRootPath,
|
||||||
cshtmlRelativePath,
|
cshtmlRelativePath,
|
||||||
inputReader,
|
inputContents,
|
||||||
outputNamespace,
|
outputNamespace,
|
||||||
resultWriter,
|
resultWriter,
|
||||||
verboseWriter);
|
verboseWriter);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue