Skip to content

Improve caching in RazorSourceGenerator #18985

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 20, 2021
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 @@ -10,15 +10,9 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
{
internal static class IncrementalValuesProviderExtensions
{
internal static IncrementalValuesProvider<T> WithLambdaComparer<T>(this IncrementalValuesProvider<T> source, Func<T?, T?, bool> equal)
internal static IncrementalValueProvider<T> WithLambdaComparer<T>(this IncrementalValueProvider<T> source, Func<T, T, bool> equal, Func<T, int> getHashCode)
{
var comparer = new LambdaComparer<T>(equal);
return source.WithComparer(comparer);
}

internal static IncrementalValueProvider<T> WithLambdaComparer<T>(this IncrementalValueProvider<T> source, Func<T?, T?, bool> equal)
{
var comparer = new LambdaComparer<T>(equal);
var comparer = new LambdaComparer<T>(equal, getHashCode);
return source.WithComparer(comparer);
}

Expand Down Expand Up @@ -53,15 +47,17 @@ internal static IncrementalValueProvider<TSource> ReportDiagnostics<TSource>(thi

internal class LambdaComparer<T> : IEqualityComparer<T>
{
private readonly Func<T?, T?, bool> _equal;
private readonly Func<T, T, bool> _equal;
private readonly Func<T, int> _getHashCode;

public LambdaComparer(Func<T?, T?, bool> equal)
public LambdaComparer(Func<T, T, bool> equal, Func<T, int> getHashCode)
{
_equal = equal;
_getHashCode = getHashCode;
}

public bool Equals(T? x, T? y) => _equal(x, y);
public bool Equals(T x, T y) => _equal(x, y);

public int GetHashCode(T obj) => EqualityComparer<T>.Default.GetHashCode(obj);
public int GetHashCode(T obj) => _getHashCode(obj);
}
}
}
20 changes: 17 additions & 3 deletions src/RazorSdk/SourceGenerators/RazorSourceGenerationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,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 System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;

namespace Microsoft.NET.Sdk.Razor.SourceGenerators
{
internal class RazorSourceGenerationOptions
internal class RazorSourceGenerationOptions : IEquatable<RazorSourceGenerationOptions>
{
public string RootNamespace { get; set; } = "ASP";

Expand Down Expand Up @@ -40,6 +41,19 @@ internal class RazorSourceGenerationOptions
/// <summary>
/// Gets the CSharp language version currently used by the compilation.
/// </summary>
public LanguageVersion CSharpLanguageVersion { get; set; } = LanguageVersion.Preview;
public LanguageVersion CSharpLanguageVersion { get; set; } = LanguageVersion.CSharp10;

public bool Equals(RazorSourceGenerationOptions other)
{
return RootNamespace == other.RootNamespace &&
Configuration == other.Configuration &&
GenerateMetadataSourceChecksumAttributes == other.GenerateMetadataSourceChecksumAttributes &&
SuppressRazorSourceGenerator == other.SuppressRazorSourceGenerator &&
CSharpLanguageVersion == other.CSharpLanguageVersion;
}

public override bool Equals(object obj) => obj is RazorSourceGenerationOptions other && Equals(other);

public override int GetHashCode() => Configuration.GetHashCode();
}
}
}
51 changes: 26 additions & 25 deletions src/RazorSdk/SourceGenerators/RazorSourceGenerator.Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +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 System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Razor;

namespace Microsoft.NET.Sdk.Razor.SourceGenerators
Expand Down Expand Up @@ -37,7 +33,9 @@ private static string GetIdentifierFromPath(string filePath)
return builder.ToString();
}

private static RazorProjectEngine GetDiscoveryProjectEngine(StaticCompilationTagHelperFeature tagHelperFeature, IEnumerable<MetadataReference> references, IEnumerable<SourceGeneratorProjectItem> items, RazorSourceGenerationOptions razorSourceGeneratorOptions)
private static RazorProjectEngine GetDeclarationProjectEngine(
IEnumerable<SourceGeneratorProjectItem> items,
RazorSourceGenerationOptions razorSourceGeneratorOptions)
{
var fileSystem = new VirtualRazorProjectFileSystem();
foreach (var item in items)
Expand All @@ -56,26 +54,43 @@ private static RazorProjectEngine GetDiscoveryProjectEngine(StaticCompilationTag

b.SetRootNamespace(razorSourceGeneratorOptions.RootNamespace);

b.Features.Add(new DefaultMetadataReferenceFeature { References = references.ToList() });
CompilerFeatures.Register(b);
RazorExtensions.Register(b);

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

return discoveryProjectEngine;
}

private static RazorProjectEngine GetDiscoveryProjectEngine(
IReadOnlyList<MetadataReference> references,
StaticCompilationTagHelperFeature tagHelperFeature)
{
var discoveryProjectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, new VirtualRazorProjectFileSystem(), b =>
{
b.Features.Add(new DefaultMetadataReferenceFeature { References = references });
b.Features.Add(tagHelperFeature);
b.Features.Add(new DefaultTagHelperDescriptorProvider());

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

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

return discoveryProjectEngine;
}

private static RazorProjectEngine GetGenerationProjectEngine(IReadOnlyList<TagHelperDescriptor> tagHelpers, IEnumerable<SourceGeneratorProjectItem> items, RazorSourceGenerationOptions razorSourceGeneratorOptions)
private static RazorProjectEngine GetGenerationProjectEngine(
IReadOnlyList<TagHelperDescriptor> tagHelpers,
SourceGeneratorProjectItem item,
IEnumerable<SourceGeneratorProjectItem> imports,
RazorSourceGenerationOptions razorSourceGeneratorOptions)
{
var fileSystem = new VirtualRazorProjectFileSystem();
foreach (var item in items)
fileSystem.Add(item);
foreach (var import in imports)
{
fileSystem.Add(item);
fileSystem.Add(import);
}

var projectEngine = RazorProjectEngine.Create(razorSourceGeneratorOptions.Configuration, fileSystem, b =>
Expand All @@ -99,19 +114,5 @@ private static RazorProjectEngine GetGenerationProjectEngine(IReadOnlyList<TagHe

return projectEngine;
}

private static TFeature? GetFeature<TFeature>(RazorProjectEngine engine)
{
var count = engine.EngineFeatures.Count;
for (var i = 0; i < count; i++)
{
if (engine.EngineFeatures[i] is TFeature feature)
{
return feature;
}
}

return default;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ private static (RazorSourceGenerationOptions?, Diagnostic?) ComputeRazorSourceGe

var razorSourceGenerationOptions = new RazorSourceGenerationOptions()
{
Configuration = razorConfiguration,
WaitForDebugger = waitForDebugger == "true",
SuppressRazorSourceGenerator = suppressRazorSourceGenerator == "true",
GenerateMetadataSourceChecksumAttributes = generateMetadataSourceChecksumAttributes == "true",
RootNamespace = rootNamespace ?? "ASP",
Configuration = razorConfiguration,
CSharpLanguageVersion = ((CSharpParseOptions)parseOptions).LanguageVersion,
};

Expand Down Expand Up @@ -80,4 +80,4 @@ private static (SourceGeneratorProjectItem?, Diagnostic?) ComputeProjectItems((A
return (projectItem, null);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private IReadOnlyList<TagHelperDescriptor> GetTagHelpers(IEnumerable<MetadataRef
return descriptors;
}

private IReadOnlyList<TagHelperDescriptor> GetTagHelpersFromCompilation(Compilation compilation, StaticCompilationTagHelperFeature tagHelperFeature, SyntaxTree syntaxTrees)
private static IReadOnlyList<TagHelperDescriptor> GetTagHelpersFromCompilation(Compilation compilation, StaticCompilationTagHelperFeature tagHelperFeature, SyntaxTree syntaxTrees)
{
var compilationWithDeclarations = compilation.AddSyntaxTrees(syntaxTrees);

Expand All @@ -34,4 +34,4 @@ private IReadOnlyList<TagHelperDescriptor> GetTagHelpersFromCompilation(Compilat
return tagHelperFeature.GetDescriptors();
}
}
}
}
Loading