目前在使用QtScriptEngine,在利用evaluate注册子函数时,要求用户输入的js文件中的内容仅仅是函数,函数体外,不能出现一些变量的声明、函数的调用等其他代码。
反复咨询DeepSeek后,终于给出了一个目前测试可用的代码:
bool isPureFunctions(const QString& code) {enum State {Normal,InFunctionBody,InLineComment,InBlockComment,InString};State state = Normal;int braceDepth = 0;bool hasFunction = false;QChar stringQuote;int functionStartDepth = 0; // 记录函数起始层级的栈for (int i = 0; i < code.length(); ++i) {const QChar c = code[i];const QChar next = (i < code.length()-1) ? code[i+1] : QChar();switch (state) {case Normal:if (c.isSpace()) {continue;} else if (c == '/' && next == '*') {state = InBlockComment;i++; // 跳过 *} else if (c == '/' && next == '/') {state = InLineComment;i++; // 跳过 /} else if (c == 'f' && code.mid(i, 8) == "function") {// 进入函数声明i += 7; // 跳过 "function"state = InFunctionBody;braceDepth = 0;hasFunction = true;functionStartDepth = 0; // 重置层级计数器} else {// 非函数代码立即拒绝if (hasFunction) return false; // 函数后出现其他代码else return false; // 函数外出现其他代码}break;case InFunctionBody:if (c == '{') {braceDepth++;if (braceDepth == 1) functionStartDepth = i; // 记录函数起始位置} else if (c == '}') {if (--braceDepth == 0) {state = Normal; // 函数体结束} else if (braceDepth < 0) {return false; // 花括号不匹配}} else if (c == '"' || c == '\'' || c == '`') {state = InString;stringQuote = c;}break;case InLineComment:if (c == '\n') state = Normal;break;case InBlockComment:if (c == '*' && next == '/') {state = Normal;i++; // 跳过 /}break;case InString:if (c == stringQuote && (i == 0 || code[i-1] != '\\')) {state = InFunctionBody;}break;}}// 最终必须回到Normal状态且至少有一个函数return state == Normal && hasFunction;
}
测试:
// 应返回 true 的有效用例
QString validCode = "function foo1(){}\n""function foo2(){ if(true){} }";
qDebug() << isPureFunctions(validCode); // 输出 true// 应返回 false 的无效用例
QString invalidCode = "function foo(){}\n""console.log(123);\n""function bar(){}";
qDebug() << isPureFunctions(invalidCode); // 输出 false