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
1 change: 1 addition & 0 deletions Discord.Net.ComponentDesigner.sln.DotSettings.user
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,5 @@




</wpf:ResourceDictionary>
10 changes: 5 additions & 5 deletions Sandbox/Examples/Spyfall/PackExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Sandbox.Examples.Spyfall;

public class PackExample
{
public static MessageComponent CreatePackInfo(
public static CXMessageComponent CreatePackInfo(
Pack pack,
int locationPage
) => cx(
Expand All @@ -20,7 +20,7 @@ int locationPage
"""
);

public static MessageComponent PageControls(Pack pack, int page)
public static CXMessageComponent PageControls(Pack pack, int page)
=> cx(
$"""
<row>
Expand All @@ -42,7 +42,7 @@ public static MessageComponent PageControls(Pack pack, int page)
"""
);

public static MessageComponent Locations(IReadOnlyList<Location> locations, int page)
public static CXMessageComponent Locations(IReadOnlyList<Location> locations, int page)
{
const int packLocationsPerPage = 3;

Expand All @@ -67,7 +67,7 @@ public static MessageComponent Locations(IReadOnlyList<Location> locations, int
);
}

public static MessageComponent LocationListItem(Location location, int index, int pageLower)
public static CXMessageComponent LocationListItem(Location location, int index, int pageLower)
{
var content = cx(
$"""
Expand Down Expand Up @@ -130,7 +130,7 @@ Created by {user.DisplayName}
);
}

public static MessageComponent PackHeader(Pack pack)
public static CXMessageComponent PackHeader(Pack pack)
{
var packHeaderText = cx(
$"""
Expand Down
9 changes: 8 additions & 1 deletion src/Discord.Net.ComponentDesigner.Generator/Diagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -495,5 +495,12 @@ public static Diagnostic CreateParsingDiagnostic(CXDiagnostic diagnostic, Locati
true
);


public static readonly DiagnosticDescriptor InvalidInterleavedComponentInCurrentContext = new(
"DC0055",
"Invalid interpolated component",
"'{0}' cannot be used in an expected context of '{1}'",
"Components",
DiagnosticSeverity.Error,
true
);
}
4 changes: 2 additions & 2 deletions src/Discord.Net.ComponentDesigner.Generator/Graph/CXGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,13 @@ public void UpdateState(ComponentContext context)
Inner.UpdateState(ref _state, context);
}

public string Render(IComponentContext context)
public string Render(IComponentContext context, ComponentRenderingOptions options = default)
{
if (_render is not null) return _render;

using (context.CreateDiagnosticScope(_diagnostics))
{
return _render = Inner.Render(State, context);
return _render = Inner.Render(State, context, options);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.CodeAnalysis.Text;
using System.Collections.Generic;
using System.Linq;
using Discord.CX.Nodes.Components;

namespace Discord.CX.Nodes;

Expand All @@ -29,14 +30,18 @@ public void Dispose()

public List<Diagnostic> GlobalDiagnostics { get; init; } = [];

public ComponentTypingContext RootTypingContext { get; }

private readonly CXGraph _graph;

private DiagnosticScope _scope;

public ComponentContext(CXGraph graph)
public ComponentContext(CXGraph graph, ComponentTypingContext? typingContext = null)
{
_graph = graph;
_scope = new(GlobalDiagnostics, null, this);

RootTypingContext = typingContext ?? ComponentTypingContext.Default;
}

public IDisposable CreateDiagnosticScope(List<Diagnostic> bag)
Expand Down
36 changes: 25 additions & 11 deletions src/Discord.Net.ComponentDesigner.Generator/Nodes/ComponentNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@

namespace Discord.CX.Nodes;

public delegate string ComponentNodeRenderer<in TState>(
TState state,
IComponentContext context,
ComponentRenderingOptions options = default
) where TState : ComponentState;

public delegate string ComponentNodeRenderer(
ComponentState state,
IComponentContext context,
ComponentRenderingOptions options = default
);

public abstract class ComponentNode<TState> : ComponentNode
where TState : ComponentState
{
public abstract string Render(TState state, IComponentContext context);
public abstract string Render(TState state, IComponentContext context, ComponentRenderingOptions options);

public virtual void UpdateState(ref TState state, IComponentContext context)
{
Expand All @@ -27,8 +39,11 @@ public sealed override void UpdateState(ref ComponentState state, IComponentCont
public sealed override ComponentState? Create(ComponentStateInitializationContext context)
=> CreateState(context);

public sealed override string Render(ComponentState state, IComponentContext context)
=> Render((TState)state, context);
public sealed override string Render(
ComponentState state,
IComponentContext context,
ComponentRenderingOptions options
) => Render((TState)state, context, options);

public virtual void Validate(TState state, IComponentContext context)
{
Expand All @@ -39,15 +54,10 @@ public sealed override void Validate(ComponentState state, IComponentContext con
=> Validate((TState)state, context);
}

public delegate string ComponentNodeRenderer<in TState>(TState state, IComponentContext context)
where TState : ComponentState;

public delegate string ComponentNodeRenderer(ComponentState state, IComponentContext context);

public abstract class ComponentNode
{
protected virtual bool IsUserAccessible => true;

public abstract string Name { get; }
public virtual IReadOnlyList<string> Aliases { get; } = [];

Expand Down Expand Up @@ -115,7 +125,11 @@ private bool TryGetPropertyFromName(string name, out ComponentProperty result)
return false;
}

public abstract string Render(ComponentState state, IComponentContext context);
public abstract string Render(
ComponentState state,
IComponentContext context,
ComponentRenderingOptions options
);

public virtual void UpdateState(ref ComponentState state, IComponentContext context)
{
Expand Down Expand Up @@ -209,7 +223,7 @@ out ComponentNode node
continue;

if (
!InterleavedComponentNode.IsValidInterleavedType(
!ComponentBuilderKindUtils.IsValidComponentBuilderType(
methodSymbol.ReturnType,
cxSemanticModel.Compilation,
out var kind
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Discord.CX.Nodes.Components;

namespace Discord.CX.Nodes;

public readonly record struct ComponentRenderingOptions(
ComponentTypingContext? TypingContext = null
)
{
public static readonly ComponentRenderingOptions Default = new();
}

public readonly record struct ComponentTypingContext(
bool CanSplat,
ComponentBuilderKind ConformingType
)
{
public static readonly ComponentTypingContext Default = new(
CanSplat: true,
ConformingType: ComponentBuilderKind.CollectionOfIMessageComponentBuilders
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public IReadOnlyList<CXGraph.Node> Children

public bool IsElement => Source is CXElement;

public bool IsRootNode => OwningNode?.Parent is null;

private readonly Dictionary<ComponentProperty, ComponentPropertyValue> _properties = [];

public ComponentPropertyValue GetProperty(ComponentProperty property)
Expand Down Expand Up @@ -167,7 +169,8 @@ public string RenderInitializer(

public string RenderChildren(
IComponentContext context,
Func<CXGraph.Node, bool>? predicate = null
Func<CXGraph.Node, bool>? predicate = null,
ComponentRenderingOptions options = default
)
{
if (OwningNode is null || !HasChildren) return string.Empty;
Expand All @@ -178,7 +181,7 @@ public string RenderChildren(

return string.Join(
$",{Environment.NewLine}",
children.Select(x => x.Render(context))
children.Select(x => x.Render(context, options))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public class ActionRowComponentNode : ComponentNode

public override IReadOnlyList<ComponentProperty> Properties { get; }

private static readonly ComponentRenderingOptions ChildRenderingOptions = new(
TypingContext: new(
CanSplat: true,
ConformingType: ComponentBuilderKind.CollectionOfIMessageComponentBuilders
)
);

public ActionRowComponentNode()
{
Properties =
Expand Down Expand Up @@ -63,7 +70,7 @@ public override void Validate(ComponentState state, IComponentContext context)
extra.State.Source
);
}

break;
case SelectMenuComponentNode:
foreach (var rest in state.Children.Skip(1))
Expand Down Expand Up @@ -101,17 +108,21 @@ private static bool IsValidChild(ComponentNode node)
or SelectMenuComponentNode
or IDynamicComponentNode;

public override string Render(ComponentState state, IComponentContext context)
public override string Render(
ComponentState state,
IComponentContext context,
ComponentRenderingOptions options
)
{
var props = state.RenderProperties(this, context, asInitializers: true);
var children = state.RenderChildren(context);
var children = state.RenderChildren(context, options: ChildRenderingOptions);

var init = new StringBuilder(props);

if (!string.IsNullOrWhiteSpace(children))
{
if (!string.IsNullOrWhiteSpace(props)) init.Append(',').AppendLine();

init.Append(
$"""
Components =
Expand All @@ -133,35 +144,11 @@ public override string Render(ComponentState state, IComponentContext context)
}}
""";
}
// => $$"""
// new {{context.KnownTypes.ActionRowBuilderType!.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}}(){{
// $"{
// state
// .RenderProperties(this, context, asInitializers: true)
// .PostfixIfSome(Environment.NewLine)
// }{
// state
// .RenderChildren(context)
// .Map(x =>
// $"""
// Components =
// [
// {x.WithNewlinePadding(4)}
// ]
// """
// )
// }"
// .TrimEnd()
// .WithNewlinePadding(4)
// .PrefixIfSome($"{Environment.NewLine}{{{Environment.NewLine}".Postfix(4))
// .PostfixIfSome($"{Environment.NewLine}}}")
// }}
// """;
}

public sealed class AutoActionRowComponentNode : ActionRowComponentNode
{
public static readonly AutoActionRowComponentNode Instance = new ();
public static readonly AutoActionRowComponentNode Instance = new();
protected override bool IsUserAccessible => false;

public override ComponentState? Create(ComponentStateInitializationContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ label.Value is not null &&
base.Validate(state, context);
}

public override string Render(ButtonComponentState state, IComponentContext context)
public override string Render(ButtonComponentState state, IComponentContext context,
ComponentRenderingOptions options)
{
string style;

Expand Down
Loading
Loading