diff --git a/QuestPathGenerator.Tests/QuestGeneratorTest.cs b/QuestPathGenerator.Tests/QuestGeneratorTest.cs new file mode 100644 index 000000000..55d4cd64b --- /dev/null +++ b/QuestPathGenerator.Tests/QuestGeneratorTest.cs @@ -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); + } +} diff --git a/QuestPathGenerator.Tests/QuestPathGenerator.Tests.csproj b/QuestPathGenerator.Tests/QuestPathGenerator.Tests.csproj new file mode 100644 index 000000000..98a27c97c --- /dev/null +++ b/QuestPathGenerator.Tests/QuestPathGenerator.Tests.csproj @@ -0,0 +1,22 @@ + + + net8.0 + enable + enable + 12 + + false + true + + + + + + + + + + + + + diff --git a/QuestPathGenerator/QuestSourceGenerator.cs b/QuestPathGenerator/QuestSourceGenerator.cs index 7184ebb07..02fc2715f 100644 --- a/QuestPathGenerator/QuestSourceGenerator.cs +++ b/QuestPathGenerator/QuestSourceGenerator.cs @@ -208,38 +208,45 @@ public class QuestSourceGenerator : ISourceGenerator private static IEnumerable CreateQuestInitializer(ushort questId, QuestRoot quest) { - return new SyntaxNodeOrToken[] + try { - InitializerExpression( - SyntaxKind.ComplexElementInitializerExpression, - SeparatedList( - new SyntaxNodeOrToken[] - { - LiteralExpression( - SyntaxKind.NumericLiteralExpression, - Literal(questId)), - Token(SyntaxKind.CommaToken), - ObjectCreationExpression( - IdentifierName(nameof(QuestRoot))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - AssignmentList(nameof(QuestRoot.Author), quest.Author) - .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestRoot.Comment), quest.Comment, null) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(QuestRoot.TerritoryBlacklist), - quest.TerritoryBlacklist).AsSyntaxNodeOrToken(), - AssignmentExpression( - SyntaxKind.SimpleAssignmentExpression, - IdentifierName(nameof(QuestRoot.QuestSequence)), - CreateQuestSequence(quest.QuestSequence)) - )))) - })), - Token(SyntaxKind.CommaToken) - }; + return new SyntaxNodeOrToken[] + { + InitializerExpression( + SyntaxKind.ComplexElementInitializerExpression, + SeparatedList( + new SyntaxNodeOrToken[] + { + LiteralExpression( + SyntaxKind.NumericLiteralExpression, + Literal(questId)), + Token(SyntaxKind.CommaToken), + ObjectCreationExpression( + IdentifierName(nameof(QuestRoot))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + AssignmentList(nameof(QuestRoot.Author), quest.Author) + .AsSyntaxNodeOrToken(), + Assignment(nameof(QuestRoot.Comment), quest.Comment, null) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(QuestRoot.TerritoryBlacklist), + quest.TerritoryBlacklist).AsSyntaxNodeOrToken(), + AssignmentExpression( + SyntaxKind.SimpleAssignmentExpression, + IdentifierName(nameof(QuestRoot.QuestSequence)), + CreateQuestSequence(quest.QuestSequence)) + )))) + })), + Token(SyntaxKind.CommaToken) + }; + } + catch (Exception e) + { + throw new Exception($"QuestGen[{questId}]: {e.Message}", e); + } } private static ExpressionSyntax CreateQuestSequence(List sequences) @@ -321,13 +328,15 @@ public class QuestSourceGenerator : ISourceGenerator .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.Sprint), step.Sprint, emptyStep.Sprint) .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.IgnoreDistanceToObject), step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject) + Assignment(nameof(QuestStep.IgnoreDistanceToObject), + step.IgnoreDistanceToObject, emptyStep.IgnoreDistanceToObject) .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.Comment), step.Comment, emptyStep.Comment) .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.Aetheryte), step.Aetheryte, emptyStep.Aetheryte) .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.AethernetShard), step.AethernetShard, emptyStep.AethernetShard) + Assignment(nameof(QuestStep.AethernetShard), step.AethernetShard, + emptyStep.AethernetShard) .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.AetheryteShortcut), step.AetheryteShortcut, emptyStep.AetheryteShortcut) @@ -357,7 +366,8 @@ public class QuestSourceGenerator : ISourceGenerator .AsSyntaxNodeOrToken(), AssignmentList(nameof(QuestStep.ComplexCombatData), step.ComplexCombatData) .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.CombatDelaySecondsAtStart), step.CombatDelaySecondsAtStart, + Assignment(nameof(QuestStep.CombatDelaySecondsAtStart), + step.CombatDelaySecondsAtStart, emptyStep.CombatDelaySecondsAtStart) .AsSyntaxNodeOrToken(), Assignment(nameof(QuestStep.JumpDestination), step.JumpDestination, @@ -378,11 +388,14 @@ public class QuestSourceGenerator : ISourceGenerator .AsSyntaxNodeOrToken(), AssignmentList(nameof(QuestStep.PointMenuChoices), step.PointMenuChoices) .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.PickUpQuestId), step.PickUpQuestId, emptyStep.PickUpQuestId) + Assignment(nameof(QuestStep.PickUpQuestId), step.PickUpQuestId, + emptyStep.PickUpQuestId) .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.TurnInQuestId), step.TurnInQuestId, emptyStep.TurnInQuestId) + Assignment(nameof(QuestStep.TurnInQuestId), step.TurnInQuestId, + emptyStep.TurnInQuestId) .AsSyntaxNodeOrToken(), - Assignment(nameof(QuestStep.NextQuestId), step.NextQuestId, emptyStep.NextQuestId) + Assignment(nameof(QuestStep.NextQuestId), step.NextQuestId, + emptyStep.NextQuestId) .AsSyntaxNodeOrToken()))))), Token(SyntaxKind.CommaToken), }.ToArray()))); diff --git a/QuestPathGenerator/RoslynShortcuts.cs b/QuestPathGenerator/RoslynShortcuts.cs index ecc3dd513..2ebecd41a 100644 --- a/QuestPathGenerator/RoslynShortcuts.cs +++ b/QuestPathGenerator/RoslynShortcuts.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Numerics; using Microsoft.CodeAnalysis; @@ -14,7 +15,7 @@ public static class RoslynShortcuts { public static IEnumerable 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) return []; @@ -31,222 +32,251 @@ public static class RoslynShortcuts public static ExpressionSyntax LiteralValue(T? value) { - if (value is string s) - return LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(s)); - else if (value is bool b) - return LiteralExpression(b ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression); - else if (value is short i16) - return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i16)); - else if (value is int i32) - return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i32)); - else if (value is byte u8) - return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u8)); - else if (value is ushort u16) - return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u16)); - else if (value is uint u32) - return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u32)); - else if (value is float f) - return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(f)); - else if (value != null && value.GetType().IsEnum) - return MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(value.GetType().Name), - IdentifierName(value.GetType().GetEnumName(value)!)); - else if (value is Vector3 vector) + try { - return ObjectCreationExpression( - IdentifierName(nameof(Vector3))) - .WithArgumentList( - ArgumentList( - SeparatedList( - new SyntaxNodeOrToken[] - { - Argument(LiteralValue(vector.X)), - Token(SyntaxKind.CommaToken), - Argument(LiteralValue(vector.Y)), - Token(SyntaxKind.CommaToken), - Argument(LiteralValue(vector.Z)) - }))); - } - else if (value is AethernetShortcut aethernetShortcut) - { - return ObjectCreationExpression( - IdentifierName(nameof(AethernetShortcut))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - Assignment(nameof(AethernetShortcut.From), aethernetShortcut.From, - null) - .AsSyntaxNodeOrToken(), - Assignment(nameof(AethernetShortcut.To), aethernetShortcut.To, - null) - .AsSyntaxNodeOrToken())))); - } - else if (value is ChatMessage chatMessage) - { - ChatMessage emptyMessage = new(); - return ObjectCreationExpression( - IdentifierName(nameof(ChatMessage))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - Assignment(nameof(ChatMessage.ExcelSheet), chatMessage.ExcelSheet, - emptyMessage.ExcelSheet) - .AsSyntaxNodeOrToken(), - Assignment(nameof(ChatMessage.Key), chatMessage.Key, - emptyMessage.Key) - .AsSyntaxNodeOrToken())))); - } - else if (value is DialogueChoice dialogueChoice) - { - DialogueChoice emptyChoice = new(); - return ObjectCreationExpression( - IdentifierName(nameof(DialogueChoice))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - Assignment(nameof(DialogueChoice.Type), dialogueChoice.Type, null) - .AsSyntaxNodeOrToken(), - Assignment(nameof(DialogueChoice.ExcelSheet), dialogueChoice.ExcelSheet, - emptyChoice.ExcelSheet) - .AsSyntaxNodeOrToken(), - Assignment(nameof(DialogueChoice.Prompt), dialogueChoice.Prompt, emptyChoice.Prompt) - .AsSyntaxNodeOrToken(), - Assignment(nameof(DialogueChoice.Yes), dialogueChoice.Yes, emptyChoice.Yes) - .AsSyntaxNodeOrToken(), - Assignment(nameof(DialogueChoice.Answer), dialogueChoice.Answer, emptyChoice.Answer) - .AsSyntaxNodeOrToken(), - Assignment(nameof(DialogueChoice.DataId), dialogueChoice.DataId, emptyChoice.DataId) - .AsSyntaxNodeOrToken())))); - } - else if (value is JumpDestination jumpDestination) - { - return ObjectCreationExpression( - IdentifierName(nameof(JumpDestination))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - Assignment(nameof(JumpDestination.Position), jumpDestination.Position, null) - .AsSyntaxNodeOrToken(), - Assignment(nameof(JumpDestination.StopDistance), jumpDestination.StopDistance, null) - .AsSyntaxNodeOrToken(), - Assignment(nameof(JumpDestination.DelaySeconds), jumpDestination.DelaySeconds, null) - .AsSyntaxNodeOrToken())))); - } - else if (value is ExcelRef excelRef) - { - if (excelRef.Type == ExcelRef.EType.Key) + if (value is string s) + return LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(s)); + else if (value is bool b) + return LiteralExpression(b ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression); + else if (value is short i16) + return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i16)); + else if (value is int i32) + return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(i32)); + else if (value is byte u8) + return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u8)); + else if (value is ushort u16) + return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u16)); + else if (value is uint u32) + return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(u32)); + else if (value is float f) + return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(f)); + else if (value != null && value.GetType().IsEnum) + return MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(value.GetType().Name), + IdentifierName(value.GetType().GetEnumName(value)!)); + else if (value is Vector3 vector) { return ObjectCreationExpression( - IdentifierName(nameof(ExcelRef))) + IdentifierName(nameof(Vector3))) .WithArgumentList( ArgumentList( - SingletonSeparatedList( - Argument(LiteralValue(excelRef.AsKey()))))); + SeparatedList( + new SyntaxNodeOrToken[] + { + Argument(LiteralValue(vector.X)), + Token(SyntaxKind.CommaToken), + Argument(LiteralValue(vector.Y)), + Token(SyntaxKind.CommaToken), + Argument(LiteralValue(vector.Z)) + }))); } - else if (excelRef.Type == ExcelRef.EType.RowId) + else if (value is AethernetShortcut aethernetShortcut) { return ObjectCreationExpression( - IdentifierName(nameof(ExcelRef))) + IdentifierName(nameof(AethernetShortcut))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(AethernetShortcut.From), + aethernetShortcut.From, + null) + .AsSyntaxNodeOrToken(), + Assignment(nameof(AethernetShortcut.To), aethernetShortcut.To, + null) + .AsSyntaxNodeOrToken())))); + } + else if (value is ChatMessage chatMessage) + { + ChatMessage emptyMessage = new(); + return ObjectCreationExpression( + IdentifierName(nameof(ChatMessage))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(ChatMessage.ExcelSheet), chatMessage.ExcelSheet, + emptyMessage.ExcelSheet) + .AsSyntaxNodeOrToken(), + Assignment(nameof(ChatMessage.Key), chatMessage.Key, + emptyMessage.Key) + .AsSyntaxNodeOrToken())))); + } + else if (value is DialogueChoice dialogueChoice) + { + DialogueChoice emptyChoice = new(); + return ObjectCreationExpression( + IdentifierName(nameof(DialogueChoice))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(DialogueChoice.Type), dialogueChoice.Type, + null) + .AsSyntaxNodeOrToken(), + Assignment(nameof(DialogueChoice.ExcelSheet), dialogueChoice.ExcelSheet, + emptyChoice.ExcelSheet) + .AsSyntaxNodeOrToken(), + Assignment(nameof(DialogueChoice.Prompt), dialogueChoice.Prompt, emptyChoice.Prompt) + .AsSyntaxNodeOrToken(), + Assignment(nameof(DialogueChoice.Yes), dialogueChoice.Yes, emptyChoice.Yes) + .AsSyntaxNodeOrToken(), + Assignment(nameof(DialogueChoice.Answer), dialogueChoice.Answer, emptyChoice.Answer) + .AsSyntaxNodeOrToken(), + Assignment(nameof(DialogueChoice.DataId), dialogueChoice.DataId, emptyChoice.DataId) + .AsSyntaxNodeOrToken())))); + } + else if (value is JumpDestination jumpDestination) + { + return ObjectCreationExpression( + IdentifierName(nameof(JumpDestination))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(JumpDestination.Position), jumpDestination.Position, + null) + .AsSyntaxNodeOrToken(), + Assignment(nameof(JumpDestination.StopDistance), jumpDestination.StopDistance, null) + .AsSyntaxNodeOrToken(), + Assignment(nameof(JumpDestination.DelaySeconds), jumpDestination.DelaySeconds, null) + .AsSyntaxNodeOrToken())))); + } + else if (value is ExcelRef excelRef) + { + if (excelRef.Type == ExcelRef.EType.Key) + { + return ObjectCreationExpression( + IdentifierName(nameof(ExcelRef))) + .WithArgumentList( + ArgumentList( + SingletonSeparatedList( + Argument(LiteralValue(excelRef.AsKey()))))); + } + else if (excelRef.Type == ExcelRef.EType.RowId) + { + return ObjectCreationExpression( + IdentifierName(nameof(ExcelRef))) + .WithArgumentList( + ArgumentList( + SingletonSeparatedList( + Argument(LiteralValue(excelRef.AsRowId()))))); + } + else + throw new Exception($"Unsupported ExcelRef type {excelRef.Type}"); + } + else if (value is ComplexCombatData complexCombatData) + { + var emptyData = new ComplexCombatData(); + return ObjectCreationExpression( + IdentifierName(nameof(ComplexCombatData))) + .WithInitializer( + InitializerExpression( + SyntaxKind.ObjectInitializerExpression, + SeparatedList( + SyntaxNodeList( + Assignment(nameof(ComplexCombatData.DataId), complexCombatData.DataId, + emptyData.DataId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(ComplexCombatData.MinimumKillCount), + complexCombatData.MinimumKillCount, emptyData.MinimumKillCount) + .AsSyntaxNodeOrToken(), + Assignment(nameof(ComplexCombatData.RewardItemId), complexCombatData.RewardItemId, + emptyData.RewardItemId) + .AsSyntaxNodeOrToken(), + Assignment(nameof(ComplexCombatData.RewardItemCount), + complexCombatData.RewardItemCount, + emptyData.RewardItemCount) + .AsSyntaxNodeOrToken(), + AssignmentList(nameof(ComplexCombatData.CompletionQuestVariablesFlags), + complexCombatData.CompletionQuestVariablesFlags), + Assignment(nameof(ComplexCombatData.IgnoreQuestMarker), + complexCombatData.IgnoreQuestMarker, + emptyData.IgnoreQuestMarker) + .AsSyntaxNodeOrToken())))); + } + else if (value is QuestWorkValue qwv) + { + return ObjectCreationExpression( + IdentifierName(nameof(QuestWorkValue))) .WithArgumentList( ArgumentList( - SingletonSeparatedList( - Argument(LiteralValue(excelRef.AsRowId()))))); + SeparatedList( + new SyntaxNodeOrToken[] + { + Argument(LiteralValue(qwv.High)), + Token(SyntaxKind.CommaToken), + Argument(LiteralValue(qwv.Low)) + }))); } - else - throw new Exception($"Unsupported ExcelRef type {excelRef.Type}"); + else if (value is List list) + { + return CollectionExpression( + SeparatedList( + SyntaxNodeList(list.Select(x => ExpressionElement( + LiteralValue(x)).AsSyntaxNodeOrToken()).ToArray()))); + } + else if (value is null) + return LiteralExpression(SyntaxKind.NullLiteralExpression); } - else if (value is ComplexCombatData complexCombatData) + catch (Exception e) { - var emptyData = new ComplexCombatData(); - return ObjectCreationExpression( - IdentifierName(nameof(ComplexCombatData))) - .WithInitializer( - InitializerExpression( - SyntaxKind.ObjectInitializerExpression, - SeparatedList( - SyntaxNodeList( - Assignment(nameof(ComplexCombatData.DataId), complexCombatData.DataId, emptyData.DataId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(ComplexCombatData.MinimumKillCount), - complexCombatData.MinimumKillCount, emptyData.MinimumKillCount) - .AsSyntaxNodeOrToken(), - Assignment(nameof(ComplexCombatData.RewardItemId), complexCombatData.RewardItemId, - emptyData.RewardItemId) - .AsSyntaxNodeOrToken(), - Assignment(nameof(ComplexCombatData.RewardItemCount), complexCombatData.RewardItemCount, - emptyData.RewardItemCount) - .AsSyntaxNodeOrToken(), - AssignmentList(nameof(ComplexCombatData.CompletionQuestVariablesFlags), - complexCombatData.CompletionQuestVariablesFlags), - Assignment(nameof(ComplexCombatData.IgnoreQuestMarker), - complexCombatData.IgnoreQuestMarker, - emptyData.IgnoreQuestMarker) - .AsSyntaxNodeOrToken())))); + throw new Exception($"Unable to handle literal [{value}]: {e.StackTrace}", e); } - else if (value is QuestWorkValue qwv) - { - return ObjectCreationExpression( - IdentifierName(nameof(QuestWorkValue))) - .WithArgumentList( - ArgumentList( - SeparatedList( - new SyntaxNodeOrToken[] - { - Argument(LiteralValue(qwv.High)), - Token(SyntaxKind.CommaToken), - Argument(LiteralValue(qwv.Low)) - }))); - } - else if (value is List list) - { - return CollectionExpression( - SeparatedList( - SyntaxNodeList(list.Select(x => ExpressionElement( - LiteralValue(x)).AsSyntaxNodeOrToken()).ToArray()))); - } - else if (value is null) - return LiteralExpression(SyntaxKind.NullLiteralExpression); - else - throw new Exception($"Unsupported data type {value.GetType()} = {value}"); + + throw new Exception($"Unsupported data type {value.GetType()} = {value}"); } public static AssignmentExpressionSyntax? Assignment(string name, T? value, T? defaultValue) { - if (value == null && defaultValue == null) - return null; + try + { + if (value == null && defaultValue == null) + return null; - if (value != null && defaultValue != null && value.Equals(defaultValue)) - return null; + if (value != null && defaultValue != null && value.Equals(defaultValue)) + return null; - return AssignmentExpression( - SyntaxKind.SimpleAssignmentExpression, - IdentifierName(name), - LiteralValue(value)); + return AssignmentExpression( + SyntaxKind.SimpleAssignmentExpression, + IdentifierName(name), + LiteralValue(value)); + } + catch (Exception e) + { + throw new Exception($"Unable to handle assignment [{name}]: {e.Message}", e); + } } - public static AssignmentExpressionSyntax? AssignmentList(string name, IEnumerable value) + public static AssignmentExpressionSyntax? AssignmentList(string name, IEnumerable? value) { - IEnumerable list = value.ToList(); - if (!list.Any()) - return null; + try + { + if (value == null) + return null; - return AssignmentExpression( - SyntaxKind.SimpleAssignmentExpression, - IdentifierName(name), - CollectionExpression( - SeparatedList( - SyntaxNodeList(list.Select(x => ExpressionElement( - LiteralValue(x)).AsSyntaxNodeOrToken()).ToArray()) - ))); + IEnumerable list = value.ToList(); + if (!list.Any()) + return null; + + return AssignmentExpression( + SyntaxKind.SimpleAssignmentExpression, + IdentifierName(name), + CollectionExpression( + SeparatedList( + SyntaxNodeList(list.Select(x => ExpressionElement( + 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) diff --git a/QuestPaths/packages.lock.json b/QuestPaths/packages.lock.json index e77d9c0c4..408e267a5 100644 --- a/QuestPaths/packages.lock.json +++ b/QuestPaths/packages.lock.json @@ -9,8 +9,8 @@ }, "System.Text.Json": { "type": "Transitive", - "resolved": "8.0.3", - "contentHash": "hpagS9joOwv6efWfrMmV9MjQXpiXZH72PgN067Ysfr6AWMSD1/1hEcvh/U5mUpPLezEWsOJSuVrmqDIVD958iA==", + "resolved": "8.0.4", + "contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==", "dependencies": { "System.Text.Encodings.Web": "8.0.0" } @@ -18,7 +18,7 @@ "questionable.model": { "type": "Project", "dependencies": { - "System.Text.Json": "[8.0.3, )" + "System.Text.Json": "[8.0.4, )" } } } diff --git a/Questionable.Model/V1/ComplexCombatData.cs b/Questionable.Model/V1/ComplexCombatData.cs index 93a0d9d41..f1e70fed8 100644 --- a/Questionable.Model/V1/ComplexCombatData.cs +++ b/Questionable.Model/V1/ComplexCombatData.cs @@ -12,5 +12,5 @@ public sealed class ComplexCombatData public uint? RewardItemId { get; set; } public int? RewardItemCount { get; set; } public IList CompletionQuestVariablesFlags { get; set; } = new List(); - public bool IgnoreQuestMarker { get; } + public bool IgnoreQuestMarker { get; set; } } diff --git a/Questionable.sln b/Questionable.sln index 5a420a9c4..0e614b410 100644 --- a/Questionable.sln +++ b/Questionable.sln @@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPaths", "QuestPathGene EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Questionable.Model", "Questionable.Model\Questionable.Model.csproj", "{E15144A5-AFF5-4D86-9561-AFF7DF7F505D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPathGenerator.Tests", "QuestPathGenerator.Tests\QuestPathGenerator.Tests.csproj", "{4FD6F346-8961-4BD5-BDA2-E5F426DE4FC7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution 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}.Release|Any CPU.ActiveCfg = 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 EndGlobal