1
0
forked from liza/Questionable

Update source gen

This commit is contained in:
Liza 2024-07-21 23:10:16 +02:00
parent 26e881abc3
commit 527fa3440e
Signed by: liza
GPG Key ID: 7199F8D727D55F67
7 changed files with 331 additions and 234 deletions

View File

@ -0,0 +1,26 @@
using Questionable.Model.V1;
using Questionable.QuestPathGenerator;
using Xunit;
namespace QuestPathGenerator.Tests;
public sealed class QuestGeneratorTest
{
[Fact]
public void SyntaxNodeListWithNullValues()
{
var complexCombatData = new ComplexCombatData
{
DataId = 47,
IgnoreQuestMarker = true,
MinimumKillCount = 1,
};
var list =
RoslynShortcuts.SyntaxNodeList(
RoslynShortcuts.AssignmentList(nameof(ComplexCombatData.CompletionQuestVariablesFlags),
complexCombatData.CompletionQuestVariablesFlags)).ToList();
Assert.Empty(list);
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12</LangVersion>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="xunit" Version="2.5.3"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\QuestPathGenerator\QuestPathGenerator.csproj" />
</ItemGroup>
</Project>

View File

@ -207,6 +207,8 @@ public class QuestSourceGenerator : ISourceGenerator
} }
private static IEnumerable<SyntaxNodeOrToken> CreateQuestInitializer(ushort questId, QuestRoot quest) private static IEnumerable<SyntaxNodeOrToken> CreateQuestInitializer(ushort questId, QuestRoot quest)
{
try
{ {
return new SyntaxNodeOrToken[] return new SyntaxNodeOrToken[]
{ {
@ -241,6 +243,11 @@ public class QuestSourceGenerator : ISourceGenerator
Token(SyntaxKind.CommaToken) Token(SyntaxKind.CommaToken)
}; };
} }
catch (Exception e)
{
throw new Exception($"QuestGen[{questId}]: {e.Message}", e);
}
}
private static ExpressionSyntax CreateQuestSequence(List<QuestSequence> sequences) private static ExpressionSyntax CreateQuestSequence(List<QuestSequence> sequences)
{ {
@ -321,13 +328,15 @@ public class QuestSourceGenerator : ISourceGenerator
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Sprint), step.Sprint, emptyStep.Sprint) Assignment(nameof(QuestStep.Sprint), step.Sprint, emptyStep.Sprint)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.IgnoreDistanceToObject), step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject) Assignment(nameof(QuestStep.IgnoreDistanceToObject),
step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment) Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte) Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.AethernetShard), step.AethernetShard, emptyStep.AethernetShard) Assignment(nameof(QuestStep.AethernetShard), step.AethernetShard,
emptyStep.AethernetShard)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.AetheryteShortcut), step.AetheryteShortcut, Assignment(nameof(QuestStep.AetheryteShortcut), step.AetheryteShortcut,
emptyStep.AetheryteShortcut) emptyStep.AetheryteShortcut)
@ -357,7 +366,8 @@ public class QuestSourceGenerator : ISourceGenerator
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
AssignmentList(nameof(QuestStep.ComplexCombatData), step.ComplexCombatData) AssignmentList(nameof(QuestStep.ComplexCombatData), step.ComplexCombatData)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.CombatDelaySecondsAtStart), step.CombatDelaySecondsAtStart, Assignment(nameof(QuestStep.CombatDelaySecondsAtStart),
step.CombatDelaySecondsAtStart,
emptyStep.CombatDelaySecondsAtStart) emptyStep.CombatDelaySecondsAtStart)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination, Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination,
@ -378,11 +388,14 @@ public class QuestSourceGenerator : ISourceGenerator
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
AssignmentList(nameof(QuestStep.PointMenuChoices), step.PointMenuChoices) AssignmentList(nameof(QuestStep.PointMenuChoices), step.PointMenuChoices)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.PickUpQuestId), step.PickUpQuestId, emptyStep.PickUpQuestId) Assignment(nameof(QuestStep.PickUpQuestId), step.PickUpQuestId,
emptyStep.PickUpQuestId)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.TurnInQuestId), step.TurnInQuestId, emptyStep.TurnInQuestId) Assignment(nameof(QuestStep.TurnInQuestId), step.TurnInQuestId,
emptyStep.TurnInQuestId)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.NextQuestId), step.NextQuestId, emptyStep.NextQuestId) Assignment(nameof(QuestStep.NextQuestId), step.NextQuestId,
emptyStep.NextQuestId)
.AsSyntaxNodeOrToken()))))), .AsSyntaxNodeOrToken()))))),
Token(SyntaxKind.CommaToken), Token(SyntaxKind.CommaToken),
}.ToArray()))); }.ToArray())));

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
@ -14,7 +15,7 @@ public static class RoslynShortcuts
{ {
public static IEnumerable<SyntaxNodeOrToken> SyntaxNodeList(params SyntaxNodeOrToken?[] nodes) public static IEnumerable<SyntaxNodeOrToken> SyntaxNodeList(params SyntaxNodeOrToken?[] nodes)
{ {
nodes = nodes.Where(x => x != null).ToArray(); nodes = nodes.Where(x => x != null && x.Value.RawKind != 0).ToArray();
if (nodes.Length == 0) if (nodes.Length == 0)
return []; return [];
@ -30,6 +31,8 @@ public static class RoslynShortcuts
} }
public static ExpressionSyntax LiteralValue<T>(T? value) public static ExpressionSyntax LiteralValue<T>(T? value)
{
try
{ {
if (value is string s) if (value is string s)
return LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(s)); return LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(s));
@ -77,7 +80,8 @@ public static class RoslynShortcuts
SyntaxKind.ObjectInitializerExpression, SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>( SeparatedList<ExpressionSyntax>(
SyntaxNodeList( SyntaxNodeList(
Assignment<EAetheryteLocation?>(nameof(AethernetShortcut.From), aethernetShortcut.From, Assignment<EAetheryteLocation?>(nameof(AethernetShortcut.From),
aethernetShortcut.From,
null) null)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment<EAetheryteLocation?>(nameof(AethernetShortcut.To), aethernetShortcut.To, Assignment<EAetheryteLocation?>(nameof(AethernetShortcut.To), aethernetShortcut.To,
@ -111,7 +115,8 @@ public static class RoslynShortcuts
SyntaxKind.ObjectInitializerExpression, SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>( SeparatedList<ExpressionSyntax>(
SyntaxNodeList( SyntaxNodeList(
Assignment<EDialogChoiceType?>(nameof(DialogueChoice.Type), dialogueChoice.Type, null) Assignment<EDialogChoiceType?>(nameof(DialogueChoice.Type), dialogueChoice.Type,
null)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(DialogueChoice.ExcelSheet), dialogueChoice.ExcelSheet, Assignment(nameof(DialogueChoice.ExcelSheet), dialogueChoice.ExcelSheet,
emptyChoice.ExcelSheet) emptyChoice.ExcelSheet)
@ -134,7 +139,8 @@ public static class RoslynShortcuts
SyntaxKind.ObjectInitializerExpression, SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>( SeparatedList<ExpressionSyntax>(
SyntaxNodeList( SyntaxNodeList(
Assignment<Vector3?>(nameof(JumpDestination.Position), jumpDestination.Position, null) Assignment<Vector3?>(nameof(JumpDestination.Position), jumpDestination.Position,
null)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(JumpDestination.StopDistance), jumpDestination.StopDistance, null) Assignment(nameof(JumpDestination.StopDistance), jumpDestination.StopDistance, null)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
@ -174,7 +180,8 @@ public static class RoslynShortcuts
SyntaxKind.ObjectInitializerExpression, SyntaxKind.ObjectInitializerExpression,
SeparatedList<ExpressionSyntax>( SeparatedList<ExpressionSyntax>(
SyntaxNodeList( SyntaxNodeList(
Assignment(nameof(ComplexCombatData.DataId), complexCombatData.DataId, emptyData.DataId) Assignment(nameof(ComplexCombatData.DataId), complexCombatData.DataId,
emptyData.DataId)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(ComplexCombatData.MinimumKillCount), Assignment(nameof(ComplexCombatData.MinimumKillCount),
complexCombatData.MinimumKillCount, emptyData.MinimumKillCount) complexCombatData.MinimumKillCount, emptyData.MinimumKillCount)
@ -182,7 +189,8 @@ public static class RoslynShortcuts
Assignment(nameof(ComplexCombatData.RewardItemId), complexCombatData.RewardItemId, Assignment(nameof(ComplexCombatData.RewardItemId), complexCombatData.RewardItemId,
emptyData.RewardItemId) emptyData.RewardItemId)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(ComplexCombatData.RewardItemCount), complexCombatData.RewardItemCount, Assignment(nameof(ComplexCombatData.RewardItemCount),
complexCombatData.RewardItemCount,
emptyData.RewardItemCount) emptyData.RewardItemCount)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
AssignmentList(nameof(ComplexCombatData.CompletionQuestVariablesFlags), AssignmentList(nameof(ComplexCombatData.CompletionQuestVariablesFlags),
@ -215,11 +223,18 @@ public static class RoslynShortcuts
} }
else if (value is null) else if (value is null)
return LiteralExpression(SyntaxKind.NullLiteralExpression); return LiteralExpression(SyntaxKind.NullLiteralExpression);
else }
catch (Exception e)
{
throw new Exception($"Unable to handle literal [{value}]: {e.StackTrace}", e);
}
throw new Exception($"Unsupported data type {value.GetType()} = {value}"); throw new Exception($"Unsupported data type {value.GetType()} = {value}");
} }
public static AssignmentExpressionSyntax? Assignment<T>(string name, T? value, T? defaultValue) public static AssignmentExpressionSyntax? Assignment<T>(string name, T? value, T? defaultValue)
{
try
{ {
if (value == null && defaultValue == null) if (value == null && defaultValue == null)
return null; return null;
@ -232,9 +247,19 @@ public static class RoslynShortcuts
IdentifierName(name), IdentifierName(name),
LiteralValue(value)); LiteralValue(value));
} }
catch (Exception e)
public static AssignmentExpressionSyntax? AssignmentList<T>(string name, IEnumerable<T> value)
{ {
throw new Exception($"Unable to handle assignment [{name}]: {e.Message}", e);
}
}
public static AssignmentExpressionSyntax? AssignmentList<T>(string name, IEnumerable<T>? value)
{
try
{
if (value == null)
return null;
IEnumerable<T> list = value.ToList(); IEnumerable<T> list = value.ToList();
if (!list.Any()) if (!list.Any())
return null; return null;
@ -248,6 +273,11 @@ public static class RoslynShortcuts
LiteralValue(x)).AsSyntaxNodeOrToken()).ToArray()) LiteralValue(x)).AsSyntaxNodeOrToken()).ToArray())
))); )));
} }
catch (Exception e)
{
throw new Exception($"Unable to handle list [{name}]: {e.StackTrace}", e);
}
}
public static SyntaxNodeOrToken? AsSyntaxNodeOrToken(this SyntaxNode? node) public static SyntaxNodeOrToken? AsSyntaxNodeOrToken(this SyntaxNode? node)
{ {

View File

@ -9,8 +9,8 @@
}, },
"System.Text.Json": { "System.Text.Json": {
"type": "Transitive", "type": "Transitive",
"resolved": "8.0.3", "resolved": "8.0.4",
"contentHash": "hpagS9joOwv6efWfrMmV9MjQXpiXZH72PgN067Ysfr6AWMSD1/1hEcvh/U5mUpPLezEWsOJSuVrmqDIVD958iA==", "contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==",
"dependencies": { "dependencies": {
"System.Text.Encodings.Web": "8.0.0" "System.Text.Encodings.Web": "8.0.0"
} }
@ -18,7 +18,7 @@
"questionable.model": { "questionable.model": {
"type": "Project", "type": "Project",
"dependencies": { "dependencies": {
"System.Text.Json": "[8.0.3, )" "System.Text.Json": "[8.0.4, )"
} }
} }
} }

View File

@ -12,5 +12,5 @@ public sealed class ComplexCombatData
public uint? RewardItemId { get; set; } public uint? RewardItemId { get; set; }
public int? RewardItemCount { get; set; } public int? RewardItemCount { get; set; }
public IList<short?> CompletionQuestVariablesFlags { get; set; } = new List<short?>(); public IList<short?> CompletionQuestVariablesFlags { get; set; } = new List<short?>();
public bool IgnoreQuestMarker { get; } public bool IgnoreQuestMarker { get; set; }
} }

View File

@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPaths", "QuestPathGene
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Questionable.Model", "Questionable.Model\Questionable.Model.csproj", "{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Questionable.Model", "Questionable.Model\Questionable.Model.csproj", "{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPathGenerator.Tests", "QuestPathGenerator.Tests\QuestPathGenerator.Tests.csproj", "{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -36,5 +38,9 @@ Global
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Debug|Any CPU.Build.0 = Debug|Any CPU {E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Release|Any CPU.ActiveCfg = Release|Any CPU {E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Release|Any CPU.Build.0 = Release|Any CPU {E15144A5-AFF5-4D86-9561-AFF7DF7F505D}.Release|Any CPU.Build.0 = Release|Any CPU
{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal