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;
FuncVars gEvalFuncVars;
FuncVars gGlobalScopeFuncVars;
FuncVars* gFuncVars = NULL;
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;
}
@ -1552,8 +1557,7 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
tbl->add(fnName, nameSpace, varName);
}
// In eval mode, global func vars are allowed.
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : NULL;
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
return ip;
}

View file

@ -38,6 +38,7 @@ CodeBlock * CodeBlock::smCurrentCodeBlock = NULL;
ConsoleParser *CodeBlock::smCurrentParser = NULL;
extern FuncVars gEvalFuncVars;
extern FuncVars gGlobalScopeFuncVars;
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)
gIsEvalCompile = fileName == NULL;
// In eval mode, global func vars are allowed.
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : NULL;
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
// Set up the parser.
smCurrentParser = getParserForFile(fileName);
@ -678,7 +678,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
codeStream.emit(OP_RETURN_VOID);
codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs);
S32 localRegisterCount = gIsEvalCompile ? gEvalFuncVars.count() : 0;
S32 localRegisterCount = gIsEvalCompile ? gEvalFuncVars.count() : gGlobalScopeFuncVars.count();
consoleAllocReset();

View file

@ -691,7 +691,8 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
setFrame = -1;
// 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
gEvalState.pushFrame(NULL, NULL, argc);

View file

@ -35,6 +35,13 @@
#include "console/simBase.h"
extern FuncVars gEvalFuncVars;
extern FuncVars gGlobalScopeFuncVars;
extern FuncVars *gFuncVars;
namespace Con
{
extern bool scriptWarningsAsAsserts;
};
namespace Compiler
{
@ -124,12 +131,24 @@ namespace Compiler
getFunctionStringTable().reset();
getIdentTable().reset();
getFunctionVariableMappingTable().reset();
gEvalFuncVars.clear();
gGlobalScopeFuncVars.clear();
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
}
void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); }
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);
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;
}
@ -155,7 +178,15 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber,
S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber)
{
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;
}
@ -163,7 +194,15 @@ TypeReq FuncVars::lookupType(StringTableEntry var, S32 lineNumber)
{
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;
}

View file

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

View file

@ -274,6 +274,7 @@ static Vector< String > sInstantGroupStack( __FILE__, __LINE__ );
static DataChunker consoleLogChunker;
static Vector<ConsoleLogEntry> consoleLog(__FILE__, __LINE__);
static bool consoleLogLocked;
bool scriptWarningsAsAsserts = true;
static bool logBufferEnabled=true;
static S32 printLevel = 10;
static FileStream consoleLogFile;
@ -353,7 +354,7 @@ void init()
ConsoleConstructor::setup();
// 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.
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 "
"failures based on a missing copy object and does not report an error..\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
addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n"