Merge pull request #676 from JeffProgrammer/ts-errors

Optionally allow to treat script assert as warning
This commit is contained in:
Brian Roberts 2021-11-17 17:03:32 -06:00 committed by GitHub
commit 75adcb9b7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 12 deletions

View file

@ -57,11 +57,16 @@ namespace Compiler
using namespace Compiler; using namespace Compiler;
FuncVars gEvalFuncVars; FuncVars gEvalFuncVars;
FuncVars gGlobalScopeFuncVars;
FuncVars* gFuncVars = NULL; FuncVars* gFuncVars = NULL;
inline FuncVars* getFuncVars(S32 lineNumber) inline FuncVars* getFuncVars(S32 lineNumber)
{ {
AssertISV(gFuncVars, avar("Attemping to use local variable in global scope. File: %s Line: %d", CodeBlock::smCurrentParser->getCurrentFile(), lineNumber)); if (gFuncVars == &gGlobalScopeFuncVars)
{
const char* str = avar("Attemping to use local variable in global scope. File: %s Line: %d", CodeBlock::smCurrentParser->getCurrentFile(), lineNumber);
scriptErrorHandler(str);
}
return gFuncVars; return gFuncVars;
} }
@ -1552,8 +1557,7 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
tbl->add(fnName, nameSpace, varName); tbl->add(fnName, nameSpace, varName);
} }
// In eval mode, global func vars are allowed. gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : NULL;
return ip; return ip;
} }

View file

@ -38,6 +38,7 @@ CodeBlock * CodeBlock::smCurrentCodeBlock = NULL;
ConsoleParser *CodeBlock::smCurrentParser = NULL; ConsoleParser *CodeBlock::smCurrentParser = NULL;
extern FuncVars gEvalFuncVars; extern FuncVars gEvalFuncVars;
extern FuncVars gGlobalScopeFuncVars;
extern FuncVars* gFuncVars; extern FuncVars* gFuncVars;
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -637,8 +638,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
// we are an eval compile if we don't have a file name associated (no exec) // we are an eval compile if we don't have a file name associated (no exec)
gIsEvalCompile = fileName == NULL; gIsEvalCompile = fileName == NULL;
// In eval mode, global func vars are allowed. gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : NULL;
// Set up the parser. // Set up the parser.
smCurrentParser = getParserForFile(fileName); smCurrentParser = getParserForFile(fileName);
@ -678,7 +678,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
codeStream.emit(OP_RETURN_VOID); codeStream.emit(OP_RETURN_VOID);
codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs); codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs);
S32 localRegisterCount = gIsEvalCompile ? gEvalFuncVars.count() : 0; S32 localRegisterCount = gIsEvalCompile ? gEvalFuncVars.count() : gGlobalScopeFuncVars.count();
consoleAllocReset(); consoleAllocReset();

View file

@ -691,7 +691,8 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
setFrame = -1; setFrame = -1;
// Do we want this code to execute using a new stack frame? // Do we want this code to execute using a new stack frame?
if (setFrame < 0) // compiling a file will force setFrame to 0, forcing us to get a new frame.
if (setFrame <= 0)
{ {
// argc is the local count for eval // argc is the local count for eval
gEvalState.pushFrame(NULL, NULL, argc); gEvalState.pushFrame(NULL, NULL, argc);

View file

@ -35,6 +35,13 @@
#include "console/simBase.h" #include "console/simBase.h"
extern FuncVars gEvalFuncVars; extern FuncVars gEvalFuncVars;
extern FuncVars gGlobalScopeFuncVars;
extern FuncVars *gFuncVars;
namespace Con
{
extern bool scriptWarningsAsAsserts;
};
namespace Compiler namespace Compiler
{ {
@ -124,12 +131,24 @@ namespace Compiler
getFunctionStringTable().reset(); getFunctionStringTable().reset();
getIdentTable().reset(); getIdentTable().reset();
getFunctionVariableMappingTable().reset(); getFunctionVariableMappingTable().reset();
gEvalFuncVars.clear(); gGlobalScopeFuncVars.clear();
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
} }
void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); } void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); }
void consoleAllocReset() { gConsoleAllocator.freeBlocks(); } void consoleAllocReset() { gConsoleAllocator.freeBlocks(); }
void scriptErrorHandler(const char* str)
{
if (Con::scriptWarningsAsAsserts)
{
AssertISV(false, str);
}
else
{
Con::warnf(ConsoleLogEntry::Type::Script, "%s", str);
}
}
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -141,7 +160,11 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber,
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var); std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
if (found != vars.end()) if (found != vars.end())
{ {
AssertISV(!found->second.isConstant, avar("Reassigning variable %s when it is a constant. File: %s Line : %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber)); if (found->second.isConstant)
{
const char* str = avar("Script Warning: Reassigning variable %s when it is a constant. File: %s Line : %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber);
scriptErrorHandler(str);
}
return found->second.reg; return found->second.reg;
} }
@ -155,7 +178,15 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber,
S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber) S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber)
{ {
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var); std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
AssertISV(found != vars.end(), avar("Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber));
if (found == vars.end())
{
const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber);
scriptErrorHandler(str);
return assign(var, TypeReqString, lineNumber, false);
}
return found->second.reg; return found->second.reg;
} }
@ -163,7 +194,15 @@ TypeReq FuncVars::lookupType(StringTableEntry var, S32 lineNumber)
{ {
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var); std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
AssertISV(found != vars.end(), avar("Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber)); if (found == vars.end())
{
const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber);
scriptErrorHandler(str);
assign(var, TypeReqString, lineNumber, false);
return vars.find(var)->second.currentType;
}
return found->second.currentType; return found->second.currentType;
} }

View file

@ -275,6 +275,8 @@ namespace Compiler
void *consoleAlloc(U32 size); void *consoleAlloc(U32 size);
void consoleAllocReset(); void consoleAllocReset();
void scriptErrorHandler(const char* str);
extern bool gSyntaxError; extern bool gSyntaxError;
extern bool gIsEvalCompile; extern bool gIsEvalCompile;
}; };

View file

@ -274,6 +274,7 @@ static Vector< String > sInstantGroupStack( __FILE__, __LINE__ );
static DataChunker consoleLogChunker; static DataChunker consoleLogChunker;
static Vector<ConsoleLogEntry> consoleLog(__FILE__, __LINE__); static Vector<ConsoleLogEntry> consoleLog(__FILE__, __LINE__);
static bool consoleLogLocked; static bool consoleLogLocked;
bool scriptWarningsAsAsserts = true;
static bool logBufferEnabled=true; static bool logBufferEnabled=true;
static S32 printLevel = 10; static S32 printLevel = 10;
static FileStream consoleLogFile; static FileStream consoleLogFile;
@ -353,7 +354,7 @@ void init()
ConsoleConstructor::setup(); ConsoleConstructor::setup();
// Set up the parser(s) // Set up the parser(s)
CON_ADD_PARSER(CMD, TORQUE_SCRIPT_EXTENSION, true); // TorqueScript CON_ADD_PARSER(CMD, (char*)TORQUE_SCRIPT_EXTENSION, true); // TorqueScript
// Setup the console types. // Setup the console types.
ConsoleBaseType::initialize(); ConsoleBaseType::initialize();
@ -377,6 +378,7 @@ void init()
addVariable("Con::objectCopyFailures", TypeS32, &gObjectCopyFailures, "If greater than zero then it counts the number of object creation " addVariable("Con::objectCopyFailures", TypeS32, &gObjectCopyFailures, "If greater than zero then it counts the number of object creation "
"failures based on a missing copy object and does not report an error..\n" "failures based on a missing copy object and does not report an error..\n"
"@ingroup Console\n"); "@ingroup Console\n");
addVariable("Con::scriptWarningsAsAsserts", TypeBool, &scriptWarningsAsAsserts, "If true, script warnings (outside of syntax errors) will be treated as fatal asserts.");
// Current script file name and root // Current script file name and root
addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n" addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n"