Skip to content

Commit e7cafe1

Browse files
authored
Merge pull request #11 from LibraStack/develop
Add AttributeUsage. Fix UxmlElement issue.
2 parents 003cf1c + c023ac7 commit e7cafe1

File tree

8 files changed

+195
-61
lines changed

8 files changed

+195
-61
lines changed

src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "com.chebanovdd.unityuxmlgenerator",
33
"displayName": "Unity Uxml Generator",
44
"author": { "name": "ChebanovDD", "url": "https://github.com/ChebanovDD" },
5-
"version": "0.0.3",
5+
"version": "0.0.4",
66
"unity": "2018.4",
77
"description": "The Unity Uxml Generator allows you to generate 'UxmlFactory' and 'UxmlTraits' source code for a custom 'VisualElement'. Just mark elements with [UxmlElement] and [UxmlAttribute] attributes.",
88
"keywords": [ "uxml", "source", "generator" ]

src/UnityUxmlGenerator/Captures/UxmlFactoryCapture.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ namespace UnityUxmlGenerator.Captures;
44

55
internal sealed class UxmlFactoryCapture : BaseCapture
66
{
7-
public UxmlFactoryCapture(ClassDeclarationSyntax @class, AttributeSyntax attribute) : base(@class)
7+
public UxmlFactoryCapture((ClassDeclarationSyntax Class, AttributeSyntax Attribute) data) : base(data.Class)
88
{
9-
Attribute = attribute;
9+
Attribute = data.Attribute;
1010
}
1111

1212
public override string ClassTag => "UxmlFactory";

src/UnityUxmlGenerator/Extensions/SyntaxNodeExtensions.cs

+23-11
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,38 @@ namespace UnityUxmlGenerator.Extensions;
55

66
internal static class SyntaxNodeExtensions
77
{
8-
public static bool IsAttributeWithName(this SyntaxNode syntaxNode, string attributeName,
9-
out AttributeSyntax? attribute)
8+
public static bool IsMemberHasAttribute<TMember>(this SyntaxNode syntaxNode, string attributeName,
9+
out (TMember Member, AttributeSyntax Attribute) result) where TMember : MemberDeclarationSyntax
1010
{
11-
if (syntaxNode is not AttributeSyntax attributeSyntax)
11+
if (syntaxNode is not TMember memberSyntax)
1212
{
13-
attribute = default;
13+
result = default;
1414
return false;
1515
}
1616

17-
attribute = attributeSyntax;
17+
result.Member = memberSyntax;
1818

19-
switch (attributeSyntax.Name)
19+
for (var i = 0; i < memberSyntax.AttributeLists.Count; i++)
2020
{
21-
case IdentifierNameSyntax identifierNameSyntax
22-
when identifierNameSyntax.Identifier.Text.Contains(attributeName):
23-
case QualifiedNameSyntax qualifiedNameSyntax
24-
when qualifiedNameSyntax.Right.Identifier.Text.Contains(attributeName):
25-
return true;
21+
var attributeList = memberSyntax.AttributeLists[i];
22+
for (var j = 0; j < attributeList.Attributes.Count; j++)
23+
{
24+
var attributeSyntax = attributeList.Attributes[j];
25+
switch (attributeSyntax.Name)
26+
{
27+
case IdentifierNameSyntax identifierNameSyntax
28+
when identifierNameSyntax.Identifier.Text.Contains(attributeName):
29+
case QualifiedNameSyntax qualifiedNameSyntax
30+
when qualifiedNameSyntax.Right.Identifier.Text.Contains(attributeName):
31+
{
32+
result.Attribute = attributeSyntax;
33+
return true;
34+
}
35+
}
36+
}
2637
}
2738

39+
result = default;
2840
return false;
2941
}
3042

src/UnityUxmlGenerator/SyntaxReceivers/UxmlFactoryReceiver.cs

+6-7
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@ internal sealed class UxmlFactoryReceiver : BaseReceiver
1515

1616
public override void OnVisitSyntaxNode(SyntaxNode syntaxNode)
1717
{
18-
if (syntaxNode.IsAttributeWithName(AttributeName, out var attribute) == false)
18+
if (syntaxNode.IsMemberHasAttribute<ClassDeclarationSyntax>(AttributeName,
19+
out (ClassDeclarationSyntax Class, AttributeSyntax Attribute) result) == false)
1920
{
2021
return;
2122
}
2223

23-
var @class = attribute!.GetParent<ClassDeclarationSyntax>();
24-
25-
if (@class.InheritsFromAnyType())
24+
if (result.Class.InheritsFromAnyType())
2625
{
27-
_captures.Add(new UxmlFactoryCapture(@class!, attribute!));
26+
_captures.Add(new UxmlFactoryCapture(result));
2827
}
29-
else if (@class is not null)
28+
else if (result.Class is not null)
3029
{
31-
RegisterDiagnostic(ClassHasNoBaseClassError, @class.GetLocation(), @class.Identifier.Text);
30+
RegisterDiagnostic(ClassHasNoBaseClassError, result.Class.GetLocation(), result.Class.Identifier.Text);
3231
}
3332
}
3433
}

src/UnityUxmlGenerator/SyntaxReceivers/UxmlTraitsReceiver.cs

+5-8
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,15 @@ internal sealed class UxmlTraitsReceiver : BaseReceiver
1616

1717
public override void OnVisitSyntaxNode(SyntaxNode syntaxNode)
1818
{
19-
if (syntaxNode.IsAttributeWithName(AttributeName, out var attribute) == false)
19+
if (syntaxNode.IsMemberHasAttribute<PropertyDeclarationSyntax>(AttributeName,
20+
out (PropertyDeclarationSyntax Property, AttributeSyntax Attribute) result) == false)
2021
{
2122
return;
2223
}
2324

24-
var property = attribute!.GetParent<PropertyDeclarationSyntax>();
25-
if (property is null)
26-
{
27-
return;
28-
}
25+
var (property, attribute) = result;
2926

30-
if (attribute!.ArgumentList is not null && attribute.ArgumentList.Arguments.Any())
27+
if (attribute.ArgumentList is not null && attribute.ArgumentList.Arguments.Any())
3128
{
3229
if (HasSameType(property, attribute.ArgumentList.Arguments.First()) == false)
3330
{
@@ -58,7 +55,7 @@ public override void OnVisitSyntaxNode(SyntaxNode syntaxNode)
5855
_captures.Add(uxmlTraits.ClassName, uxmlTraits);
5956
}
6057

61-
uxmlTraits.Properties.Add((property, attribute));
58+
uxmlTraits.Properties.Add(result);
6259
}
6360

6461
private static bool HasSameType(BasePropertyDeclarationSyntax property, AttributeArgumentSyntax attributeArgument)

src/UnityUxmlGenerator/UxmlGenerator.Attributes.cs

+20-3
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@ internal sealed partial class UxmlGenerator
99
{
1010
private const string AttributeBaseType = "global::System.Attribute";
1111

12+
private const string AttributeClassTarget = "Class";
13+
private const string AttributePropertyTarget = "Property";
14+
1215
private const string UxmlElementClassName = "UxmlElementAttribute";
1316
private const string UxmlAttributeClassName = "UxmlAttributeAttribute";
1417

1518
private static SourceText GenerateUxmlElementAttribute()
1619
{
17-
return GenerateAttributeClass(UxmlElementClassName);
20+
return GenerateAttributeClass(UxmlElementClassName, AttributeClassTarget);
1821
}
1922

2023
private static SourceText GenerateUxmlAttributeAttribute()
2124
{
22-
return GenerateAttributeClass(UxmlAttributeClassName, GetUxmlAttributeMembers());
25+
return GenerateAttributeClass(UxmlAttributeClassName, AttributePropertyTarget, GetUxmlAttributeMembers());
2326
}
2427

25-
private static SourceText GenerateAttributeClass(string attributeClassIdentifier,
28+
private static SourceText GenerateAttributeClass(string attributeClassIdentifier, string attributeTarget,
2629
IEnumerable<MemberDeclarationSyntax>? members = null)
2730
{
2831
return CompilationUnitWidget(
@@ -31,6 +34,20 @@ private static SourceText GenerateAttributeClass(string attributeClassIdentifier
3134
identifier: attributeClassIdentifier,
3235
modifiers: new[] { SyntaxKind.InternalKeyword, SyntaxKind.SealedKeyword },
3336
baseType: SimpleBaseType(IdentifierName(AttributeBaseType)),
37+
attribute: AttributeWidget(
38+
identifier: "global::System.AttributeUsage",
39+
arguments: new[]
40+
{
41+
AttributeArgument(MemberAccessWidget(
42+
identifier: "global::System.AttributeTargets",
43+
memberName: attributeTarget)),
44+
AttributeArgument(AssignmentWidget(
45+
left: IdentifierName("AllowMultiple"),
46+
right: LiteralExpression(SyntaxKind.FalseLiteralExpression))),
47+
AttributeArgument(AssignmentWidget(
48+
left: IdentifierName("Inherited"),
49+
right: LiteralExpression(SyntaxKind.FalseLiteralExpression)))
50+
}),
3451
members: members,
3552
addGeneratedCodeAttributes: true),
3653
normalizeWhitespace: true)

0 commit comments

Comments
 (0)