Skip to content

Commit 2284a85

Browse files
committed
fix bugs, add new syntax
1 parent 0fe2ec2 commit 2284a85

File tree

23 files changed

+587
-128
lines changed

23 files changed

+587
-128
lines changed

Discord.Net.ComponentDesigner.sln.DotSettings.user

Lines changed: 12 additions & 4 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ Valid children of an element are:
7676
### Attributes
7777

7878
Attributes consist of a name and an optional value, valid values can be:
79-
- A string literal.
80-
- An interpolation
79+
- A [string literal](#string-literals).
80+
- An [interpolation](#interpolation-syntax)
81+
- An [inline element](#inline-elements-in-attributes)
8182

8283

8384
```xml
@@ -87,9 +88,22 @@ Attributes consist of a name and an optional value, valid values can be:
8788
baz={123}
8889
switch1
8990
switch2
91+
inline=(<Foo/>)
9092
/>
9193
```
9294

95+
96+
#### Inline elements in attributes
97+
98+
Inline elements are valid for attribute values, and are defined as one [element](#elements) wrapped in parenthesis `()`:
99+
100+
```xml
101+
<Example
102+
foo=(<Bar/>)
103+
/>
104+
```
105+
106+
93107
### String literals
94108

95109
String literals are text and/or interpolations wrapped in quotes. You can either use a single quote or a double quote to denote a string literal. The quote character can be used to simply escapes; double quotes don't need to be escaped in a single-quote literal, and vice versa.

Sandbox/Examples/Spyfall/PackExample.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ public static MessageComponent LocationListItem(Location location, int index, in
8787
content = cx(
8888
$"""
8989
<section
90-
accessory={cx($"<thumbnail url={location.Icon} />")}
90+
accessory=(
91+
<thumbnail url={location.Icon} />
92+
)
9193
>
9294
{content}
9395
</section>
@@ -144,9 +146,9 @@ public static MessageComponent PackHeader(Pack pack)
144146
return cx(
145147
$"""
146148
<section
147-
accessory={cx(
148-
$"<thumbnail url={pack.Icon} />"
149-
)}
149+
accessory=(
150+
<thumbnail url={pack.Icon} />
151+
)
150152
>
151153
{packHeaderText}
152154
</section>

Sandbox/Program.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
using Discord;
22
using Discord.CX.Parser;
3+
using Sandbox.Examples.Spyfall;
34
using static Discord.ComponentDesigner;
45

5-
Console.WriteLine("Hello world");
6+
var pack = new Pack(
7+
Guid.NewGuid(),
8+
"Example",
9+
"Description",
10+
null,
11+
[
12+
new Location(
13+
Guid.NewGuid(),
14+
"Location1",
15+
null,
16+
[
17+
new Role(Guid.NewGuid(), "Role1", 100, null),
18+
new Role(Guid.NewGuid(), "Role2", 100, null),
19+
],
20+
100
21+
)
22+
],
23+
new(Guid.NewGuid(), "author", 123),
24+
DateTimeOffset.Now
25+
);
26+
27+
var x = PackExample.CreatePackInfo(pack, 0);
28+
29+
Console.WriteLine(x);

src/Discord.Net.ComponentDesigner.Generator/Diagnostics.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,4 +368,22 @@ public static Diagnostic CreateParsingDiagnostic(CXDiagnostic diagnostic, Locati
368368
DiagnosticSeverity.Error,
369369
true
370370
);
371+
372+
public static readonly DiagnosticDescriptor CardinalityForcedToRuntime = new(
373+
"DC0040",
374+
"Cardinality forced to runtime check",
375+
"'{0}' can be more than 1 component, a runtime check will occur to enforce a single component",
376+
"Components",
377+
DiagnosticSeverity.Warning,
378+
true
379+
);
380+
381+
public static readonly DiagnosticDescriptor LabelComponentDuplicate = new(
382+
"DC0041",
383+
"Duplicate component definition",
384+
"A label cannot specify 'component' both in an attribute and in the children",
385+
"Components",
386+
DiagnosticSeverity.Error,
387+
true
388+
);
371389
}

src/Discord.Net.ComponentDesigner.Generator/Graph/CXGraph.cs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ out var inner
157157
inner,
158158
state,
159159
[],
160+
[],
160161
parent
161162
)
162163
];
@@ -209,13 +210,34 @@ out componentNode
209210

210211
if (state is null) return [];
211212

213+
var attributeNodes = new List<Node>();
212214
var nodeChildren = new List<Node>();
213215
var node = map[element] = state.OwningNode = new(
214216
componentNode,
215217
state,
216218
nodeChildren,
219+
attributeNodes,
217220
parent
218221
);
222+
223+
foreach (var attribute in element.Attributes)
224+
{
225+
if (attribute.Value is CXValue.Element nestedElement)
226+
{
227+
attributeNodes.AddRange(
228+
CreateNodes(
229+
manager,
230+
nestedElement.Value,
231+
node,
232+
reusedNodes,
233+
oldGraph,
234+
map,
235+
diagnostics,
236+
incrementalParseResult
237+
)
238+
);
239+
}
240+
}
219241

220242
nodeChildren.AddRange(
221243
children
@@ -251,10 +273,15 @@ public sealed class Node
251273
public ComponentNode Inner { get; }
252274
public ComponentState State => _state;
253275
public IReadOnlyList<Node> Children { get; }
276+
public IReadOnlyList<Node> AttributeNodes { get; }
254277
public Node? Parent { get; }
255278

256279
public IReadOnlyList<Diagnostic> Diagnostics
257-
=> [.._diagnostics, ..Children.SelectMany(x => x.Diagnostics)];
280+
=> [
281+
.._diagnostics,
282+
..AttributeNodes.SelectMany(x => x.Diagnostics),
283+
..Children.SelectMany(x => x.Diagnostics)
284+
];
258285

259286
public bool Incremental { get; }
260287

@@ -267,6 +294,7 @@ public Node(
267294
ComponentNode inner,
268295
ComponentState state,
269296
IReadOnlyList<Node> children,
297+
IReadOnlyList<Node> attributeNodes,
270298
Node? parent = null,
271299
IReadOnlyList<Diagnostic>? diagnostics = null,
272300
bool incremental = false,
@@ -276,6 +304,7 @@ public Node(
276304
Inner = inner;
277305
_state = state;
278306
Children = children;
307+
AttributeNodes = attributeNodes;
279308
Parent = parent;
280309
_diagnostics = [..diagnostics ?? []];
281310
_render = render;
@@ -284,7 +313,9 @@ public Node(
284313

285314
public void UpdateState(ComponentContext context)
286315
{
287-
// update children first
316+
foreach (var attributeNode in AttributeNodes)
317+
attributeNode.UpdateState(context);
318+
288319
foreach (var node in Children)
289320
node.UpdateState(context);
290321

@@ -306,6 +337,7 @@ public void Validate(ComponentContext context)
306337
using (context.CreateDiagnosticScope(_diagnostics))
307338
{
308339
Inner.Validate(State, context);
340+
foreach (var attributeNode in AttributeNodes) attributeNode.Validate(context);
309341
foreach (var child in Children) child.Validate(context);
310342
}
311343
}
@@ -364,6 +396,7 @@ public Node Reuse(Node? parent, IncrementalParseResult parseResult, CXGraphManag
364396
Inner,
365397
State,
366398
Children,
399+
AttributeNodes,
367400
parent,
368401
diagnostics,
369402
true,

src/Discord.Net.ComponentDesigner.Generator/Nodes/ComponentPropertyValue.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ namespace Discord.CX.Nodes;
66

77
public sealed record ComponentPropertyValue(
88
ComponentProperty Property,
9-
CXAttribute? Attribute
9+
CXAttribute? Attribute,
10+
CXGraph.Node? Node = null
1011
)
1112
{
1213
private CXValue? _value;

src/Discord.Net.ComponentDesigner.Generator/Nodes/ComponentState.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ public ComponentPropertyValue GetProperty(ComponentProperty property)
3333
property.Name == x.Identifier.Value || property.Aliases.Contains(x.Identifier.Value)
3434
);
3535

36-
return _properties[property] = new(property, attribute);
36+
CXGraph.Node? node = null;
37+
38+
if (attribute?.Value is CXValue.Element element)
39+
{
40+
node = OwningNode?.AttributeNodes
41+
.FirstOrDefault(x => ReferenceEquals(x.State.Source, element.Value));
42+
}
43+
44+
return _properties[property] = new(property, attribute, node);
3745
}
3846

3947
public void ReportPropertyNotAllowed(ComponentProperty property, ComponentContext context)

0 commit comments

Comments
 (0)