Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 6 files). Show all
Unified · Split
| @@ -86,6 +86,8 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ · 85 unmodified lines | ||
| 86 | 86 | .replace("\n", "\\n") |
| 87 | 87 | .replace("\r", "\\r") |
| 88 | 88 | .replace("'", "\\'"); |
| 89 | + | |
| 90 | + // FIXME - this approach neeeds revisiting. print() comes here, which ends up doing an evaluate? | |
| 89 | 91 | engine->evaluate("Script.print('" + message + "')"); |
| 90 | 92 | |
| 91 | 93 | return QScriptValue(); |
| @@ -130,20 +132,20 @@ QString encodeEntityIdIntoEntityUrl(const QString& url, const QString& entityID) · 38 unmodified lines | ||
| 130 | 132 | return url + " [EntityID:" + entityID + "]"; |
| 131 | 133 | } |
| 132 | 134 | |
| 133 | −static bool hasCorrectSyntax(const QScriptProgram& program) { | |
| 135 | +static bool hasCorrectSyntax(const QScriptProgram& program, ScriptEngine* reportingEngine) { | |
| 134 | 136 | const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode()); |
| 135 | 137 | if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { |
| 136 | 138 | const auto error = syntaxCheck.errorMessage(); |
| 137 | 139 | const auto line = QString::number(syntaxCheck.errorLineNumber()); |
| 138 | 140 | const auto column = QString::number(syntaxCheck.errorColumnNumber()); |
| 139 | 141 | const auto message = QString("[SyntaxError] %1 in %2:%3(%4)").arg(error, program.fileName(), line, column); |
| 140 | − qCWarning(scriptengine) << qPrintable(message); | |
| 142 | + reportingEngine->scriptErrorMessage(qPrintable(message)); | |
| 141 | 143 | return false; |
| 142 | 144 | } |
| 143 | 145 | return true; |
| 144 | 146 | } |
| 145 | 147 | |
| 146 | −static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName) { | |
| 148 | +static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName, ScriptEngine* reportingEngine) { | |
| 147 | 149 | if (engine.hasUncaughtException()) { |
| 148 | 150 | const auto backtrace = engine.uncaughtExceptionBacktrace(); |
| 149 | 151 | const auto exception = engine.uncaughtException().toString(); |
| @@ -155,7 +157,7 @@ static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName · 5 unmodified lines | ||
| 155 | 157 | static const auto lineSeparator = "\n "; |
| 156 | 158 | message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator)); |
| 157 | 159 | } |
| 158 | − qCWarning(scriptengine) << qPrintable(message); | |
| 160 | + reportingEngine->scriptErrorMessage(qPrintable(message)); | |
| 159 | 161 | return true; |
| 160 | 162 | } |
| 161 | 163 | return false; |
| @@ -170,20 +172,20 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 8 unmodified lines | ||
| 170 | 172 | DependencyManager::get<ScriptEngines>()->addScriptEngine(this); |
| 171 | 173 | |
| 172 | 174 | connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) { |
| 173 | − hadUncaughtExceptions(*this, _fileNameString); | |
| 175 | + hadUncaughtExceptions(*this, _fileNameString, this); | |
| 174 | 176 | }); |
| 175 | 177 | |
| 176 | 178 | setProcessEventsInterval(MSECS_PER_SECOND); |
| 177 | 179 | } |
| 178 | 180 | |
| 179 | 181 | ScriptEngine::~ScriptEngine() { |
| 180 | − qCDebug(scriptengine) << "Script Engine shutting down:" << getFilename(); | |
| 182 | + scriptInfoMessage("Script Engine shutting down:" + getFilename()); | |
| 181 | 183 | |
| 182 | 184 | auto scriptEngines = DependencyManager::get<ScriptEngines>(); |
| 183 | 185 | if (scriptEngines) { |
| 184 | 186 | scriptEngines->removeScriptEngine(this); |
| 185 | 187 | } else { |
| 186 | − qCWarning(scriptengine) << "Script destroyed after ScriptEngines!"; | |
| 188 | + scriptWarningMessage("Script destroyed after ScriptEngines!"); | |
| 187 | 189 | } |
| 188 | 190 | } |
| 189 | 191 | |
| @@ -274,7 +276,7 @@ void ScriptEngine::runDebuggable() { · 84 unmodified lines | ||
| 274 | 276 | } |
| 275 | 277 | _lastUpdate = now; |
| 276 | 278 | // Debug and clear exceptions |
| 277 | − hadUncaughtExceptions(*this, _fileNameString); | |
| 279 | + hadUncaughtExceptions(*this, _fileNameString, this); | |
| 278 | 280 | }); |
| 279 | 281 | |
| 280 | 282 | timer->start(10); |
| @@ -359,7 +361,7 @@ void ScriptEngine::waitTillDoneRunning() { · 78 unmodified lines | ||
| 359 | 361 | QThread::yieldCurrentThread(); |
| 360 | 362 | } |
| 361 | 363 | |
| 362 | − qCDebug(scriptengine) << "Script Engine has stopped:" << getFilename(); | |
| 364 | + scriptInfoMessage("Script Engine has stopped:" + getFilename()); | |
| 363 | 365 | } |
| 364 | 366 | } |
| 365 | 367 | |
| @@ -398,10 +400,25 @@ void ScriptEngine::scriptContentsAvailable(const QUrl& url, const QString& scrip · 32 unmodified lines | ||
| 398 | 400 | emit scriptLoaded(url.toString()); |
| 399 | 401 | } |
| 400 | 402 | |
| 403 | +void ScriptEngine::scriptErrorMessage(const QString& message) { | |
| 404 | + qCCritical(scriptengine) << message; | |
| 405 | + emit errorMessage(message); | |
| 406 | +} | |
| 407 | + | |
| 408 | +void ScriptEngine::scriptWarningMessage(const QString& message) { | |
| 409 | + qCWarning(scriptengine) << message; | |
| 410 | + emit warningMessage(message); | |
| 411 | +} | |
| 412 | + | |
| 413 | +void ScriptEngine::scriptInfoMessage(const QString& message) { | |
| 414 | + qCInfo(scriptengine) << message; | |
| 415 | + emit infoMessage(message); | |
| 416 | +} | |
| 417 | + | |
| 401 | 418 | // FIXME - switch this to the new model of ScriptCache callbacks |
| 402 | 419 | void ScriptEngine::errorInLoadingScript(const QUrl& url) { |
| 403 | − qCDebug(scriptengine) << "ERROR Loading file:" << url.toString() << "line:" << __LINE__; | |
| 404 | − emit errorLoadingScript(_fileNameString); // ?? | |
| 420 | + scriptErrorMessage("ERROR Loading file:" + url.toString()); | |
| 421 | + emit errorLoadingScript(_fileNameString); | |
| 405 | 422 | } |
| 406 | 423 | |
| 407 | 424 | // Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of |
| @@ -809,7 +826,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi · 401 unmodified lines | ||
| 809 | 826 | |
| 810 | 827 | // Check syntax |
| 811 | 828 | const QScriptProgram program(sourceCode, fileName, lineNumber); |
| 812 | − if (!hasCorrectSyntax(program)) { | |
| 829 | + if (!hasCorrectSyntax(program, this)) { | |
| 813 | 830 | return QScriptValue(); |
| 814 | 831 | } |
| 815 | 832 | |
| @@ -817,7 +834,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi · 1 unmodified line | ||
| 817 | 834 | const auto result = QScriptEngine::evaluate(program); |
| 818 | 835 | --_evaluatesPending; |
| 819 | 836 | |
| 820 | − const auto hadUncaughtException = hadUncaughtExceptions(*this, program.fileName()); | |
| 837 | + const auto hadUncaughtException = hadUncaughtExceptions(*this, program.fileName(), this); | |
| 821 | 838 | emit evaluationFinished(result, hadUncaughtException); |
| 822 | 839 | return result; |
| 823 | 840 | } |
| @@ -934,10 +951,10 @@ void ScriptEngine::run() { · 110 unmodified lines | ||
| 934 | 951 | _lastUpdate = now; |
| 935 | 952 | |
| 936 | 953 | // Debug and clear exceptions |
| 937 | − hadUncaughtExceptions(*this, _fileNameString); | |
| 954 | + hadUncaughtExceptions(*this, _fileNameString, this); | |
| 938 | 955 | } |
| 939 | 956 | |
| 940 | − qCDebug(scriptengine) << "Script Engine stopping:" << getFilename(); | |
| 957 | + scriptInfoMessage("Script Engine stopping:" + getFilename()); | |
| 941 | 958 | |
| 942 | 959 | stopAllTimers(); // make sure all our timers are stopped if the script is ending |
| 943 | 960 | emit scriptEnding(); |
| @@ -1044,7 +1061,7 @@ void ScriptEngine::timerFired() { · 100 unmodified lines | ||
| 1044 | 1061 | { |
| 1045 | 1062 | auto engine = DependencyManager::get<ScriptEngines>(); |
| 1046 | 1063 | if (!engine || engine->isStopped()) { |
| 1047 | − qCDebug(scriptengine) << "Script.timerFired() while shutting down is ignored... parent script:" << getFilename(); | |
| 1064 | + scriptWarningMessage("Script.timerFired() while shutting down is ignored... parent script:" + getFilename()); | |
| 1048 | 1065 | return; // bail early |
| 1049 | 1066 | } |
| 1050 | 1067 | } |
| @@ -1084,7 +1101,7 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int · 33 unmodified lines | ||
| 1084 | 1101 | |
| 1085 | 1102 | QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) { |
| 1086 | 1103 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1087 | − qCDebug(scriptengine) << "Script.setInterval() while shutting down is ignored... parent script:" << getFilename(); | |
| 1104 | + scriptWarningMessage("Script.setInterval() while shutting down is ignored... parent script:" + getFilename()); | |
| 1088 | 1105 | return NULL; // bail early |
| 1089 | 1106 | } |
| 1090 | 1107 | |
| @@ -1093,7 +1110,7 @@ QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) · 2 unmodified lines | ||
| 1093 | 1110 | |
| 1094 | 1111 | QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) { |
| 1095 | 1112 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1096 | − qCDebug(scriptengine) << "Script.setTimeout() while shutting down is ignored... parent script:" << getFilename(); | |
| 1113 | + scriptWarningMessage("Script.setTimeout() while shutting down is ignored... parent script:" + getFilename()); | |
| 1097 | 1114 | return NULL; // bail early |
| 1098 | 1115 | } |
| 1099 | 1116 | |
| @@ -1153,8 +1170,8 @@ void ScriptEngine::print(const QString& message) { · 53 unmodified lines | ||
| 1153 | 1170 | // all of the files have finished loading. |
| 1154 | 1171 | void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) { |
| 1155 | 1172 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1156 | − qCDebug(scriptengine) << "Script.include() while shutting down is ignored..." | |
| 1157 | − << "includeFiles:" << includeFiles << "parent script:" << getFilename(); | |
| 1173 | + scriptWarningMessage("Script.include() while shutting down is ignored... includeFiles:" | |
| 1174 | + + includeFiles.join(",") + "parent script:" + getFilename()); | |
| 1158 | 1175 | return; // bail early |
| 1159 | 1176 | } |
| 1160 | 1177 | QList<QUrl> urls; |
| @@ -1182,7 +1199,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 21 unmodified lines | ||
| 1182 | 1199 | thisURL = expandScriptUrl(QUrl::fromLocalFile(expandScriptPath(file))); |
| 1183 | 1200 | QUrl defaultScriptsLoc = defaultScriptsLocation(); |
| 1184 | 1201 | if (!defaultScriptsLoc.isParentOf(thisURL)) { |
| 1185 | − qCDebug(scriptengine) << "ScriptEngine::include -- skipping" << file << "-- outside of standard libraries"; | |
| 1202 | + scriptWarningMessage("Script.include() -- skipping" + file + "-- outside of standard libraries"); | |
| 1186 | 1203 | continue; |
| 1187 | 1204 | } |
| 1188 | 1205 | isStandardLibrary = true; |
| @@ -1193,8 +1210,9 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 4 unmodified lines | ||
| 1193 | 1210 | if (!isStandardLibrary && !currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") && |
| 1194 | 1211 | (currentSandboxURL.scheme() != "file" || |
| 1195 | 1212 | !thisURL.toString(strippingFlags).startsWith(currentSandboxURL.toString(strippingFlags), getSensitivity()))) { |
| 1196 | − qCWarning(scriptengine) << "Script.include() ignoring file path" | |
| 1197 | − << thisURL << "outside of original entity script" << currentSandboxURL; | |
| 1213 | + | |
| 1214 | + scriptWarningMessage("Script.include() ignoring file path" + thisURL.toString() | |
| 1215 | + + "outside of original entity script" + currentSandboxURL.toString()); | |
| 1198 | 1216 | } else { |
| 1199 | 1217 | // We could also check here for CORS, but we don't yet. |
| 1200 | 1218 | // It turns out that QUrl.resolve will not change hosts and copy authority, so we don't need to check that here. |
| @@ -1216,7 +1234,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 15 unmodified lines | ||
| 1216 | 1234 | for (QUrl url : urls) { |
| 1217 | 1235 | QString contents = data[url]; |
| 1218 | 1236 | if (contents.isNull()) { |
| 1219 | − qCDebug(scriptengine) << "Error loading file: " << url << "line:" << __LINE__; | |
| 1237 | + scriptErrorMessage("Error loading file: " + url.toString()); | |
| 1220 | 1238 | } else { |
| 1221 | 1239 | std::lock_guard<std::recursive_mutex> lock(_lock); |
| 1222 | 1240 | if (!_includedURLs.contains(url)) { |
| @@ -1230,7 +1248,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 7 unmodified lines | ||
| 1230 | 1248 | |
| 1231 | 1249 | doWithEnvironment(capturedEntityIdentifier, capturedSandboxURL, operation); |
| 1232 | 1250 | } else { |
| 1233 | − qCDebug(scriptengine) << "Script.include() skipping evaluation of previously included url:" << url; | |
| 1251 | + scriptWarningMessage("Script.include() skipping evaluation of previously included url:" + url.toString()); | |
| 1234 | 1252 | } |
| 1235 | 1253 | } |
| 1236 | 1254 | } |
| @@ -1259,8 +1277,8 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 22 unmodified lines | ||
| 1259 | 1277 | |
| 1260 | 1278 | void ScriptEngine::include(const QString& includeFile, QScriptValue callback) { |
| 1261 | 1279 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1262 | − qCDebug(scriptengine) << "Script.include() while shutting down is ignored... " | |
| 1263 | − << "includeFile:" << includeFile << "parent script:" << getFilename(); | |
| 1280 | + scriptWarningMessage("Script.include() while shutting down is ignored... includeFile:" | |
| 1281 | + + includeFile + "parent script:" + getFilename()); | |
| 1264 | 1282 | return; // bail early |
| 1265 | 1283 | } |
| 1266 | 1284 | |
| @@ -1274,13 +1292,13 @@ void ScriptEngine::include(const QString& includeFile, QScriptValue callback) { · 7 unmodified lines | ||
| 1274 | 1292 | // the Application or other context will connect to in order to know to actually load the script |
| 1275 | 1293 | void ScriptEngine::load(const QString& loadFile) { |
| 1276 | 1294 | if (DependencyManager::get<ScriptEngines>()->isStopped()) { |
| 1277 | − qCDebug(scriptengine) << "Script.load() while shutting down is ignored... " | |
| 1278 | − << "loadFile:" << loadFile << "parent script:" << getFilename(); | |
| 1295 | + scriptWarningMessage("Script.load() while shutting down is ignored... loadFile:" | |
| 1296 | + + loadFile + "parent script:" + getFilename()); | |
| 1279 | 1297 | return; // bail early |
| 1280 | 1298 | } |
| 1281 | 1299 | if (!currentEntityIdentifier.isInvalidID()) { |
| 1282 | − qCWarning(scriptengine) << "Script.load() from entity script is ignored... " | |
| 1283 | − << "loadFile:" << loadFile << "parent script:" << getFilename(); | |
| 1300 | + scriptWarningMessage("Script.load() from entity script is ignored... loadFile:" | |
| 1301 | + + loadFile + "parent script:" + getFilename()); | |
| 1284 | 1302 | return; // bail early |
| 1285 | 1303 | } |
| 1286 | 1304 | |
| @@ -1368,7 +1386,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 81 unmodified lines | ||
| 1368 | 1386 | auto fileName = isURL ? scriptOrURL : "EmbeddedEntityScript"; |
| 1369 | 1387 | |
| 1370 | 1388 | QScriptProgram program(contents, fileName); |
| 1371 | − if (!hasCorrectSyntax(program)) { | |
| 1389 | + if (!hasCorrectSyntax(program, this)) { | |
| 1372 | 1390 | if (!isFileUrl) { |
| 1373 | 1391 | scriptCache->addScriptToBadScriptList(scriptOrURL); |
| 1374 | 1392 | } |
| @@ -1396,7 +1414,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 21 unmodified lines | ||
| 1396 | 1414 | }); |
| 1397 | 1415 | testConstructor = sandbox.evaluate(program); |
| 1398 | 1416 | } |
| 1399 | − if (hadUncaughtExceptions(sandbox, program.fileName())) { | |
| 1417 | + if (hadUncaughtExceptions(sandbox, program.fileName(), this)) { | |
| 1400 | 1418 | return; |
| 1401 | 1419 | } |
| 1402 | 1420 | |
| @@ -1410,10 +1428,10 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 7 unmodified lines | ||
| 1410 | 1428 | if (testConstructorValue.size() > maxTestConstructorValueSize) { |
| 1411 | 1429 | testConstructorValue = testConstructorValue.mid(0, maxTestConstructorValueSize) + "..."; |
| 1412 | 1430 | } |
| 1413 | − qCDebug(scriptengine) << "Error -- ScriptEngine::loadEntityScript() entity:" << entityID | |
| 1414 | − << "failed to load entity script -- expected a function, got " + testConstructorType | |
| 1415 | − << "," << testConstructorValue | |
| 1416 | − << "," << scriptOrURL; | |
| 1431 | + scriptErrorMessage("Error -- ScriptEngine::loadEntityScript() entity:" + entityID.toString() | |
| 1432 | + + "failed to load entity script -- expected a function, got " + testConstructorType | |
| 1433 | + + "," + testConstructorValue | |
| 1434 | + + "," + scriptOrURL); | |
| 1417 | 1435 | |
| 1418 | 1436 | if (!isFileUrl) { |
| 1419 | 1437 | scriptCache->addScriptToBadScriptList(scriptOrURL); |
| @@ -1513,7 +1531,7 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 93 unmodified lines | ||
| 1513 | 1531 | QString filePath = QUrl(details.scriptText).toLocalFile(); |
| 1514 | 1532 | auto lastModified = QFileInfo(filePath).lastModified().toMSecsSinceEpoch(); |
| 1515 | 1533 | if (lastModified > details.lastModified) { |
| 1516 | − qCDebug(scriptengine) << "Reloading modified script " << details.scriptText; | |
| 1534 | + scriptInfoMessage("Reloading modified script " + details.scriptText); | |
| 1517 | 1535 | |
| 1518 | 1536 | QFile file(filePath); |
| 1519 | 1537 | file.open(QIODevice::ReadOnly); |
| @@ -1521,7 +1539,7 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 1 unmodified line | ||
| 1521 | 1539 | this->unloadEntityScript(entityID); |
| 1522 | 1540 | this->entityScriptContentAvailable(entityID, details.scriptText, scriptContents, true, true); |
| 1523 | 1541 | if (!_entityScripts.contains(entityID)) { |
| 1524 | − qWarning() << "Reload script " << details.scriptText << " failed"; | |
| 1542 | + scriptWarningMessage("Reload script " + details.scriptText + " failed"); | |
| 1525 | 1543 | } else { |
| 1526 | 1544 | details = _entityScripts[entityID]; |
| 1527 | 1545 | } |
| @@ -1548,7 +1566,7 @@ void ScriptEngine::doWithEnvironment(const EntityItemID& entityID, const QUrl& s · 20 unmodified lines | ||
| 1548 | 1566 | #else |
| 1549 | 1567 | operation(); |
| 1550 | 1568 | #endif |
| 1551 | − hadUncaughtExceptions(*this, _fileNameString); | |
| 1569 | + hadUncaughtExceptions(*this, _fileNameString, this); | |
| 1552 | 1570 | |
| 1553 | 1571 | currentEntityIdentifier = oldIdentifier; |
| 1554 | 1572 | currentSandboxURL = oldSandboxURL; |