Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal sealed class DefaultRazorTagHelperContextDiscoveryPhase : RazorEnginePh
{
protected override void ExecuteCore(RazorCodeDocument codeDocument)
{
var syntaxTree = codeDocument.GetSyntaxTree();
var syntaxTree = codeDocument.GetPreTagHelperSyntaxTree() ?? codeDocument.GetSyntaxTree();
ThrowForMissingDocumentDependency(syntaxTree);

var descriptors = codeDocument.GetTagHelpers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
using Microsoft.AspNetCore.Razor.Language;
Expand Down Expand Up @@ -66,25 +67,25 @@ private static RazorProjectEngine GetDeclarationProjectEngine(
return discoveryProjectEngine;
}

private static RazorProjectEngine GetDiscoveryProjectEngine(
IReadOnlyList<MetadataReference> references,
StaticCompilationTagHelperFeature tagHelperFeature)
private static StaticCompilationTagHelperFeature GetStaticTagHelperFeature(Compilation compilation)
{
var tagHelperFeature = new StaticCompilationTagHelperFeature(compilation);

// the tagHelperFeature will have its Engine property set as part of adding it to the engine, which is used later when doing the actual discovery
var discoveryProjectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, new VirtualRazorProjectFileSystem(), b =>
{
b.Features.Add(new DefaultMetadataReferenceFeature { References = references });
b.Features.Add(new DefaultMetadataReferenceFeature { References = compilation.References.ToImmutableArray() });
b.Features.Add(tagHelperFeature);
b.Features.Add(new DefaultTagHelperDescriptorProvider());

CompilerFeatures.Register(b);
RazorExtensions.Register(b);
});

return discoveryProjectEngine;
return tagHelperFeature;
}

private static RazorProjectEngine GetGenerationProjectEngine(
IReadOnlyList<TagHelperDescriptor> tagHelpers,
private static SourceGeneratorProjectEngine GetGenerationProjectEngine(
SourceGeneratorProjectItem item,
IEnumerable<SourceGeneratorProjectItem> imports,
RazorSourceGenerationOptions razorSourceGeneratorOptions,
Expand All @@ -97,7 +98,7 @@ private static RazorProjectEngine GetGenerationProjectEngine(
fileSystem.Add(import);
}

var projectEngine = RazorProjectEngine.Create(razorSourceGeneratorOptions.Configuration, fileSystem, b =>
var projectEngine = (DefaultRazorProjectEngine)RazorProjectEngine.Create(razorSourceGeneratorOptions.Configuration, fileSystem, b =>
{
b.Features.Add(new DefaultTypeNameFeature());
b.SetRootNamespace(razorSourceGeneratorOptions.RootNamespace);
Expand All @@ -110,16 +111,13 @@ private static RazorProjectEngine GetGenerationProjectEngine(
options.SuppressAddComponentParameter = !isAddComponentParameterAvailable;
}));

b.Features.Add(new StaticTagHelperFeature { TagHelpers = tagHelpers });
b.Features.Add(new DefaultTagHelperDescriptorProvider());

CompilerFeatures.Register(b);
RazorExtensions.Register(b);

b.SetCSharpLanguageVersion(razorSourceGeneratorOptions.CSharpLanguageVersion);
});

return projectEngine;
return new SourceGeneratorProjectEngine(projectEngine);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Razor;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.CodeAnalysis;
Expand Down Expand Up @@ -80,6 +81,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
var generatedDeclarationCode = componentFiles
.Combine(importFiles.Collect())
.Combine(razorSourceGeneratorOptions)
.WithLambdaComparer((old, @new) => (old.Right.Equals(@new.Right) && old.Left.Left.Equals(@new.Left.Left) && old.Left.Right.SequenceEqual(@new.Left.Right)), getHashCode: (a) => Assumed.Unreachable<int>())
.Select(static (pair, _) =>
{
var ((sourceItem, importFiles), razorSourceGeneratorOptions) = pair;
Expand All @@ -98,30 +100,31 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

var generatedDeclarationSyntaxTrees = generatedDeclarationCode
.Combine(parseOptions)
.Select(static (pair, _) =>
.Select(static (pair, ct) =>
{
var (generatedDeclarationCode, parseOptions) = pair;
return CSharpSyntaxTree.ParseText(generatedDeclarationCode, (CSharpParseOptions)parseOptions);
return CSharpSyntaxTree.ParseText(generatedDeclarationCode, (CSharpParseOptions)parseOptions, cancellationToken: ct);
});

var declCompilation = generatedDeclarationSyntaxTrees
.Collect()
.Combine(compilation)
.Select(static (pair, _) =>
{
return pair.Right.AddSyntaxTrees(pair.Left);
});

var tagHelpersFromCompilation = compilation
.Combine(generatedDeclarationSyntaxTrees.Collect())
var tagHelpersFromCompilation = declCompilation
.Combine(razorSourceGeneratorOptions)
.Select(static (pair, _) =>
{
RazorSourceGeneratorEventSource.Log.DiscoverTagHelpersFromCompilationStart();

var ((compilation, generatedDeclarationSyntaxTrees), razorSourceGeneratorOptions) = pair;

var tagHelperFeature = new StaticCompilationTagHelperFeature();
var discoveryProjectEngine = GetDiscoveryProjectEngine(compilation.References.ToImmutableArray(), tagHelperFeature);

var compilationWithDeclarations = compilation.AddSyntaxTrees(generatedDeclarationSyntaxTrees);
var (compilation, razorSourceGeneratorOptions) = pair;

tagHelperFeature.Compilation = compilationWithDeclarations;
tagHelperFeature.TargetSymbol = compilationWithDeclarations.Assembly;

var result = (IList<TagHelperDescriptor>)tagHelperFeature.GetDescriptors();
var tagHelperFeature = GetStaticTagHelperFeature(compilation);
var result = tagHelperFeature.GetDescriptors(compilation.Assembly);

RazorSourceGeneratorEventSource.Log.DiscoverTagHelpersFromCompilationStop();
return result;
})
Expand Down Expand Up @@ -181,17 +184,14 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
return ImmutableArray<TagHelperDescriptor>.Empty;
}

var tagHelperFeature = new StaticCompilationTagHelperFeature();
var discoveryProjectEngine = GetDiscoveryProjectEngine(compilation.References.ToImmutableArray(), tagHelperFeature);
var tagHelperFeature = GetStaticTagHelperFeature(compilation);

List<TagHelperDescriptor> descriptors = new();
tagHelperFeature.Compilation = compilation;
foreach (var reference in compilation.References)
{
if (compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
{
tagHelperFeature.TargetSymbol = assembly;
descriptors.AddRange(tagHelperFeature.GetDescriptors());
descriptors.AddRange(tagHelperFeature.GetDescriptors(assembly));
}
}

Expand Down Expand Up @@ -219,7 +219,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

var withOptions = sourceItems
.Combine(importFiles.Collect())
.Combine(allTagHelpers)
.WithLambdaComparer((old, @new) => old.Left.Equals(@new.Left) && old.Right.SequenceEqual(@new.Right), (a) => a.GetHashCode())
.Combine(razorSourceGeneratorOptions);

var withOptionsDesignTime = withOptions
Expand All @@ -238,31 +238,66 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
t.GetMembers("AddComponentParameter").Any(static m => m.DeclaredAccessibility == Accessibility.Public), compilation);
});

IncrementalValuesProvider<(string, RazorCodeDocument)> processed(bool designTime) => (designTime ? withOptionsDesignTime : withOptions)
IncrementalValuesProvider<(string, SourceGeneratorRazorCodeDocument)> processed(bool designTime) => (designTime ? withOptionsDesignTime : withOptions)
.Combine(isAddComponentParameterAvailable)
.Select((pair, _) =>
{
var ((((sourceItem, imports), allTagHelpers), razorSourceGeneratorOptions), isAddComponentParameterAvailable) = pair;
var (((sourceItem, imports), razorSourceGeneratorOptions), isAddComponentParameterAvailable) = pair;

var kind = designTime ? "DesignTime" : "Runtime";
RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStart(sourceItem.FilePath, kind);
RazorSourceGeneratorEventSource.Log.ParseRazorDocumentStart(sourceItem.RelativePhysicalPath);

var projectEngine = GetGenerationProjectEngine(sourceItem, imports, razorSourceGeneratorOptions, isAddComponentParameterAvailable);

var projectEngine = GetGenerationProjectEngine(allTagHelpers, sourceItem, imports, razorSourceGeneratorOptions,
isAddComponentParameterAvailable: isAddComponentParameterAvailable);
var document = projectEngine.ProcessInitialParse(sourceItem, designTime);

var codeDocument = designTime
? projectEngine.ProcessDesignTime(sourceItem)
: projectEngine.Process(sourceItem);
RazorSourceGeneratorEventSource.Log.ParseRazorDocumentStop(sourceItem.RelativePhysicalPath);
return (projectEngine, sourceItem.RelativePhysicalPath, document);
})

RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStop(sourceItem.FilePath, kind);
return (filePath: sourceItem.RelativePhysicalPath, codeDocument);
// Add the tag helpers in, but ignore if they've changed or not, only reprocessing the actual document changed
.Combine(allTagHelpers)
.WithLambdaComparer((old, @new) => old.Left.Equals(@new.Left), getHashCode: (item) => Assumed.Unreachable<int>())
.Select(static (pair, _) =>
{
var ((projectEngine, filePath, codeDocument), allTagHelpers) = pair;
RazorSourceGeneratorEventSource.Log.RewriteTagHelpersStart(filePath);

codeDocument = projectEngine.ProcessTagHelpers(codeDocument, allTagHelpers, checkForIdempotency: false);

RazorSourceGeneratorEventSource.Log.RewriteTagHelpersStop(filePath);
return (projectEngine, filePath, codeDocument);
})

// next we do a second parse, along with the helpers, but check for idempotency. If the tag helpers used on the previous parse match, the compiler can skip re-writing them
.Combine(allTagHelpers)
.Select(static (pair, _) =>
{

var ((projectEngine, filePath, document), allTagHelpers) = pair;
RazorSourceGeneratorEventSource.Log.CheckAndRewriteTagHelpersStart(filePath);

document = projectEngine.ProcessTagHelpers(document, allTagHelpers, checkForIdempotency: true);

RazorSourceGeneratorEventSource.Log.CheckAndRewriteTagHelpersStop(filePath);
return (projectEngine, filePath, document);
})
.Select((pair, _) =>
{
var (projectEngine, filePath, document) = pair;

var kind = designTime ? "DesignTime" : "Runtime";
RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStart(filePath, kind);
document = projectEngine.ProcessRemaining(document);

RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStop(filePath, kind);
return (filePath, document);
});

var csharpDocuments = processed(designTime: false)
.Select(static (pair, _) =>
{
var (filePath, document) = pair;
return (filePath, csharpDocument: document.GetCSharpDocument());
return (filePath, csharpDocument: document.CodeDocument.GetCSharpDocument());
})
.WithLambdaComparer(static (a, b) =>
{
Expand Down Expand Up @@ -297,9 +332,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
{
var (filePath, document) = pair;
var hintName = GetIdentifierFromPath(filePath);
context.AddOutput(hintName + ".rsg.cs", document.GetCSharpDocument().GeneratedCode);
context.AddOutput(hintName + ".rsg.html", document.GetHtmlDocument().GeneratedCode);
context.AddOutput(hintName + ".rsg.cs", document.CodeDocument.GetCSharpDocument().GeneratedCode);
context.AddOutput(hintName + ".rsg.html", document.CodeDocument.GetHtmlDocument().GeneratedCode);
});
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,29 @@ private RazorSourceGeneratorEventSource() { }
private const int GenerateDeclarationSyntaxTreeStopId = 14;
[Event(GenerateDeclarationSyntaxTreeStopId, Level = EventLevel.Informational)]
public void GenerateDeclarationSyntaxTreeStop() => WriteEvent(GenerateDeclarationSyntaxTreeStopId);

private const int ParseRazorDocumentStartId = 15;
[Event(ParseRazorDocumentStartId, Level = EventLevel.Informational)]
public void ParseRazorDocumentStart(string file) => WriteEvent(ParseRazorDocumentStartId, file);

private const int ParseRazorDocumentStopId = 16;
[Event(ParseRazorDocumentStopId, Level = EventLevel.Informational)]
public void ParseRazorDocumentStop(string file) => WriteEvent(ParseRazorDocumentStopId, file);

private const int RewriteTagHelpersStartId = 17;
[Event(RewriteTagHelpersStartId, Level = EventLevel.Informational)]
public void RewriteTagHelpersStart(string file) => WriteEvent(RewriteTagHelpersStartId, file);

private const int RewriteTagHelpersStopId = 18;
[Event(RewriteTagHelpersStopId, Level = EventLevel.Informational)]
public void RewriteTagHelpersStop(string file) => WriteEvent(RewriteTagHelpersStopId, file);

private const int CheckAndRewriteTagHelpersStartId = 19;
[Event(CheckAndRewriteTagHelpersStartId, Level = EventLevel.Informational)]
public void CheckAndRewriteTagHelpersStart(string file) => WriteEvent(CheckAndRewriteTagHelpersStartId, file);

private const int CheckAndRewriteTagHelpersStopId = 20;
[Event(CheckAndRewriteTagHelpersStopId, Level = EventLevel.Informational)]
public void CheckAndRewriteTagHelpersStop(string file) => WriteEvent(CheckAndRewriteTagHelpersStopId, file);
}
}
Loading