mirror of
https://github.com/SK-la/osu-framework.git
synced 2026-03-15 03:20:30 +00:00
Refactor multiphase tests to not use statics
This commit is contained in:
@@ -5,11 +5,11 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using osu.Framework.SourceGeneration.Generators;
|
||||
|
||||
namespace osu.Framework.SourceGeneration.Tests.Verifiers
|
||||
{
|
||||
public partial class CSharpMultiPhaseSourceGeneratorVerifier<TSourceGenerator>
|
||||
where TSourceGenerator : IIncrementalGenerator, new()
|
||||
public partial class CSharpMultiPhaseSourceGeneratorVerifier<TSourceGenerator> where TSourceGenerator : IIncrementalGenerator, IGeneratorWithEvents, new()
|
||||
{
|
||||
// ReSharper disable once StaticMemberInGenericType
|
||||
private static readonly Regex multi_phase = new Regex(@"^(?<filename>.*)\.(?<num>\d+)\.cs$", RegexOptions.Compiled);
|
||||
|
||||
@@ -6,16 +6,17 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using osu.Framework.SourceGeneration.Generators.Dependencies;
|
||||
using osu.Framework.SourceGeneration.Generators;
|
||||
|
||||
namespace osu.Framework.SourceGeneration.Tests.Verifiers
|
||||
{
|
||||
public partial class CSharpMultiPhaseSourceGeneratorVerifier<TSourceGenerator>
|
||||
where TSourceGenerator : IIncrementalGenerator, new()
|
||||
where TSourceGenerator : IIncrementalGenerator, IGeneratorWithEvents, new()
|
||||
{
|
||||
public class Test
|
||||
{
|
||||
private GeneratorDriver driver;
|
||||
private TSourceGenerator generator;
|
||||
private readonly (string filename, string content)[] commonSources;
|
||||
private readonly (string filename, string content)[] commonGenerated;
|
||||
private readonly List<List<(string filename, string content)>> multiPhaseSources;
|
||||
@@ -32,7 +33,7 @@ namespace osu.Framework.SourceGeneration.Tests.Verifiers
|
||||
List<List<(string filename, string content)>> multiPhaseSources,
|
||||
List<List<(string filename, string content)>> multiPhaseGenerated)
|
||||
{
|
||||
driver = CSharpGeneratorDriver.Create(new TSourceGenerator());
|
||||
driver = CSharpGeneratorDriver.Create(generator = new TSourceGenerator());
|
||||
driver = driver.WithUpdatedParseOptions(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion));
|
||||
this.commonSources = commonSources;
|
||||
this.commonGenerated = commonGenerated;
|
||||
@@ -55,9 +56,9 @@ namespace osu.Framework.SourceGeneration.Tests.Verifiers
|
||||
emitHits = 0;
|
||||
};
|
||||
|
||||
DependencyInjectionSourceGenerator.GeneratorEvent.SyntaxTargetCreated += _ => syntaxTargetCreated++;
|
||||
DependencyInjectionSourceGenerator.GeneratorEvent.SemanticTargetCreated += _ => semanticTargetCreated++;
|
||||
DependencyInjectionSourceGenerator.GeneratorEvent.Emit += _ => emitHits++;
|
||||
generator.EventDriver.SyntaxTargetCreated += _ => syntaxTargetCreated++;
|
||||
generator.EventDriver.SemanticTargetCreated += _ => semanticTargetCreated++;
|
||||
generator.EventDriver.Emit += _ => emitHits++;
|
||||
|
||||
PhaseCompleted += () =>
|
||||
{
|
||||
|
||||
@@ -11,17 +11,19 @@ using osu.Framework.SourceGeneration.Generators.Dependencies.Emitters;
|
||||
namespace osu.Framework.SourceGeneration.Generators.Dependencies
|
||||
{
|
||||
[Generator]
|
||||
public partial class DependencyInjectionSourceGenerator : IIncrementalGenerator
|
||||
public class DependencyInjectionSourceGenerator : IIncrementalGenerator, IGeneratorWithEvents
|
||||
{
|
||||
public GeneratorEventDriver EventDriver { get; } = new GeneratorEventDriver();
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
// Stage 1: Create SyntaxTarget objects for all classes.
|
||||
IncrementalValuesProvider<SyntaxTarget> syntaxTargets =
|
||||
context.SyntaxProvider.CreateSyntaxProvider(
|
||||
(n, _) => GeneratorClassCandidate.IsSyntaxTarget(n),
|
||||
(ctx, _) => returnWithEvent(new SyntaxTarget((ClassDeclarationSyntax)ctx.Node, ctx.SemanticModel), GeneratorEvent.OnSyntaxTargetCreated))
|
||||
(ctx, _) => returnWithEvent(new SyntaxTarget((ClassDeclarationSyntax)ctx.Node, ctx.SemanticModel), EventDriver.OnSyntaxTargetCreated))
|
||||
.Select((t, _) => t.WithName())
|
||||
.Select((t, _) => returnWithEvent(t.WithSemanticTarget(), GeneratorEvent.OnSemanticTargetCreated));
|
||||
.Select((t, _) => returnWithEvent(t.WithSemanticTarget(), EventDriver.OnSemanticTargetCreated));
|
||||
|
||||
// Stage 2: Separate out the old and new syntax targets for the same class object.
|
||||
// At this point, there are a bunch of old and new syntax targets that may refer to the same class object.
|
||||
@@ -34,7 +36,7 @@ namespace osu.Framework.SourceGeneration.Generators.Dependencies
|
||||
.Collect()
|
||||
.SelectMany((targets, _) =>
|
||||
{
|
||||
GeneratorEvent.OnStage2Entry(targets);
|
||||
EventDriver.OnStage2Entry(targets);
|
||||
|
||||
// Ensure all targets have a generation ID. This is over-engineered as two loops to:
|
||||
// 1. Increment the generation ID locally for deterministic test output.
|
||||
@@ -50,7 +52,7 @@ namespace osu.Framework.SourceGeneration.Generators.Dependencies
|
||||
foreach (var target in targets)
|
||||
target.GenerationId ??= maxGenerationIds[target] + 1;
|
||||
|
||||
GeneratorEvent.OnStage2GenerationIdAssigned(targets);
|
||||
EventDriver.OnStage2GenerationIdAssigned(targets);
|
||||
|
||||
HashSet<SyntaxTarget> result = new HashSet<SyntaxTarget>(SyntaxTargetNameComparer.DEFAULT);
|
||||
|
||||
@@ -58,7 +60,7 @@ namespace osu.Framework.SourceGeneration.Generators.Dependencies
|
||||
foreach (SyntaxTarget t in targets.OrderByDescending(t => t.GenerationId))
|
||||
result.Add(t);
|
||||
|
||||
GeneratorEvent.OnStage2Exit(result);
|
||||
EventDriver.OnStage2Exit(result);
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -67,7 +69,7 @@ namespace osu.Framework.SourceGeneration.Generators.Dependencies
|
||||
|
||||
private void emit(SourceProductionContext context, GeneratorClassCandidate candidate)
|
||||
{
|
||||
GeneratorEvent.OnEmit(candidate);
|
||||
EventDriver.OnEmit(candidate);
|
||||
new DependenciesFileEmitter(candidate).Emit(context.AddSource);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace osu.Framework.SourceGeneration.Generators.Dependencies
|
||||
{
|
||||
public partial class DependencyInjectionSourceGenerator
|
||||
{
|
||||
public static class GeneratorEvent
|
||||
{
|
||||
public static event Action<SyntaxTarget>? SyntaxTargetCreated;
|
||||
public static event Action<SyntaxTarget>? SemanticTargetCreated;
|
||||
public static event Action<ImmutableArray<SyntaxTarget>>? Stage2Entry;
|
||||
public static event Action<ImmutableArray<SyntaxTarget>>? Stage2GenerationIdAssigned;
|
||||
public static event Action<HashSet<SyntaxTarget>>? Stage2Exit;
|
||||
public static event Action<GeneratorClassCandidate>? Emit;
|
||||
|
||||
public static void OnSyntaxTargetCreated(SyntaxTarget target)
|
||||
{
|
||||
conditionalInvoke(SyntaxTargetCreated, target);
|
||||
}
|
||||
|
||||
public static void OnSemanticTargetCreated(SyntaxTarget target)
|
||||
{
|
||||
conditionalInvoke(SemanticTargetCreated, target);
|
||||
}
|
||||
|
||||
public static void OnStage2Entry(ImmutableArray<SyntaxTarget> target)
|
||||
{
|
||||
conditionalInvoke(Stage2Entry, target);
|
||||
}
|
||||
|
||||
public static void OnStage2GenerationIdAssigned(ImmutableArray<SyntaxTarget> target)
|
||||
{
|
||||
conditionalInvoke(Stage2GenerationIdAssigned, target);
|
||||
}
|
||||
|
||||
public static void OnStage2Exit(HashSet<SyntaxTarget> target)
|
||||
{
|
||||
conditionalInvoke(Stage2Exit, target);
|
||||
}
|
||||
|
||||
public static void OnEmit(GeneratorClassCandidate candidate)
|
||||
{
|
||||
conditionalInvoke(Emit, candidate);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private static void conditionalInvoke<T>(Action<T>? @event, T arg)
|
||||
{
|
||||
@event?.Invoke(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.SourceGeneration.Generators.Dependencies;
|
||||
|
||||
namespace osu.Framework.SourceGeneration.Generators
|
||||
{
|
||||
public class GeneratorEventDriver
|
||||
{
|
||||
public event Action<SyntaxTarget>? SyntaxTargetCreated;
|
||||
public event Action<SyntaxTarget>? SemanticTargetCreated;
|
||||
public event Action<ImmutableArray<SyntaxTarget>>? Stage2Entry;
|
||||
public event Action<ImmutableArray<SyntaxTarget>>? Stage2GenerationIdAssigned;
|
||||
public event Action<HashSet<SyntaxTarget>>? Stage2Exit;
|
||||
public event Action<GeneratorClassCandidate>? Emit;
|
||||
|
||||
public void OnSyntaxTargetCreated(SyntaxTarget target)
|
||||
{
|
||||
conditionalInvoke(SyntaxTargetCreated, target);
|
||||
}
|
||||
|
||||
public void OnSemanticTargetCreated(SyntaxTarget target)
|
||||
{
|
||||
conditionalInvoke(SemanticTargetCreated, target);
|
||||
}
|
||||
|
||||
public void OnStage2Entry(ImmutableArray<SyntaxTarget> target)
|
||||
{
|
||||
conditionalInvoke(Stage2Entry, target);
|
||||
}
|
||||
|
||||
public void OnStage2GenerationIdAssigned(ImmutableArray<SyntaxTarget> target)
|
||||
{
|
||||
conditionalInvoke(Stage2GenerationIdAssigned, target);
|
||||
}
|
||||
|
||||
public void OnStage2Exit(HashSet<SyntaxTarget> target)
|
||||
{
|
||||
conditionalInvoke(Stage2Exit, target);
|
||||
}
|
||||
|
||||
public void OnEmit(GeneratorClassCandidate candidate)
|
||||
{
|
||||
conditionalInvoke(Emit, candidate);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void conditionalInvoke<T>(Action<T>? @event, T arg)
|
||||
{
|
||||
@event?.Invoke(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Framework.SourceGeneration.Generators
|
||||
{
|
||||
public interface IGeneratorWithEvents
|
||||
{
|
||||
GeneratorEventDriver EventDriver { get; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user