QJSEngine, global и script, что вызывает синтаксическую ошибку - PullRequest
0 голосов
/ 08 апреля 2020

Я использую QJSEngine , я добавил глобальный объект:

QJSValue objGlobal = pobjScriptEng->globalObject();

pobjScriptEng - указатель на экземпляр QJSEngine.

У меня есть карта глобалов, определение типа карты:

std::map<QString, QString> mpGlobals;

Я перебираю карту глобалов, добавляя их в движок:

for( mpGlobals::iterator itr=rmpGlobals.begin(); itr!=rmpGlobals.end(); itr++ ) {
    QString strName(itr->first);
    if ( objGlobal.hasProperty(strName) == false ) {
        QString strData(itr->second);
        QJSValue result = pobjScriptEng->evaluate(strData);
        objGlobal.setProperty(strName, result);
    }
}

rmpGlobals является ссылкой на карту глобалов.

У меня есть скрипт, который включает ссылку на глобал, глобал называется db и является JSON объектом, который содержит:

{"db":"test","host":"localhost","usr":"root","pass":"123456"}

I добавлены некоторые журналы отладки в l oop, который вызывает setProperty, и это то, что отображается в выходных данных приложения:

itr->first "db" 
itr->second "{\"db\":\"test\",\"host\":\"localhost\",\"usr\":\"root\",\"pass\":\"resuocra\"}"

Синтаксическая ошибка исходит от JSON, но почему нет ничего не так с этим. Я сбросил result.toString() на консоль, и он содержит:

SyntaxError: Ожидаемый токен `, '

Сценарий:

function test() {
    try{
        console.info("---------------");
        console.info("test(), Line 4");

        if ( db === undefined ) {
            console.info("db is undefined");
            return;
        }
        if ( typeof db === "object" ) {
            var mbr;
            console.info("test(), Line 7");
            console.info(db);
            console.info("test(), Line 9");

            for( mbr in db ) {
                console.info("test(), Line12");
                console.info(mbr);
                console.info("test(), Line14");
            }
            console.info("test(), Line 14");            
        }
        console.info("test(), Line 16");        
        console.info("---------------");
    } catch( e ) {
        console.warn( "test() WARNING: " + e );
    }
}

Когда Запустите мое приложение, и сценарий будет оценен. Я вижу следующее в «Выводе приложения»:

2020-04-08 08:21:36.320693+0100 XMLMPAM[3657:59571] [js] ---------------
2020-04-08 08:21:36.320732+0100 XMLMPAM[3657:59571] [js] test(), Line 4
2020-04-08 08:21:36.320747+0100 XMLMPAM[3657:59571] [js] test(), Line 7
2020-04-08 08:21:36.320762+0100 XMLMPAM[3657:59571] [js] SyntaxError: Expected token `,'
2020-04-08 08:21:36.320769+0100 XMLMPAM[3657:59571] [js] test(), Line 9
2020-04-08 08:21:36.320790+0100 XMLMPAM[3657:59571] [js] test(), Line 14
2020-04-08 08:21:36.320798+0100 XMLMPAM[3657:59571] [js] test(), Line 16
2020-04-08 08:21:36.320804+0100 XMLMPAM[3657:59571] [js] ---------------

Игнорировать все до того, как [js] будет моей меткой времени и отладочной информацией, после того, как [js] будет все вывод консоли.

Что такое:

SyntaxError: Ожидаемый токен `, '

Я не вижу ничего плохого в глобальном или скрипте.

Если я изменю скрипт и вставлю:

var db =  {"db":"test","host":"localhost","usr":"root","pass":"123456"};

В качестве первой строки синтаксическая ошибка не отображается, и все в порядке, так что не так с глобальным, добавленным с помощью setProperty ?

Вот код, который добавляет глобал к карте:

void clsXMLnode::addGlobal(QString strGlobal) {
    QStringList slstGlobal = strGlobal.split(clsXMLnode::msccGlobalDelimiter);

    if ( slstGlobal.length() == clsXMLnode::mscintAssignmentParts ) {
        QString strName(slstGlobal[clsXMLnode::mscintGlobalName].trimmed())
       ,strValue(slstGlobal[clsXMLnode::mscintGlobalValue].trimmed());
        msmpGlobals.insert(std::make_pair(strName, strValue));
    }
}

Некоторые определения:

clsXMLnode::msccGlobalDelimiter        is "="
clsXMLnode::mscintAssignmentParts      is 2
clsXMLnode::mscintGlobalName           is 0
clsXMLnode::mscintGlobalValue          is 1

1 Ответ

0 голосов
/ 08 апреля 2020

В этих строках вы устанавливаете свойства для globalObject:

QJSValue result = pobjScriptEng->evaluate( strData );
objGlobal.setProperty( strName, result );

Исключение:

SyntaxError: Ожидаемый токен `, '

связано с тем, что в конфигурации JSON отсутствуют заключенные в скобки (), поэтому оценка не удалась. Вам необходимо проверить это с помощью QJSValue::isError() метода result.

Пример (см. документация ):

QJSValue result = pobjScriptEng->evaluate( strData );
if ( result.isError() )
{
    qDebug() << "Uncaught exception at line"
             << result.property("lineNumber").toInt()
             << ":" << result.toString();
    return -1;
}

После правильного включения JSON Конфигурация будет успешно оценена, и она должна работать.

Вот полный рабочий пример с необработанными строковыми литералами для JSON и JavaScript код:

#include <QCoreApplication>
#include <QJSEngine>
#include <QJSValue>
#include <QDebug>

int main( int argc, char** argv )
{
    QCoreApplication app{ argc, argv };

    const auto raw_config =
    R"json((
    {
        "db": "test",
        "host": "localhost",
        "usr": "root",
        "pass": "123456"
    }
    ))json";

    QJSEngine engine;
    engine.installExtensions( QJSEngine::ConsoleExtension );

    const auto json_config = engine.evaluate( raw_config );
    if ( json_config.isError() )
    {
        qDebug() << "Uncaught exception at line"
                 << json_config.property("lineNumber").toInt()
                 << ":" << json_config.toString();
        return -1;
    }

    engine.globalObject().setProperty( "db", json_config );

    const auto test_script =
    R"javascript((
    function test() {
        try{
            console.info("---------------");

            if ( db === undefined ) {
                console.info("db is undefined");
                return;
            }
            else if ( typeof db === "object" ) {
                for( k in db ) {
                    console.info( k + ": " + db[k] );
                }
            }
            console.info("---------------");
        } catch( e ) {
            console.warn( "test() WARNING: " + e );
        }
    }
    ))javascript";

    auto test_func = engine.evaluate( test_script );
    if ( test_func.isError() )
    {
        qDebug() << "Uncaught exception at line"
                 << test_func.property("lineNumber").toInt()
                 << ":" << test_func.toString();
        return -1;
    }

    const auto result = test_func.call();
    if ( result.isError() )
    {
        qDebug() << "Uncaught exception at line"
                 << result.property("lineNumber").toInt()
                 << ":" << result.toString();
        return -1;
    }

    return 0;
}

Вывод:

js: ---------------
js: db: test
js: host: localhost
js: usr: root
js: pass: 123456
js: ---------------

Соответствующий JavaScript -specifi c поток в операторе группировки () Синтаксис:

...