Forráskód Böngészése

Merge pull request #676 from JeffProgrammer/ts-errors

Optionally allow to treat script assert as warning
Brian Roberts 3 éve
szülő
commit
75adcb9b7c

+ 7 - 3
Engine/source/console/astNodes.cpp

@@ -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;
 }

+ 3 - 3
Engine/source/console/codeBlock.cpp

@@ -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();
 

+ 2 - 1
Engine/source/console/compiledEval.cpp

@@ -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);

+ 43 - 4
Engine/source/console/compiler.cpp

@@ -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;
 }
 

+ 2 - 0
Engine/source/console/compiler.h

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

+ 3 - 1
Engine/source/console/console.cpp

@@ -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"