Skip to content

Commit df3518e

Browse files
add invalid value handling system
1 parent 5ebee27 commit df3518e

29 files changed

Lines changed: 249 additions & 104 deletions

Code/Extensions/SerExtensions.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using SER.Code.TokenSystem.Tokens;
77
using SER.Code.TokenSystem.Tokens.Interfaces;
88
using SER.Code.ValueSystem;
9+
using SER.Code.ValueSystem.Other;
910

1011
namespace SER.Code.Extensions;
1112

@@ -25,12 +26,19 @@ public static TryGet<TOut> SuccessTryCast<TOut>(this TryGet<Value> value) where
2526

2627
public static TryGet<TOut> TryCast<TOut>(this object value, string rawRep = "")
2728
{
28-
switch (value)
29+
if (value is null) throw new AndrzejFuckedUpException();
30+
if (value is TOut outValue) return outValue;
31+
32+
if (value is IInvalidable inv && inv.SafeValue is TOut outValue2)
33+
return outValue2;
34+
35+
if (typeof(TOut).IsGenericType && typeof(TOut).GetGenericTypeDefinition() == typeof(Invalidable<>))
2936
{
30-
case null:
31-
throw new AndrzejFuckedUpException();
32-
case TOut outValue:
33-
return outValue;
37+
var innerType = typeof(TOut).GetGenericArguments()[0];
38+
if (innerType.IsInstanceOfType(value))
39+
{
40+
return (TOut)Activator.CreateInstance(typeof(TOut), value);
41+
}
3442
}
3543

3644
string valueRep = "";
@@ -42,6 +50,11 @@ public static TryGet<TOut> TryCast<TOut>(this object value, string rawRep = "")
4250
return $"{valueRep}{value.FriendlyTypeName()} is not a {typeof(TOut).FriendlyTypeName()}";
4351
}
4452

53+
private static Type Unwrap(Type type) =>
54+
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Invalidable<>))
55+
? type.GetGenericArguments()[0]
56+
: type;
57+
4558
extension(BaseToken token)
4659
{
4760
public bool CanReturn<T>([NotNullWhen(true)] out Func<TryGet<T>>? get) where T : Value
@@ -93,7 +106,15 @@ public bool CapableOf<T>([NotNullWhen(true)] out Func<TryGet<T>>? get) where T :
93106
if (!valToken.PossibleValues.AreKnown(out var knownReturnTypes)) return true;
94107

95108
// if any of known types is assignable to T, or T to type, then it may return T
96-
return knownReturnTypes.Any(type => typeof(T).IsAssignableFrom(type) || type.IsAssignableFrom(typeof(T)));
109+
return knownReturnTypes.Any(type =>
110+
{
111+
if (typeof(T).IsAssignableFrom(type) || type.IsAssignableFrom(typeof(T))) return true;
112+
113+
var unwrappedTarget = Unwrap(typeof(T));
114+
var unwrappedSource = Unwrap(type);
115+
116+
return unwrappedTarget.IsAssignableFrom(unwrappedSource) || unwrappedSource.IsAssignableFrom(unwrappedTarget);
117+
});
97118
}
98119

99120
public TryGet<T> TryGet<T>() where T : Value

Code/FlagSystem/Flags/OnCRoleFlag.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SER.Code.ArgumentSystem.Arguments;
2+
using SER.Code.ValueSystem;
23
using SER.Code.Extensions;
34
using SER.Code.FlagSystem.Structures;
45
using SER.Code.MethodSystem.Methods.CustomRoleMethods.Structures;
@@ -72,8 +73,8 @@ public override void OnParsingComplete()
7273
script.CompileWithAutomaticThrow();
7374

7475
script.AddLocalVariables(
75-
new PlayerVariable("evPlayer", new(plr)),
76-
new ReferenceVariable("evCRole", new(role))
76+
new PlayerVariable("evPlayer", new PlayerValue(plr)),
77+
new ReferenceVariable("evCRole", new ReferenceValue(role))
7778
);
7879

7980
script.Run(RunReason.Event);

Code/Helpers/NumericExpressionReslover.cs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -109,35 +109,44 @@ private static Result ParseToken(
109109
{
110110
switch (token)
111111
{
112-
case ReferenceVariableToken referenceVariable:
112+
case IValueToken valueToken:
113113
{
114-
var tmp = MakeTempName();
115-
variables[tmp] = new(() =>
114+
valueToken.CapableOf<ReferenceValue>(out var referencefGet);
115+
valueToken.CapableOf<LiteralValue>(out var literalGet);
116+
117+
if (referencefGet is null && literalGet is null)
116118
{
117-
if (referenceVariable.ExactValue.HasErrored(out var error, out var value))
118-
{
119-
return mainErr + error;
120-
}
121-
122-
return value.IsValid
123-
? value.ToString()
124-
: "invalid";
125-
});
119+
goto default;
120+
}
126121

127-
AppendRaw(tmp);
128-
return true;
129-
}
130-
case IValueToken valueToken when valueToken.CapableOf<LiteralValue>(out var get):
131-
{
132122
var tmp = MakeTempName();
133-
134-
if (valueToken.IsConstant)
123+
124+
if (referencefGet is not null && literalGet is not null)
125+
{
126+
variables[tmp] = new(() =>
127+
{
128+
var literalVal = literalGet();
129+
if (literalVal.WasSuccessful(out var literalValue))
130+
{
131+
return literalValue.Value;
132+
}
133+
134+
var refVal = referencefGet();
135+
if (refVal.WasSuccessful(out var refValue))
136+
{
137+
return refValue.ToString();
138+
}
139+
140+
return TryGet<object>.Error($"{valueToken} did not return a reference value nor a literal value.");
141+
});
142+
}
143+
else if (referencefGet is not null)
135144
{
136-
variables[tmp] = get().OnSuccess(s => s.Value, mainErr);
145+
variables[tmp] = new(() => referencefGet.Invoke().OnSuccess(v => v.ToString()));
137146
}
138-
else
147+
else if (literalGet is not null)
139148
{
140-
variables[tmp] = new(() => get().OnSuccess(s => s.Value, mainErr));
149+
variables[tmp] = new(() => literalGet.Invoke().OnSuccess(v => v.Value));
141150
}
142151

143152
AppendRaw(tmp);

Code/MethodSystem/BaseMethods/Method.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ public override string ToString()
7373
? $"{Name} method in line {LineNum}"
7474
: $"{Name} method";
7575
}
76-
77-
public static string NameOfMethod(Type type) => type.Name[..^"Method".Length].Replace("_", ".");
76+
77+
protected static string NameOfMethod(Type type) => type.Name[..^"Method".Length].Replace("_", ".");
7878
}

Code/MethodSystem/Methods/CollectionVariableMethods/Coll_RemoveMethod.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public override void Execute()
3232
Script.AddLocalVariable(
3333
new CollectionVariable(
3434
collectionVar.Name,
35-
CollectionValue.Remove(collectionVar.Value, value, amountToRemove)
35+
CollectionValue.Remove(collectionVar, value, amountToRemove)
3636
)
3737
);
3838
}
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
11
using SER.Code.ArgumentSystem.Arguments;
22
using SER.Code.ArgumentSystem.BaseArguments;
3-
using SER.Code.Exceptions;
43
using SER.Code.MethodSystem.BaseMethods.Synchronous;
54
using SER.Code.MethodSystem.MethodDescriptors;
5+
using SER.Code.ValueSystem;
66
using SER.Code.ValueSystem.Other;
77

88
namespace SER.Code.MethodSystem.Methods.PlayerDataMethods;
99

1010
[UsedImplicitly]
11-
public class GetPlayerDataMethod : ReturningMethod, IAdditionalDescription, ICanError
11+
public class GetPlayerDataMethod : ReturningMethod, IAdditionalDescription
1212
{
1313
public override string Description => "Gets player data from the key.";
1414

15-
public string AdditionalDescription =>
16-
"WARNING: This method will error if the key doesn't exist. " +
17-
$"Use {NameOfMethod(typeof(HasPlayerDataMethod))} to verify if a key exists before calling this method.";
15+
public string AdditionalDescription => "If the key does not exist, invalid value will be returned.";
1816

1917
public override TypeOfValue Returns => new UnknownTypeOfValue();
20-
21-
public string[] ErrorReasons { get; } =
22-
[
23-
"Key was not found for the player."
24-
];
25-
18+
2619
public override Argument[] ExpectedArguments { get; } =
2720
[
2821
new PlayerArgument("player"),
@@ -34,12 +27,14 @@ public override void Execute()
3427
var player = Args.GetPlayer("player");
3528
var key = Args.GetText("key");
3629

37-
if (!SetPlayerDataMethod.PlayerData.TryGetValue(player, out var dict) ||
38-
!dict.TryGetValue(key, out var value))
30+
if (SetPlayerDataMethod.PlayerData.TryGetValue(player, out var dict) &&
31+
dict.TryGetValue(key, out var value))
3932
{
40-
throw new ScriptRuntimeError(this, ErrorReasons[0]);
33+
ReturnValue = value;
34+
}
35+
else
36+
{
37+
ReturnValue = new InvalidValue();
4138
}
42-
43-
ReturnValue = value;
4439
}
4540
}

Code/MethodSystem/Methods/VariableMethods/LogVarMethod.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class LogVarMethod : ReturningMethod<TextValue>
2020
public override void Execute()
2121
{
2222
var variable = Args.GetVariable("variable");
23-
ReturnValue = $"{variable} = {(variable is LiteralVariable lv ? lv.Value : variable.BaseValue)}"
23+
ReturnValue = $"{variable} = {(variable is LiteralVariable lv ? lv.ExactValue : variable.BaseValue)}"
2424
.ToStaticTextValue();
2525
}
2626
}

Code/Plugin/Commands/HelpSystem/HelpInfoStorage.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Interactables.Interobjects;
22
using LabApi.Features.Enums;
33
using MapGeneration;
4+
using PlayerRoles;
45
using SER.Code.FlagSystem.Flags;
56

67
namespace SER.Code.Plugin.Commands.HelpSystem;
@@ -14,6 +15,7 @@ public static class HelpInfoStorage
1415
typeof(DoorName),
1516
typeof(ItemType),
1617
typeof(ElevatorGroup),
17-
typeof(CustomCommandFlag.ConsoleType)
18+
typeof(CustomCommandFlag.ConsoleType),
19+
typeof(Team)
1820
];
1921
}

Code/ScriptSystem/Script.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using SER.Code.TokenSystem.Structures;
1717
using SER.Code.TokenSystem.Tokens;
1818
using SER.Code.TokenSystem.Tokens.VariableTokens;
19+
using SER.Code.ValueSystem;
1920
using SER.Code.VariableSystem;
2021
using SER.Code.VariableSystem.Bases;
2122
using SER.Code.VariableSystem.Structures;
@@ -42,12 +43,12 @@ public required ScriptExecutor Executor
4243
{
4344
case RemoteAdminExecutor { Sender: { } sender } when Player.Get(sender) is { } player:
4445
{
45-
AddLocalVariable(new PlayerVariable("sender", new(player)));
46+
AddLocalVariable(new PlayerVariable("sender", new PlayerValue(player)));
4647
break;
4748
}
4849
case PlayerConsoleExecutor { Sender: { } hub } when Player.Get(hub) is { } player:
4950
{
50-
AddLocalVariable(new PlayerVariable("sender", new(player)));
51+
AddLocalVariable(new PlayerVariable("sender", new PlayerValue(player)));
5152
break;
5253
}
5354
}

Code/TokenSystem/Tokenizer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ public static class Tokenizer
2929
typeof(CollectionVariableToken),
3030
typeof(ReferenceVariableToken),
3131
typeof(DurationToken),
32-
typeof(RunFunctionToken)
32+
typeof(RunFunctionToken),
33+
typeof(InvalidToken)
3334
];
3435

3536
public static readonly Type[] OrderedImportanceTokensFromCollectionSlices =

0 commit comments

Comments
 (0)