diff --git a/DMCompiler/Compiler/CompilerError.cs b/DMCompiler/Compiler/CompilerError.cs index ecf5ff6f25..f23dc9a2df 100644 --- a/DMCompiler/Compiler/CompilerError.cs +++ b/DMCompiler/Compiler/CompilerError.cs @@ -50,6 +50,7 @@ public enum WarningCode { PointlessScopeOperator = 2209, PointlessPositionalArgument = 2210, ProcArgumentGlobal = 2211, // Prepending "/" on a proc arg (e.g. "/proc/example(/var/foo)" makes the arg a global var. Ref https://www.byond.com/forum/post/2830750 + AmbiguousVarStatic = 2212, // Referencing a static variable when an instance variable with the same name exists MalformedRange = 2300, InvalidRange = 2301, InvalidSetStatement = 2302, diff --git a/DMCompiler/DM/Builders/DMExpressionBuilder.cs b/DMCompiler/DM/Builders/DMExpressionBuilder.cs index c531200e66..68f57ce4f2 100644 --- a/DMCompiler/DM/Builders/DMExpressionBuilder.cs +++ b/DMCompiler/DM/Builders/DMExpressionBuilder.cs @@ -554,13 +554,16 @@ private static DMExpression BuildIdentifier(DMASTIdentifier identifier, DMObject } var field = dmObject.GetVariable(name); - if (field != null) { + if (field != null && CurrentScopeMode == ScopeMode.Normal) { return new Field(identifier.Location, field, field.ValType); } var globalId = proc?.GetGlobalVariableId(name) ?? dmObject.GetGlobalVariableId(name); if (globalId != null) { + if (field is not null) + DMCompiler.Emit(WarningCode.AmbiguousVarStatic, identifier.Location, $"Static var definition cannot reference instance variable \"{name}\" but a global exists"); + var globalVar = DMObjectTree.Globals[globalId.Value]; var global = new GlobalField(identifier.Location, globalVar.Type, globalId.Value, globalVar.ValType); return global; diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index 723bf763bb..15b90c9727 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -350,8 +350,11 @@ public void ProcessStatementSpawn(DMASTProcStatementSpawn statementSpawn) { proc.AddLabel(afterSpawnLabel); } + /// + /// Global/static var declarations are handled by + /// public void ProcessStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration) { - if (varDeclaration.IsGlobal) { return; } //Currently handled by DMObjectBuilder + if (varDeclaration.IsGlobal) { return; } DMExpression value; if (varDeclaration.Value != null) { diff --git a/DMCompiler/DMStandard/DefaultPragmaConfig.dm b/DMCompiler/DMStandard/DefaultPragmaConfig.dm index dcbb676b88..f6adf4e312 100644 --- a/DMCompiler/DMStandard/DefaultPragmaConfig.dm +++ b/DMCompiler/DMStandard/DefaultPragmaConfig.dm @@ -32,6 +32,7 @@ #pragma SuspiciousSwitchCase warning #pragma PointlessPositionalArgument warning #pragma ProcArgumentGlobal warning // Ref BYOND issue https://www.byond.com/forum/post/2830750 +#pragma AmbiguousVarStatic warning // https://github.com/OpenDreamProject/OpenDream/issues/997 // NOTE: The next few pragmas are for OpenDream's experimental type checker // This feature is still in development, elevating these pragmas outside of local testing is discouraged // An RFC to finalize this feature is coming soon(TM) @@ -48,7 +49,7 @@ #pragma EmptyBlock notice #pragma EmptyProc disabled // NOTE: If you enable this in OD's default pragma config file, it will emit for OD's DMStandard. Put it in your codebase's pragma config file. #pragma UnsafeClientAccess disabled // NOTE: Only checks for unsafe accesses like "client.foobar" and doesn't consider if the client was already null-checked earlier in the proc -#pragma AssignmentInConditional warning +#pragma AssignmentInConditional warning #pragma PickWeightedSyntax disabled #pragma AmbiguousInOrder warning #pragma RuntimeSearchOperator disabled