add a scanner, but this seems to be a wrong solution. Change open-source head
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateChangeBindingAttribute"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -14,11 +21,11 @@ namespace StgSharp.UserInterface
|
||||
{
|
||||
|
||||
public string StatePath { get; } = string.IsNullOrWhiteSpace(statePath) ?
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(statePath)) :
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(statePath)) :
|
||||
statePath;
|
||||
|
||||
public string PanelHostPath { get; } = string.IsNullOrWhiteSpace(panelHostPath) ?
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(panelHostPath)) :
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(panelHostPath)) :
|
||||
panelHostPath;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateNodeAttribute"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace StgSharp.UserInterface
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="Service.Host"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="Service.LoadAccomplishmentEvent"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace StgSharp.UserInterface
|
||||
{
|
||||
public sealed record ServiceLoadAccomplishmentEvent
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="Service.LoadCommand"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="State.AppState"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="State.FrontCommandHost"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="State.Host"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="State.PanelState"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="State.ServiceManager"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="View.CommandResult"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace StgSharp.UserInterface
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="View.ExecuteCommand"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="View.Host"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="View.StateChangeCommand"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace StgSharp.UserInterface
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="View.StateValueCommand"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace StgSharp.UserInterface
|
||||
@@ -6,9 +13,10 @@ namespace StgSharp.UserInterface
|
||||
{
|
||||
|
||||
public StateValueCommand(
|
||||
string statePath,
|
||||
TValue value
|
||||
) : base(statePath)
|
||||
string statePath,
|
||||
TValue value
|
||||
)
|
||||
: base(statePath)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,57 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.Analysis"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace StgSharp.UserInterface.Generator;
|
||||
|
||||
internal static class PanelStateIncrementalGeneratorAnalysis
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
{
|
||||
public static PanelStateIncrementalGeneratorOutput Analyze(
|
||||
PanelStateIncrementalGeneratorInput input
|
||||
)
|
||||
internal static class PanelStateIncrementalGeneratorAnalysis
|
||||
{
|
||||
if (input.TypeTargets.IsDefaultOrEmpty)
|
||||
{
|
||||
return new PanelStateIncrementalGeneratorOutput(
|
||||
input.Compilation,
|
||||
ImmutableArray<PanelStateIncrementalGeneratorTypeAnalysis>.Empty);
|
||||
}
|
||||
|
||||
HashSet<string> emittedTypes = new(StringComparer.Ordinal);
|
||||
ImmutableArray<PanelStateIncrementalGeneratorTypeAnalysis>.Builder builder =
|
||||
ImmutableArray.CreateBuilder<PanelStateIncrementalGeneratorTypeAnalysis>();
|
||||
|
||||
foreach (PanelStateIncrementalGeneratorTypeTarget target in input.TypeTargets
|
||||
.OrderBy(static item => item.TypeDisplayName, StringComparer.Ordinal))
|
||||
public static PanelStateIncrementalGeneratorOutput Analyze(
|
||||
PanelStateIncrementalGeneratorInput input
|
||||
)
|
||||
{
|
||||
if (!emittedTypes.Add(target.TypeDisplayName))
|
||||
{
|
||||
continue;
|
||||
if (input.TypeTargets.IsDefaultOrEmpty) {
|
||||
return new PanelStateIncrementalGeneratorOutput(
|
||||
input.Compilation,
|
||||
ImmutableArray<PanelStateIncrementalGeneratorTypeAnalysis>.Empty);
|
||||
}
|
||||
|
||||
PanelStateSymbolPartAnalysis stateSymbols = PanelStateIncrementalGeneratorStateSymbols.Analyze(target);
|
||||
StateChangeBindingPartAnalysis stateChangeBindings = PanelStateIncrementalGeneratorStateChangeBindings.Analyze(target);
|
||||
HashSet<string> emittedTypes = new(StringComparer.Ordinal);
|
||||
ImmutableArray<PanelStateIncrementalGeneratorTypeAnalysis>.Builder builder =
|
||||
ImmutableArray.CreateBuilder<PanelStateIncrementalGeneratorTypeAnalysis>();
|
||||
|
||||
builder.Add(
|
||||
new PanelStateIncrementalGeneratorTypeAnalysis(
|
||||
target,
|
||||
stateSymbols,
|
||||
stateChangeBindings,
|
||||
PanelStateIncrementalGeneratorStateCommandHandlers.Analyze(
|
||||
target,
|
||||
stateSymbols,
|
||||
stateChangeBindings)));
|
||||
foreach (PanelStateIncrementalGeneratorTypeTarget target in input.TypeTargets
|
||||
.OrderBy(static item => item.TypeDisplayName, StringComparer.Ordinal))
|
||||
{
|
||||
if (!emittedTypes.Add(target.TypeDisplayName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PanelStateSymbolPartAnalysis stateSymbols = PanelStateIncrementalGeneratorStateSymbols.Analyze(target);
|
||||
StateChangeBindingPartAnalysis stateChangeBindings = PanelStateIncrementalGeneratorStateChangeBindings.Analyze(target);
|
||||
|
||||
builder.Add(
|
||||
new PanelStateIncrementalGeneratorTypeAnalysis(target, stateSymbols,
|
||||
stateChangeBindings,
|
||||
PanelStateIncrementalGeneratorStateCommandHandlers.Analyze(
|
||||
target,
|
||||
stateSymbols,
|
||||
stateChangeBindings)));
|
||||
}
|
||||
|
||||
return new PanelStateIncrementalGeneratorOutput(
|
||||
input.Compilation,
|
||||
builder.ToImmutable());
|
||||
}
|
||||
|
||||
return new PanelStateIncrementalGeneratorOutput(
|
||||
input.Compilation,
|
||||
builder.ToImmutable());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,16 @@
|
||||
namespace StgSharp.UserInterface.Generator;
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.Diagnostics"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
internal static class PanelStateIncrementalGeneratorDiagnostics
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
{
|
||||
public const string Category = "StgSharp.UserInterface.Generator";
|
||||
internal static class PanelStateIncrementalGeneratorDiagnostics
|
||||
{
|
||||
|
||||
public const string Category = "StgSharp.UserInterface.Generator";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.Emitter"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System.Linq;
|
||||
@@ -31,8 +38,8 @@ namespace StgSharp.UserInterface.Generator
|
||||
|
||||
foreach (string typeName in source.TypeAnalyses
|
||||
.Select(static analysis => analysis.Target.TypeDisplayName)
|
||||
.Distinct()
|
||||
.OrderBy(static name => name, StringComparer.Ordinal))
|
||||
.Distinct()
|
||||
.OrderBy(static name => name, StringComparer.Ordinal))
|
||||
{
|
||||
_ = builder.Append(" \"");
|
||||
_ = builder.Append(typeName.Replace("\"", "\"\"", StringComparison.Ordinal));
|
||||
@@ -45,7 +52,7 @@ namespace StgSharp.UserInterface.Generator
|
||||
_ = builder.AppendLine(" {");
|
||||
|
||||
foreach (PanelStateIncrementalGeneratorTypeAnalysis analysis in source.TypeAnalyses
|
||||
.OrderBy(static item => item.Target.TypeDisplayName, StringComparer.Ordinal))
|
||||
.OrderBy(static item => item.Target.TypeDisplayName, StringComparer.Ordinal))
|
||||
{
|
||||
string summary = $"{analysis.Target.TypeDisplayName} | symbols={analysis.StateSymbols.Members.Length} | bindings={analysis.StateChangeBindings.Members.Length} | handlers={analysis.StateChangeCommandHandlers.Members.Length}";
|
||||
_ = builder.Append(" \"");
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.Models"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
@@ -14,7 +21,8 @@ namespace StgSharp.UserInterface.Generator
|
||||
string? metadataName
|
||||
)
|
||||
{
|
||||
return IsStateSymbolAttribute(metadataName) || metadataName == StateChangeBindingAttribute;
|
||||
return IsStateSymbolAttribute(metadataName) ||
|
||||
metadataName == StateChangeBindingAttribute;
|
||||
}
|
||||
|
||||
public static bool IsStateSymbolAttribute(
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
using System.Collections.Immutable;
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.Pipeline"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading;
|
||||
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
@@ -12,12 +19,13 @@ namespace StgSharp.UserInterface.Generator
|
||||
SyntaxNode node
|
||||
)
|
||||
{
|
||||
return node is TypeDeclarationSyntax typeDeclaration && HasAttributedMembers(typeDeclaration);
|
||||
return node is TypeDeclarationSyntax typeDeclaration &&
|
||||
HasAttributedMembers(typeDeclaration);
|
||||
}
|
||||
|
||||
public static PanelStateIncrementalGeneratorTypeTarget? Transform(
|
||||
GeneratorSyntaxContext context,
|
||||
CancellationToken cancellationToken
|
||||
GeneratorSyntaxContext context,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -26,14 +34,12 @@ namespace StgSharp.UserInterface.Generator
|
||||
return null;
|
||||
}
|
||||
|
||||
if (context.SemanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken) is not INamedTypeSymbol typeSymbol)
|
||||
{
|
||||
if (context.SemanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken) is not INamedTypeSymbol typeSymbol) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> markedMembers = CollectMarkedMembers(typeSymbol);
|
||||
if (markedMembers.IsDefaultOrEmpty)
|
||||
{
|
||||
if (markedMembers.IsDefaultOrEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -43,6 +49,50 @@ namespace StgSharp.UserInterface.Generator
|
||||
markedMembers);
|
||||
}
|
||||
|
||||
private static ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> CollectMarkedMembers(
|
||||
INamedTypeSymbol typeSymbol
|
||||
)
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Builder builder =
|
||||
ImmutableArray.CreateBuilder<PanelStateIncrementalGeneratorMarkedMember>();
|
||||
|
||||
foreach (ISymbol member in typeSymbol.GetMembers())
|
||||
{
|
||||
foreach (AttributeData attributeData in member.GetAttributes())
|
||||
{
|
||||
string? metadataName = attributeData.AttributeClass?.ToDisplayString();
|
||||
if (!PanelStateIncrementalGeneratorKnownAttributes.IsKnown(metadataName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Add(
|
||||
new PanelStateIncrementalGeneratorMarkedMember(member, metadataName!,
|
||||
member.Name,
|
||||
GetSymbolTypeName(member)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
private static string GetSymbolTypeName(
|
||||
ISymbol symbol
|
||||
)
|
||||
{
|
||||
return symbol switch
|
||||
{
|
||||
IFieldSymbol fieldSymbol => fieldSymbol.Type
|
||||
.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
IPropertySymbol propertySymbol => propertySymbol.Type
|
||||
.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
IMethodSymbol methodSymbol => methodSymbol.ReturnType
|
||||
.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
_ => symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)
|
||||
};
|
||||
}
|
||||
|
||||
private static bool HasAttributedMembers(
|
||||
TypeDeclarationSyntax typeDeclaration
|
||||
)
|
||||
@@ -61,48 +111,5 @@ namespace StgSharp.UserInterface.Generator
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> CollectMarkedMembers(
|
||||
INamedTypeSymbol typeSymbol
|
||||
)
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Builder builder =
|
||||
ImmutableArray.CreateBuilder<PanelStateIncrementalGeneratorMarkedMember>();
|
||||
|
||||
foreach (ISymbol member in typeSymbol.GetMembers())
|
||||
{
|
||||
foreach (AttributeData attributeData in member.GetAttributes())
|
||||
{
|
||||
string? metadataName = attributeData.AttributeClass?.ToDisplayString();
|
||||
if (!PanelStateIncrementalGeneratorKnownAttributes.IsKnown(metadataName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Add(
|
||||
new PanelStateIncrementalGeneratorMarkedMember(
|
||||
member,
|
||||
metadataName!,
|
||||
member.Name,
|
||||
GetSymbolTypeName(member)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
private static string GetSymbolTypeName(
|
||||
ISymbol symbol
|
||||
)
|
||||
{
|
||||
return symbol switch
|
||||
{
|
||||
IFieldSymbol fieldSymbol => fieldSymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
IPropertySymbol propertySymbol => propertySymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
IMethodSymbol methodSymbol => methodSymbol.ReturnType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
_ => symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+22
-12
@@ -1,20 +1,30 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.StateChangeBindings"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace StgSharp.UserInterface.Generator;
|
||||
|
||||
internal static class PanelStateIncrementalGeneratorStateChangeBindings
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
{
|
||||
public static StateChangeBindingPartAnalysis Analyze(
|
||||
PanelStateIncrementalGeneratorTypeTarget target
|
||||
)
|
||||
internal static class PanelStateIncrementalGeneratorStateChangeBindings
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members = target.MarkedMembers
|
||||
.Where(static member => member.AttributeMetadataName == PanelStateIncrementalGeneratorKnownAttributes.StateChangeBindingAttribute)
|
||||
.ToImmutableArray();
|
||||
|
||||
return new StateChangeBindingPartAnalysis(
|
||||
target.TypeDisplayName,
|
||||
members);
|
||||
public static StateChangeBindingPartAnalysis Analyze(
|
||||
PanelStateIncrementalGeneratorTypeTarget target
|
||||
)
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members = target.MarkedMembers
|
||||
.Where(static member => member.AttributeMetadataName == PanelStateIncrementalGeneratorKnownAttributes.StateChangeBindingAttribute)
|
||||
.ToImmutableArray();
|
||||
|
||||
return new StateChangeBindingPartAnalysis(
|
||||
target.TypeDisplayName,
|
||||
members);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+54
-45
@@ -1,61 +1,70 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.StateCommandHandlers"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace StgSharp.UserInterface.Generator;
|
||||
|
||||
internal static class PanelStateIncrementalGeneratorStateCommandHandlers
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
{
|
||||
public static StateChangeCommandHandlerPartAnalysis Analyze(
|
||||
PanelStateIncrementalGeneratorTypeTarget target,
|
||||
PanelStateSymbolPartAnalysis stateSymbols,
|
||||
StateChangeBindingPartAnalysis stateChangeBindings
|
||||
)
|
||||
internal static class PanelStateIncrementalGeneratorStateCommandHandlers
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members = MergeMembers(
|
||||
stateChangeBindings.Members,
|
||||
stateSymbols.Members);
|
||||
|
||||
return new StateChangeCommandHandlerPartAnalysis(
|
||||
target.TypeDisplayName,
|
||||
members);
|
||||
}
|
||||
|
||||
private static ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> MergeMembers(
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> primaryMembers,
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> secondaryMembers
|
||||
)
|
||||
{
|
||||
if (primaryMembers.IsDefaultOrEmpty && secondaryMembers.IsDefaultOrEmpty)
|
||||
public static StateChangeCommandHandlerPartAnalysis Analyze(
|
||||
PanelStateIncrementalGeneratorTypeTarget target,
|
||||
PanelStateSymbolPartAnalysis stateSymbols,
|
||||
StateChangeBindingPartAnalysis stateChangeBindings
|
||||
)
|
||||
{
|
||||
return ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Empty;
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members = MergeMembers(
|
||||
stateChangeBindings.Members,
|
||||
stateSymbols.Members);
|
||||
|
||||
return new StateChangeCommandHandlerPartAnalysis(
|
||||
target.TypeDisplayName,
|
||||
members);
|
||||
}
|
||||
|
||||
HashSet<string> seen = new(StringComparer.Ordinal);
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Builder builder =
|
||||
ImmutableArray.CreateBuilder<PanelStateIncrementalGeneratorMarkedMember>();
|
||||
|
||||
AddMembers(builder, seen, primaryMembers);
|
||||
AddMembers(builder, seen, secondaryMembers);
|
||||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
private static void AddMembers(
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Builder builder,
|
||||
HashSet<string> seen,
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members
|
||||
)
|
||||
{
|
||||
foreach (PanelStateIncrementalGeneratorMarkedMember member in members)
|
||||
private static void AddMembers(
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Builder builder,
|
||||
HashSet<string> seen,
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members
|
||||
)
|
||||
{
|
||||
string key = member.Symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
if (!seen.Add(key))
|
||||
foreach (PanelStateIncrementalGeneratorMarkedMember member in members)
|
||||
{
|
||||
continue;
|
||||
string key = member.Symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
if (!seen.Add(key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Add(member);
|
||||
}
|
||||
}
|
||||
|
||||
private static ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> MergeMembers(
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> primaryMembers,
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> secondaryMembers
|
||||
)
|
||||
{
|
||||
if (primaryMembers.IsDefaultOrEmpty && secondaryMembers.IsDefaultOrEmpty) {
|
||||
return ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Empty;
|
||||
}
|
||||
|
||||
builder.Add(member);
|
||||
HashSet<string> seen = new(StringComparer.Ordinal);
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember>.Builder builder =
|
||||
ImmutableArray.CreateBuilder<PanelStateIncrementalGeneratorMarkedMember>();
|
||||
|
||||
AddMembers(builder, seen, primaryMembers);
|
||||
AddMembers(builder, seen, secondaryMembers);
|
||||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,30 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator.StateSymbols"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace StgSharp.UserInterface.Generator;
|
||||
|
||||
internal static class PanelStateIncrementalGeneratorStateSymbols
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
{
|
||||
public static PanelStateSymbolPartAnalysis Analyze(
|
||||
PanelStateIncrementalGeneratorTypeTarget target
|
||||
)
|
||||
internal static class PanelStateIncrementalGeneratorStateSymbols
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members = target.MarkedMembers
|
||||
.Where(static member => PanelStateIncrementalGeneratorKnownAttributes.IsStateSymbolAttribute(member.AttributeMetadataName))
|
||||
.ToImmutableArray();
|
||||
|
||||
return new PanelStateSymbolPartAnalysis(
|
||||
target.TypeDisplayName,
|
||||
members);
|
||||
public static PanelStateSymbolPartAnalysis Analyze(
|
||||
PanelStateIncrementalGeneratorTypeTarget target
|
||||
)
|
||||
{
|
||||
ImmutableArray<PanelStateIncrementalGeneratorMarkedMember> members = target.MarkedMembers
|
||||
.Where(static member => PanelStateIncrementalGeneratorKnownAttributes.IsStateSymbolAttribute(member.AttributeMetadataName))
|
||||
.ToImmutableArray();
|
||||
|
||||
return new PanelStateSymbolPartAnalysis(
|
||||
target.TypeDisplayName,
|
||||
members);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,65 @@
|
||||
using System.Collections.Immutable;
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateIncrementalGenerator"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StgSharp.UserInterface.Generator;
|
||||
|
||||
[Generator(LanguageNames.CSharp)]
|
||||
public sealed class PanelStateIncrementalGenerator : IIncrementalGenerator
|
||||
namespace StgSharp.UserInterface.Generator
|
||||
{
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
[Generator(LanguageNames.CSharp)]
|
||||
public sealed class PanelStateIncrementalGenerator : IIncrementalGenerator
|
||||
{
|
||||
IncrementalValuesProvider<PanelStateIncrementalGeneratorTypeTarget> typeTargets = context.SyntaxProvider
|
||||
.CreateSyntaxProvider(
|
||||
static (node, _) => PanelStateIncrementalGeneratorPipeline.IsCandidate(node),
|
||||
static (syntaxContext, cancellationToken) =>
|
||||
PanelStateIncrementalGeneratorPipeline.Transform(syntaxContext, cancellationToken))
|
||||
.Where(static target => target is not null)
|
||||
.Select(static (target, _) => target!);
|
||||
|
||||
IncrementalValueProvider<ImmutableArray<PanelStateIncrementalGeneratorTypeTarget>> collectedTypeTargets = typeTargets.Collect();
|
||||
public void Initialize(
|
||||
IncrementalGeneratorInitializationContext context
|
||||
)
|
||||
{
|
||||
IncrementalValuesProvider<PanelStateIncrementalGeneratorTypeTarget> typeTargets = context.SyntaxProvider
|
||||
.CreateSyntaxProvider(
|
||||
static(
|
||||
node,
|
||||
_
|
||||
) => PanelStateIncrementalGeneratorPipeline.IsCandidate(node),
|
||||
static(
|
||||
syntaxContext,
|
||||
cancellationToken
|
||||
) => PanelStateIncrementalGeneratorPipeline.Transform(syntaxContext, cancellationToken))
|
||||
.Where(static target => target is not null)
|
||||
.Select(static(
|
||||
target,
|
||||
_
|
||||
) => target!);
|
||||
|
||||
IncrementalValueProvider<PanelStateIncrementalGeneratorInput> generatorInput = context.CompilationProvider
|
||||
.Combine(collectedTypeTargets)
|
||||
.Select(
|
||||
static (pair, _) => new PanelStateIncrementalGeneratorInput(
|
||||
pair.Left,
|
||||
pair.Right));
|
||||
IncrementalValueProvider<ImmutableArray<PanelStateIncrementalGeneratorTypeTarget>> collectedTypeTargets = typeTargets.Collect();
|
||||
|
||||
IncrementalValueProvider<PanelStateIncrementalGeneratorOutput> generatorOutput = generatorInput
|
||||
.Select(
|
||||
static (input, _) => PanelStateIncrementalGeneratorAnalysis.Analyze(input));
|
||||
IncrementalValueProvider<PanelStateIncrementalGeneratorInput> generatorInput = context.CompilationProvider
|
||||
.Combine(collectedTypeTargets)
|
||||
.Select(
|
||||
static(
|
||||
pair,
|
||||
_
|
||||
) => new PanelStateIncrementalGeneratorInput(
|
||||
pair.Left,
|
||||
pair.Right));
|
||||
|
||||
IncrementalValueProvider<PanelStateIncrementalGeneratorOutput> generatorOutput = generatorInput
|
||||
.Select(
|
||||
static(
|
||||
input,
|
||||
_
|
||||
) => PanelStateIncrementalGeneratorAnalysis.Analyze(input));
|
||||
|
||||
context.RegisterSourceOutput(
|
||||
generatorOutput,
|
||||
static(
|
||||
productionContext,
|
||||
source
|
||||
) => PanelStateIncrementalGeneratorEmitter.Emit(productionContext, source));
|
||||
}
|
||||
|
||||
context.RegisterSourceOutput(
|
||||
generatorOutput,
|
||||
static (productionContext, source) =>
|
||||
PanelStateIncrementalGeneratorEmitter.Emit(productionContext, source));
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="Global"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
|
||||
@@ -1,33 +1,25 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="PanelStateSample"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace StgSharp.UserInterface.Sample
|
||||
{
|
||||
public sealed class PanelStateSample : PanelState
|
||||
{
|
||||
|
||||
public const string SampleStatePath = nameof(PanelStateSample) + "." + nameof(SampleState);
|
||||
|
||||
private int sampleState;
|
||||
|
||||
public PanelStateSample()
|
||||
: base(nameof(PanelStateSample))
|
||||
{
|
||||
}
|
||||
public PanelStateSample() : base(nameof(PanelStateSample)) { }
|
||||
|
||||
public int SampleState => sampleState;
|
||||
|
||||
// 生成器拆分后,这里相当于某个节点 handler 的 guard,
|
||||
// 对应 ICommand 语义中的 CanExecute。
|
||||
private static bool CanApplySampleStateChange(
|
||||
int origin,
|
||||
int current,
|
||||
StateValueCommand<int> command
|
||||
)
|
||||
{
|
||||
return string.Equals(command.StatePath, SampleStatePath, StringComparison.Ordinal)
|
||||
&& current >= 0
|
||||
&& origin != current;
|
||||
}
|
||||
|
||||
// 实际项目里这整个 StateChangeHandler 都由源生成器产出;
|
||||
// 这里手写展开,只是为了展示“没有生成器时 VSS 代码长什么样”。
|
||||
public void ApplySampleStateChangeCommand(
|
||||
@@ -38,8 +30,7 @@ namespace StgSharp.UserInterface.Sample
|
||||
|
||||
int origin = sampleState;
|
||||
int current = command.Value;
|
||||
if (!CanApplySampleStateChange(origin, current, command))
|
||||
{
|
||||
if (!CanApplySampleStateChange(origin, current, command)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,8 +41,8 @@ namespace StgSharp.UserInterface.Sample
|
||||
// 生成器拆分后,这里相当于某个节点写入后的 post-change hook,
|
||||
// 对应手写体系里常见的 OnChange 位置。
|
||||
private static void BroadcastSampleStateChanged(
|
||||
int origin,
|
||||
int current
|
||||
int origin,
|
||||
int current
|
||||
)
|
||||
{
|
||||
_ = origin;
|
||||
@@ -61,5 +52,18 @@ namespace StgSharp.UserInterface.Sample
|
||||
// 这里只能继续手写内部同步/广播逻辑;正式版本由生成器织入。
|
||||
}
|
||||
|
||||
// 生成器拆分后,这里相当于某个节点 handler 的 guard,
|
||||
// 对应 ICommand 语义中的 CanExecute。
|
||||
private static bool CanApplySampleStateChange(
|
||||
int origin,
|
||||
int current,
|
||||
StateValueCommand<int> command
|
||||
)
|
||||
{
|
||||
return string.Equals(command.StatePath, SampleStatePath, StringComparison.Ordinal) &&
|
||||
current >= 0 &&
|
||||
origin != current;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user