From 20edaafed37724afc76e1ee13b617fc79eccdfec Mon Sep 17 00:00:00 2001 From: ike709 Date: Sun, 7 Jul 2024 14:43:14 -0700 Subject: [PATCH] Lint for invalid datum[] indexing (#1877) Co-authored-by: ike709 --- .../DMProject/Tests/Dereference/DatumIndex.dm | 8 ++++++++ DMCompiler/Compiler/CompilerError.cs | 1 + DMCompiler/DM/Expressions/Dereference.cs | 16 ++++++++++++++++ DMCompiler/DMStandard/DefaultPragmaConfig.dm | 1 + 4 files changed, 26 insertions(+) create mode 100644 Content.Tests/DMProject/Tests/Dereference/DatumIndex.dm diff --git a/Content.Tests/DMProject/Tests/Dereference/DatumIndex.dm b/Content.Tests/DMProject/Tests/Dereference/DatumIndex.dm new file mode 100644 index 0000000000..fecdeecaee --- /dev/null +++ b/Content.Tests/DMProject/Tests/Dereference/DatumIndex.dm @@ -0,0 +1,8 @@ +// COMPILE ERROR +#pragma InvalidIndexOperation error + +// Indexing a datum (e.g. datum["foo"]) is not valid in BYOND 515.1641+ + +/proc/RunTest() + var/datum/meep = new + ASSERT(isnull(meep["foo"])) diff --git a/DMCompiler/Compiler/CompilerError.cs b/DMCompiler/Compiler/CompilerError.cs index 48a09d0f10..c8192a78c7 100644 --- a/DMCompiler/Compiler/CompilerError.cs +++ b/DMCompiler/Compiler/CompilerError.cs @@ -54,6 +54,7 @@ public enum WarningCode { InvalidRange = 2301, InvalidSetStatement = 2302, InvalidOverride = 2303, + InvalidIndexOperation = 2304, DanglingVarType = 2401, // For types inferred by a particular var definition and nowhere else, that ends up not existing (not forced-fatal because BYOND doesn't always error) MissingInterpolatedExpression = 2500, // A text macro is missing a required interpolated expression AmbiguousResourcePath = 2600, diff --git a/DMCompiler/DM/Expressions/Dereference.cs b/DMCompiler/DM/Expressions/Dereference.cs index afebac6cba..dcbbd903a2 100644 --- a/DMCompiler/DM/Expressions/Dereference.cs +++ b/DMCompiler/DM/Expressions/Dereference.cs @@ -114,6 +114,13 @@ private void EmitOperation(DMObject dmObject, DMProc proc, Operation operation, break; case IndexOperation indexOperation: + if (NestedPath is not null) { + var obj = DMObjectTree.GetDMObject(NestedPath.Value, false); + if (obj is not null && obj.IsSubtypeOf(DreamPath.Datum) && !obj.HasProc("operator[]")) { + DMCompiler.Emit(WarningCode.InvalidIndexOperation, Location, "Invalid index operation. datum[] index operations are not valid starting in BYOND 515.1641"); + } + } + indexOperation.Index.EmitPushValue(dmObject, proc); proc.DereferenceIndex(); break; @@ -159,12 +166,21 @@ public override DMReference EmitReference(DMObject dmObject, DMProc proc, string if (fieldOperation.Safe) { ShortCircuitHandler(proc, endLabel, shortCircuitMode); } + return DMReference.CreateField(fieldOperation.Identifier); case IndexOperation indexOperation: + if (NestedPath is not null) { + var obj = DMObjectTree.GetDMObject(NestedPath.Value, false); + if (obj is not null && obj.IsSubtypeOf(DreamPath.Datum) && !obj.HasProc("operator[]=")) { + DMCompiler.Emit(WarningCode.InvalidIndexOperation, Location, "Invalid index operation. datum[] index operations are not valid starting in BYOND 515.1641"); + } + } + if (indexOperation.Safe) { ShortCircuitHandler(proc, endLabel, shortCircuitMode); } + indexOperation.Index.EmitPushValue(dmObject, proc); return DMReference.ListIndex; diff --git a/DMCompiler/DMStandard/DefaultPragmaConfig.dm b/DMCompiler/DMStandard/DefaultPragmaConfig.dm index b9636a6d4f..e9727a82c2 100644 --- a/DMCompiler/DMStandard/DefaultPragmaConfig.dm +++ b/DMCompiler/DMStandard/DefaultPragmaConfig.dm @@ -25,6 +25,7 @@ #pragma InvalidRange error #pragma InvalidSetStatement error #pragma InvalidOverride warning +#pragma InvalidIndexOperation warning #pragma DanglingVarType warning #pragma MissingInterpolatedExpression warning #pragma AmbiguousResourcePath warning