Skip to content

Commit 80e3c9e

Browse files
committed
Add Source generator version
1 parent f2f5452 commit 80e3c9e

File tree

7 files changed

+154
-4
lines changed

7 files changed

+154
-4
lines changed

BlazorPreRender/BlazorApp1/BlazorApp1.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorApp1.Server", "Blazor
99
EndProject
1010
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PreRenderer", "PreRenderer\PreRenderer.csproj", "{49B31D6A-5EC3-4813-89EC-E4C005488A1B}"
1111
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenerators", "SourceGenerators\SourceGenerators.csproj", "{2431466A-BDF3-4998-B3C9-85C4B24FC293}"
13+
EndProject
1214
Global
1315
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1416
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
2729
{49B31D6A-5EC3-4813-89EC-E4C005488A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
2830
{49B31D6A-5EC3-4813-89EC-E4C005488A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
2931
{49B31D6A-5EC3-4813-89EC-E4C005488A1B}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{2431466A-BDF3-4998-B3C9-85C4B24FC293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33+
{2431466A-BDF3-4998-B3C9-85C4B24FC293}.Debug|Any CPU.Build.0 = Debug|Any CPU
34+
{2431466A-BDF3-4998-B3C9-85C4B24FC293}.Release|Any CPU.ActiveCfg = Release|Any CPU
35+
{2431466A-BDF3-4998-B3C9-85C4B24FC293}.Release|Any CPU.Build.0 = Release|Any CPU
3036
EndGlobalSection
3137
GlobalSection(SolutionProperties) = preSolution
3238
HideSolutionNode = FALSE

BlazorPreRender/BlazorApp1/BlazorApp1/BlazorApp1.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@
1010
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
1111
</ItemGroup>
1212

13+
<ItemGroup>
14+
<ProjectReference Include="..\SourceGenerators\SourceGenerators.csproj" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
15+
</ItemGroup>
16+
1317
</Project>

BlazorPreRender/BlazorApp1/BlazorApp1/Pages/Index.razor

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
<h1>Hello, world!</h1>
44

5-
Welcome to your new app.
5+
This app has the following routes:
6+
7+
<ul>
8+
@foreach (var route in AppRoutes.Routes)
9+
{
10+
<li>
11+
<code>@route</code>
12+
</li>
13+
}
14+
</ul>
615

716
<SurveyPrompt Title="How is Blazor working for you?" />

BlazorPreRender/BlazorApp1/PreRenderer/GenerateOutput.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Net.Http;
88
using System.Threading.Tasks;
9+
using BlazorApp1;
910
using Xunit;
1011
using Xunit.Abstractions;
1112

@@ -44,9 +45,9 @@ public void Dispose()
4445
/// Massage the values into something that works for xunit theory
4546
/// </summary>
4647
public static IEnumerable<object[]> GetPagesToPreRender()
47-
=> PrerenderRouteHelper
48-
.GetRoutes(typeof(BlazorApp1.App).Assembly)
49-
.Select(config => new object[] { config });
48+
=> AppRoutes.Routes
49+
//PrerenderRouteHelper.GetRoutes(typeof(BlazorApp1.App).Assembly)
50+
.Select(route => new object[] { route });
5051

5152
[Theory, Trait("Category", "PreRender")]
5253
[MemberData(nameof(GetPagesToPreRender))]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.CSharp;
3+
using Microsoft.CodeAnalysis.CSharp.Syntax;
4+
using Microsoft.CodeAnalysis.Text;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Collections.Immutable;
8+
using System.Diagnostics;
9+
using System.Linq;
10+
using System.Text;
11+
12+
namespace SourceGenerators
13+
{
14+
// see https://github.com/dotnet/roslyn-sdk/blob/master/samples/CSharp/SourceGenerators/SourceGeneratorSamples/AutoNotifyGenerator.cs
15+
// https://github.com/dotnet/roslyn-sdk/blob/master/samples/CSharp/SourceGenerators/SourceGeneratorSamples/MustacheGenerator.cs
16+
[Generator]
17+
public class AppRoutesGenerator : ISourceGenerator
18+
{
19+
private const string RouteAttributeName = "Microsoft.AspNetCore.Components.RouteAttribute";
20+
21+
public void Execute(GeneratorExecutionContext context)
22+
{
23+
try
24+
{
25+
Debugger.Launch();
26+
var allRoutePaths = GetRouteTemplates(context.Compilation);
27+
28+
var dictSource = SourceText.From(Templates.AppRoutes(allRoutePaths), Encoding.UTF8);
29+
context.AddSource("AppRoutes", dictSource);
30+
}
31+
catch (Exception)
32+
{
33+
Debugger.Launch();
34+
}
35+
}
36+
37+
public void Initialize(GeneratorInitializationContext context)
38+
{
39+
//Debugger.Launch();
40+
}
41+
42+
private static ImmutableArray<string> GetRouteTemplates(Compilation compilation)
43+
{
44+
// Get all classes
45+
IEnumerable<SyntaxNode> allNodes = compilation.SyntaxTrees.SelectMany(s => s.GetRoot().DescendantNodes());
46+
IEnumerable<ClassDeclarationSyntax> allClasses = allNodes
47+
.Where(d => d.IsKind(SyntaxKind.ClassDeclaration))
48+
.OfType<ClassDeclarationSyntax>();
49+
50+
return allClasses
51+
.Select(component => GetRoutePath(compilation, component))
52+
.Where(route => route is not null)
53+
.Cast<string>()// stops the nullable lies
54+
.ToImmutableArray();
55+
}
56+
57+
private static string? GetRoutePath(Compilation compilation, ClassDeclarationSyntax component)
58+
{
59+
var routeAttribute = component.AttributeLists
60+
.SelectMany(x => x.Attributes)
61+
.FirstOrDefault(attr => attr.Name.ToString() == RouteAttributeName);
62+
63+
if (routeAttribute?.ArgumentList?.Arguments.Count != 1)
64+
{
65+
// no route path
66+
return null;
67+
}
68+
69+
var semanticModel = compilation.GetSemanticModel(component.SyntaxTree);
70+
71+
var routeArg = routeAttribute.ArgumentList.Arguments[0];
72+
var routeExpr = routeArg.Expression;
73+
return semanticModel.GetConstantValue(routeExpr).ToString();
74+
}
75+
}
76+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>latest</LangVersion>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<PropertyGroup>
10+
<RestoreAdditionalProjectSources>https://dotnet.myget.org/F/roslyn/api/v3/index.json ;$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" PrivateAssets="all" />
15+
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
16+
</ItemGroup>
17+
18+
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Collections.Generic;
2+
using System.Text;
3+
4+
namespace SourceGenerators
5+
{
6+
internal static class Templates
7+
{
8+
public static string AppRoutes(IEnumerable<string> allRoutes)
9+
{
10+
// hard code the namespace for now
11+
var sb = new StringBuilder(@"
12+
using System.Collections.Generic;
13+
using System.Collections.ObjectModel;
14+
15+
namespace BlazorApp1
16+
{
17+
public static class AppRoutes
18+
{
19+
public static ReadOnlyCollection<string> Routes { get; } =
20+
new ReadOnlyCollection<string>(
21+
new List<string>
22+
{
23+
");
24+
foreach (var route in allRoutes)
25+
{
26+
sb.AppendLine($"\"{route}\",");
27+
}
28+
sb.Append(@"
29+
}
30+
);
31+
}
32+
}");
33+
return sb.ToString();
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)