From f6290277455da23768acb4b229c1c2a4881f565d Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Tue, 23 Jan 2024 18:37:47 +0200 Subject: [PATCH 01/10] Add succ relation and basic tests for it --- scripts/gen_translation_modules.js | 41 +- src/lib/analyses/cfg/dominate.dl | 4 +- src/lib/analyses/cfg/succ.dl | 558 +++++++++++++++++++++++++ src/lib/analyses/state_var_modified.dl | 2 +- src/lib/translate.ts | 45 ++ test/samples/analyses/cfg/do_while.sol | 15 + test/samples/analyses/cfg/for.sol | 109 +++++ test/succ.spec.ts | 313 ++++++++++++++ 8 files changed, 1082 insertions(+), 5 deletions(-) create mode 100644 src/lib/analyses/cfg/succ.dl create mode 100644 test/samples/analyses/cfg/do_while.sol create mode 100644 test/samples/analyses/cfg/for.sol create mode 100644 test/succ.spec.ts diff --git a/scripts/gen_translation_modules.js b/scripts/gen_translation_modules.js index 15680c9..6c3f324 100644 --- a/scripts/gen_translation_modules.js +++ b/scripts/gen_translation_modules.js @@ -106,6 +106,9 @@ const staticPreamble = ` .decl ExternalCall(id: FunctionCallId) .decl ConstantExpression(id: id) .decl CompilerVersion(major: number, minor: number, patch: number) +.decl nextStmt(prev: StatementId, next: StatementId) +.decl firstStmt(block: id, next: StatementId) +.decl lastStmt(block: id, next: StatementId) .decl Expression(id: id) .decl Statement(id: id) .decl StatementWithChildren(id: id) @@ -114,7 +117,7 @@ const staticPreamble = ` .decl ContractDefinition_linearizedBaseContracts(parentId: ContractDefinitionId, childId: ContractDefinitionId, idx: number) .decl ContractDefinition_usedErrors(parentId: ContractDefinitionId, childId: ErrorDefinitionId, idx: number) .decl ContractDefinition_usedEvents(parentId: ContractDefinitionId, childId: EventDefinitionId, idx: number) -.decl TupleExpression_components(parentId: TupleExpressionId, childId: ExpressionId, idx: number) +.decl TupleExpression_components(parentId: TupleExpressionId, childId: ExpressionId, idx: number, realIdx: number) .decl FunctionDefinition_modifiers(parentId: FunctionDefinitionId, childId: ModifierInvocationId, idx: number) .decl FunctionCall_arguments(parentId: FunctionCallId, childId: ExpressionId, idx: number) .decl TryStatement_clauses(parentId: TryStatementId, childId: TryCatchClauseId, idx: number) @@ -127,7 +130,7 @@ const staticPreamble = ` .decl UsingForDirective_functionList(parentId: UsingForDirectiveId, childId: IdentifierPathId, operator: symbol, idx: number) .decl StructDefinition_members(parentId: StructDefinitionId, childId: VariableDeclarationId, idx: number) .decl EnumDefinition_members(parentId: EnumDefinitionId, childId: EnumValueId, idx: number) -.decl VariableDeclarationStatement_assignments(parentId: VariableDeclarationStatementId, childId: VariableDeclarationId, idx: number) +.decl VariableDeclarationStatement_assignments(parentId: VariableDeclarationStatementId, childId: VariableDeclarationId, idx: number, realIdx: number) .decl OverrideSpecifier_overrides(parentId: OverrideSpecifierId, childId: id, idx: number) .decl FunctionCall_fieldNames(parentId: FunctionCallId, name: symbol, idx: number) @@ -739,6 +742,32 @@ function buildFactInvocation(className, constructor, baseName) { } `; } + // Add relations for sparse array arguments + for (let [paramName, ,] of params.slice(2)) { + const canonicalParamName = getCanonicalParamName(className, paramName); + if ( + !( + (className === "TupleExpression" && canonicalParamName === "components") || + (className === "VariableDeclarationStatement" && + canonicalParamName === "assignments") + ) + ) { + continue; + } + + res += ` + for (let realI = 0, i = 0; realI < nd.${canonicalParamName}.length; realI++) { + let t = nd.${canonicalParamName}[realI]; + + if (t === null || t === undefined) { + continue; + } + + res.push(\`${className}_${paramName}(\${nd.id}, \${t}, \${i}, \${realI}).\`); + i++; + } +`; + } // Add relations for array arguments for (let [paramName, optional, type] of params.slice(2)) { @@ -752,6 +781,14 @@ function buildFactInvocation(className, constructor, baseName) { const canonicalParamName = getCanonicalParamName(className, paramName); + // Skip sparse arrays. We need special logic for them + if ( + (className === "TupleExpression" && canonicalParamName === "components") || + (className === "VariableDeclarationStatement" && canonicalParamName === "assignments") + ) { + continue; + } + const args = [`\${nd.id}`]; if (type === `number[]`) { diff --git a/src/lib/analyses/cfg/dominate.dl b/src/lib/analyses/cfg/dominate.dl index e4b5a60..a69ad89 100644 --- a/src/lib/analyses/cfg/dominate.dl +++ b/src/lib/analyses/cfg/dominate.dl @@ -76,8 +76,8 @@ dominate(pred, succ) :- /// TupleExpression dominate(pred, succ) :- TupleExpression(tId), - TupleExpression_components(tId, pred, i), - TupleExpression_components(tId, succ, i + 1). + TupleExpression_components(tId, pred, i, _), + TupleExpression_components(tId, succ, i + 1, _). /// Domination is transitive dominate(pred, succ) :- dominate(pred, x), dominate(x, succ). \ No newline at end of file diff --git a/src/lib/analyses/cfg/succ.dl b/src/lib/analyses/cfg/succ.dl new file mode 100644 index 0000000..4e7f997 --- /dev/null +++ b/src/lib/analyses/cfg/succ.dl @@ -0,0 +1,558 @@ + .decl succ(prev: id, next: id) overridable + .decl succ_first(cId: id, fId: id) overridable + + /// EXPRESSIONS + + // Primitive expressions with nothing inside + // ---- Identifier + succ_first(cId, cId) :- + Identifier(cId). + + // ---- Literal + succ_first(cId, cId) :- + Literal(cId). + + // ---- ElementaryTypeNameExpression + succ_first(etneId, etneId) :- + ElementaryTypeNameExpression(etneId). + + // ---- UnaryOperation + succ_first(cId, fId) :- + UnaryOperation(cId), + UnaryOperation_subExpression(cId, subExpr), + succ_first(subExpr, fId). + + succ(prev, next) :- + UnaryOperation_subExpression(next, prev). + + // TODO: What about the case where we have a function call in the unary?? + + // ---- BinaryOperation + succ_first(cId, fId) :- + BinaryOperation(cId), + BinaryOperation_leftExpression(cId, lhsId), + succ_first(lhsId, fId). + + succ(prev, next) :- + BinaryOperation(bId), + BinaryOperation_leftExpression(bId, prev), + BinaryOperation_rightExpression(bId, rhsId), + succ_first(rhsId, next). + + succ(prev, next) :- + BinaryOperation_rightExpression(next, prev). + + // ---- Conditional + succ_first(cId, fId) :- + Conditional(cId), + Conditional_condition(cId, condId), + succ_first(condId, fId). + + succ(prev, next) :- + Conditional(cId), + Conditional_condition(cId, prev), + Conditional_trueExpression(cId, trueId), + succ_first(trueId, next). + + succ(prev, next) :- + Conditional(cId), + Conditional_condition(cId, prev), + Conditional_falseExpression(cId, falseId), + succ_first(falseId, next). + + succ(prev, next) :- + Conditional_trueExpression(next, prev). + + succ(prev, next) :- + Conditional_falseExpression(next, prev). + + // ---- Index access + // TODO: Is the base or index expresion evaluated first? + // If there is an index expression this is a normal index access + succ_first(iaId, first) :- + IndexAccess_baseExpression(iaId, beId), + IndexAccess_indexExpression(iaId, _, 1), + succ_first(beId, first). + + succ(prev, next) :- + IndexAccess_baseExpression(iaId, prev), + IndexAccess_indexExpression(iaId, ieId, 1), + succ_first(ieId, next). + + succ(prev, next) :- + IndexAccess_indexExpression(next, prev, 1). + + + // If there is no index expression this is an array type - just consider the whole thing one expression + succ_first(iaId, iaId) :- + IndexAccess_indexExpression(iaId, _, 0). + + // ---- IndexRangeAccess + // TODO: Whats the actual order between base, start and end? + succ_first(iraId, first) :- + IndexRangeAccess_baseExpression(iraId, beId), + succ_first(beId, first). + + // Case 1: Has start and end expressions + succ(prev, next) :- + IndexRangeAccess_baseExpression(iraId, prev), + IndexRangeAccess_startExpression(iraId, startExprId, 1), + succ_first(startExprId, next). + + succ(prev, next) :- + IndexRangeAccess_startExpression(iraId, prev, 1), + IndexRangeAccess_endExpression(iraId, eeId, 1), + succ_first(eeId, next). + + succ(prev, next) :- + IndexRangeAccess_endExpression(next, prev, 1). + + // Case 2: Only start expression + succ(prev, next) :- + IndexRangeAccess_endExpression(next, _, 0), + IndexRangeAccess_startExpression(next, prev, 1). + + // Case 3: Only end expression + succ(prev, next) :- + IndexRangeAccess_baseExpression(iraId, prev), + IndexRangeAccess_startExpression(iraId, _, 0), + IndexRangeAccess_endExpression(iraId, eeId, 1), + succ_first(eeId, next). + + // Case 4: No start, no end expression + succ(prev, next) :- + IndexRangeAccess_baseExpression(next, prev), + IndexRangeAccess_startExpression(next, _, 0), + IndexRangeAccess_endExpression(next, _, 0). + + // ---- Assignment + // TODO: Is the left or right side of the assignment evaluated first? + succ_first(aId, first) :- + Assignment_leftHandSide(aId, lhsId), + succ_first(lhsId, first). + + succ(prev, next) :- + Assignment_leftHandSide(aId, prev), + Assignment_rightHandSide(aId, rhsId), + succ_first(rhsId, next). + + succ(prev, next) :- + Assignment_rightHandSide(next, prev). + + // ---- FunctionCallOptions + // TODO: The ordering for FunctionCallOptions is not quite correct. + // We just enforce that the options are evaluated before the base expression. + // We don't enforce an ordering between the option expression, or that they are + // all evaluated (instead that one of them is non-deterministically evaluted) + succ_first(fcoptsId, first) :- + FunctionCallOptions_options(fcoptsId, _, optId), + succ_first(optId, first). + + succ(prev, next) :- + FunctionCallOptions_options(fcoptsId, _, prev), + FunctionCallOptions_expression(fcoptsId, baseId), + succ_first(baseId, next). + + + succ(prev, next) :- + FunctionCallOptions_expression(next, prev). + + // ---- FunctionCall + // TODO: Is the callee or arguments evaluated first? + succ_first(fcId, first) :- + FunctionCall_expression(fcId, exprId), + succ_first(exprId, first). + + // Has arguments - after base the whole call executes + succ(prev, next) :- + FunctionCall_expression(fcId, prev), + FunctionCall_arguments(fcId, firstArgId, 0), + succ_first(firstArgId, next). + + // No arguments case - after base the whole call executes + succ(prev, next) :- + FunctionCall_expression(next, prev), + (!FunctionCall_arguments(next, _, 0)). + + // Ordering between args + succ(prev, next) :- + FunctionCall_arguments(fcId, prev, i), + FunctionCall_arguments(fcId, nextArg, i + 1), + succ_first(nextArg, next). + + // After last arg whole call executes + succ(prev, next) :- + FunctionCall_arguments(next, prev, i), + (!FunctionCall_arguments(next, _, i + 1)). + + // ---- MemberAccess + succ_first(maId, first) :- + MemberAccess_expression(maId, baseId), + succ_first(baseId, first). + + succ(prev, next) :- + MemberAccess_expression(next, prev). + + // NewExpression + succ_first(first, first) :- + NewExpression(first). + + // Tuple expression + // TODO: What is the order of evaluation of elements? + // Case 1: Non-empty tuple + succ_first(teId, first) :- + TupleExpression_components(teId, firstCompId, 0, _), + succ_first(firstCompId, first). + + succ(prev, next) :- + TupleExpression_components(teId, prev, i, _), + TupleExpression_components(teId, nextComp, i+1, _), + succ_first(nextComp, next). + + succ(prev, next) :- + TupleExpression_components(next, prev, i, _), + (!TupleExpression_components(next, _, i+1, _)). + + // Case 2: Non-empty tuple + succ_first(teId, teId) :- + TupleExpression(teId), + !TupleExpression_components(teId, _, _, _). + +// Statements succ + // ---------- HELPERS ------------- + // True if nd is a checked or unchecked block + .decl isBlock(nd: id) + isBlock(nd) :- (Block(nd) ; UncheckedBlock(nd)). + + // True if nd is a "fall-through" statement (i.e. if control-flow may continue to the next statement). + .decl fallThrough(node: id) + // Non-block fall-through statements + fallThrough(id) :- + Statement(id), + !isBlock(id), + !(Return(id) ; Break(id) ; Continue(id); RevertStatement(id); Throw(id)). + + // Empty blocks are fall-through + fallThrough(id) :- + isBlock(id), + !lastStmt(id, _). + + // Blocks whose last statement is fall-through are also fall-through + fallThrough(id) :- + isBlock(id), + lastStmt(id, lastStmt), + fallThrough(lastStmt). + + // True if nd is not a "fall-through" statement (i.e. if control-flow does not continue to the next statement). + .decl noFallThrough(nd: id) + noFallThrough(nd) :- Statement(nd), !fallThrough(nd). + + // True if nd is a loop statement. + .decl isLoop(node: id) + isLoop(id) :- (ForStatement(id) ; WhileStatement(id) ; DoWhileStatement(id)). + + // Return the closest enclosing loop `loopId` to `node` + .decl enclosingLoop(node: id, loopId: id) + + enclosingLoop(id, id) :- isLoop(id). + enclosingLoop(id, loopId) :- + parent(ptId, id), + (!isLoop(id)), + enclosingLoop(ptId, loopId). + + // ---------- Statement Relations ------------- + // ---- Block or UncheckedBlock + // For non-empty blocks the first thing in the first statement is first + succ_first(bId, first) :- + firstStmt(bId, firstStmtId), // this ensures bId is a block + succ_first(firstStmtId, first). + + // For empty blocks we consider them immediately executed + succ_first(bId, bId) :- + isBlock(bId), + !firstStmt(bId, _). + + // Control flow goes from one statement to the next in a block, if the prev + // is not a terminator + succ(prev, next) :- + fallThrough(prev), + nextStmt(prev, nextStmt), + succ_first(nextStmt, next). + + // The block is considered executed, after the last statement executes, if + // the last statement is not a terminator + succ(prev, next) :- + lastStmt(next, prev), + fallThrough(prev). + + // ---- ExpressionStatement + succ_first(exprStmtId, first) :- + ExpressionStatement_expression(exprStmtId, exprId), + succ_first(exprId, first). + + succ(prev, next) :- + ExpressionStatement_expression(next, prev). + + // ---- IfStatement + // The condition executes first in an if statement + succ_first(ifId, first) :- + IfStatement_condition(ifId, cId), + succ_first(cId, first). + + // After the condition the true body may execute + succ(prev, next) :- + IfStatement_condition(ifId, prev), + IfStatement_trueBody(ifId, trueId), + succ_first(trueId, next). + + // After the condition the false body may execute + succ(prev, next) :- + IfStatement_condition(ifId, prev), + IfStatement_falseBody(ifId, falseId, 1), + succ_first(falseId, next). + + // After the true body, the whole if statement is considered executed + succ(prev, next) :- + IfStatement_trueBody(next, prev). + + // After the false body, the whole if statement is considered executed + succ(prev, next) :- + IfStatement_falseBody(next, prev, 1). + + + // If there is no false body, after the condition the whole if statement may be executed + succ(prev, next) :- + IfStatement_condition(next, prev), + IfStatement_falseBody(next, _, 0). + + // ---- Break + succ_first(brId, brId) :- + Break(brId). + + // After a Break the closest enclosing loop is considered executed + succ(prev, next) :- + Break(prev), + enclosingLoop(prev, next). + + // ---- Continue + succ_first(cId, cId) :- + Continue(cId). + + // After continue, we execute the condition of the closest loop + // (if its while/do while) + succ(prev, next) :- + Continue(prev), + enclosingLoop(prev, loopId), + ( + WhileStatement_condition(loopId, condId); + DoWhileStatement_condition(loopId, condId) + ), + succ_first(condId, next). + + // After continue we execute the increment statement if there is one, of the closeset `for` loop + succ(prev, next) :- + Continue(prev), + enclosingLoop(prev, loopId), + ForStatement_loopExpression(loopId, loopExpr, 1), + succ_first(loopExpr, next). + + // After continue we execute the condtion, if there is one, of the closeset `for` loop without an increment statement + succ(prev, next) :- + Continue(prev), + enclosingLoop(prev, loopId), + ForStatement_loopExpression(loopId, _, 0), + ForStatement_condition(loopId, cond, 1), + succ_first(cond, next). + + // After continue we execute the body of the closeset `for` loop without an increment statement or condition + succ(prev, next) :- + Continue(prev), + enclosingLoop(prev, loopId), + ForStatement_loopExpression(loopId, _, 0), + ForStatement_condition(loopId, _, 0), + ForStatement_body(loopId, body), + succ_first(body, next). + + // ---- WhileStatement + // Condition is executed first in a while statement + succ_first(wsId, first) :- + WhileStatement_condition(wsId, cId), + succ_first(cId, first). + + // After the condition we can execute the body + succ(prev, next) :- + WhileStatement_condition(wsId, prev), + WhileStatement_body(wsId, bodyId), + succ_first(bodyId, next). + + // After the condition we can finish executing the loop + succ(prev, next) :- + WhileStatement_condition(next, prev). + + // After the body we execute the condition again + succ(prev, next) :- + WhileStatement_body(wsId, prev), + WhileStatement_condition(wsId, next). + + // ---- DoWhileStatement + // Execute the body of a do-while statement first + succ_first(dwId, first) :- + DoWhileStatement_body(dwId, bodyId), + succ_first(bodyId, first). + + // After the body we always execute the condition + succ(prev, next) :- + DoWhileStatement_body(dwId, prev), + DoWhileStatement_condition(dwId, condId), + succ_first(condId, next). + + // After the condition we may execute the body or consider the whole statement executed. + succ(prev, next) :- + DoWhileStatement_condition(dwId, prev), + DoWhileStatement_body(dwId, next). + + succ(prev, next) :- + DoWhileStatement_condition(next, prev). + + // --- ForStatement + // If the for has an initialization expr its executed first + succ_first(fsId, first) :- + ForStatement_initializationExpression(fsId, ieId, 1), + succ_first(ieId, first). + + // If the for doesnt have an initialization expr, but has a condition its executed first + succ_first(fsId, first) :- + ForStatement_initializationExpression(fsId, _, 0), + ForStatement_condition(fsId, cId, 1), + succ_first(cId, first). + + // If the for doesnt have an initialization expr or a condition, the body is first + succ_first(fsId, first) :- + ForStatement_initializationExpression(fsId, _, 0), + ForStatement_condition(fsId, _, 0), + ForStatement_body(fsId, body), + succ_first(body, first). + + // After an initialization statement we execute the condition (if there is one) + succ(prev, next) :- + ForStatement_initializationExpression(fsId, prev, 1), + ForStatement_condition(fsId, cId, 1), + succ_first(cId, next). + + // After an initialization statement we execute the body (if there is no condition) + succ(prev, next) :- + ForStatement_initializationExpression(fsId, prev, 1), + ForStatement_condition(fsId, _, 0), + ForStatement_body(fsId, body), + succ_first(body, next). + + // After the condition we execute the body + succ(prev, next) :- + ForStatement_condition(fsId, prev, 1), + ForStatement_body(fsId, body), + succ_first(body, next). + + // After the body we execute the loop expression (if there is one) + succ(prev, next) :- + ForStatement_body(fsId, prev), + ForStatement_loopExpression(fsId, leId, 1), + succ_first(leId, next). + + // After the body we execute the condition (if there is no loop expression) + succ(prev, next) :- + ForStatement_body(fsId, prev), + ForStatement_loopExpression(fsId, leId, 0), + ForStatement_condition(fsId, condId, 1), + succ_first(condId, next). + + // After the body we execute the body again (if there is no loop expression or condition) + succ(prev, next) :- + ForStatement_body(fsId, prev), + ForStatement_loopExpression(fsId, leId, 0), + ForStatement_condition(fsId, condId, 0), + succ_first(prev, next). + + // After the loop expression we execute the condition (if there is one) + succ(prev, next) :- + ForStatement_loopExpression(fsId, prev, 1), + ForStatement_condition(fsId, condId, 1), + succ_first(condId, next). + + // After the condition we may exit the loop + succ(prev, next) :- + ForStatement_condition(next, prev, 1). + + // ---- InlineAssembly + succ_first(iaId, iaId) :- + InlineAssembly(iaId). + + // ---- Return + succ_first(retId, first) :- + Return_expression(retId, exprId, 1), + succ_first(exprId, first). + + succ_first(retId, retId) :- + Return_expression(retId, _, 0). + + succ(prev, next) :- + Return_expression(next, prev, 1). + + // ---- RevertStatement + succ_first(revId, first) :- + RevertStatement_errorCall(revId, callId), + succ_first(callId, first). + + succ(prev, next) :- + RevertStatement_errorCall(next, prev). + + // ---- Throw + succ_first(throwId, throwId) :- + Throw(throwId). + + // ---- TryStatement + // We first execute the external call in the try + succ_first(tsId, first) :- + TryStatement_externalCall(tsId, callId), + succ_first(callId, first). + + // After the external call in the try we may execute any of the clauses + succ(prev, next) :- + TryStatement_externalCall(tsId, prev), + TryStatement_clauses(tsId, clauseId, _), + succ_first(clauseId, next). + + // After any of the clauses the whole try/catch is finished + succ(prev, next) :- + TryStatement_clauses(next, prev, _). + + // ---- TryCatchClause + succ_first(tccId, first) :- + TryCatchClause_block(tccId, blockId), + succ_first(blockId, first). + + succ(prev, next) :- + TryCatchClause_block(next, prev). + + // ---- VariableDeclarationStatement + succ_first(vdsId, first) :- + VariableDeclarationStatement_initialValue(vdsId, ivId, 1), + succ_first(ivId, first). + + succ_first(vdsId, vdsId) :- + VariableDeclarationStatement_initialValue(vdsId, _, 0). + + succ(prev, next) :- + VariableDeclarationStatement_initialValue(next, prev, 1). + + // --- PlaceholderStatement + // Note: succ relation doesnt do anything with placehodler statements. + // We use a higher-level relation to tie toghether placeholders and function + // modifiers in the context of a particular FunctionDefinition. + + // --- EmitStatement + succ_first(esId, first) :- + EmitStatement_eventCall(esId, evCall), + succ_first(evCall, first). + + succ(prev, next) :- + EmitStatement_eventCall(next, prev). diff --git a/src/lib/analyses/state_var_modified.dl b/src/lib/analyses/state_var_modified.dl index ba2bfc3..64b7890 100644 --- a/src/lib/analyses/state_var_modified.dl +++ b/src/lib/analyses/state_var_modified.dl @@ -27,7 +27,7 @@ stateVarModifiedInLHS(varId, exprId) :- stateVarModifiedInLHS(varId, exprId) :- TupleExpression(exprId), TupleExpression_isInlineArray(exprId, 0), - TupleExpression_components(exprId, componentId, _), + TupleExpression_components(exprId, componentId, _, _), componentId >= 0, stateVarModifiedInLHS(varId, componentId). diff --git a/src/lib/translate.ts b/src/lib/translate.ts index 7056b6e..ed040d9 100644 --- a/src/lib/translate.ts +++ b/src/lib/translate.ts @@ -37,10 +37,55 @@ function translateNode(nd: sol.ASTNode, infer: sol.InferType): string[] { return res; } +/** + * Walk a block, skipping any nested/empty blocks and return a list of the + * top-level statements in the block in order. So for example for: + * ``` + * {{}} + * i=0; + * unchecked {{ i++; {} }} + * i--; + * {} + * ``` + * + * This function will return [`i=0`, `i++`, `i--`] + */ +function linearizeStmts(nd: sol.Block | sol.UncheckedBlock): sol.Statement[] { + const res: sol.Statement[] = []; + + for (const stmt of nd.vStatements) { + if (stmt instanceof sol.Block || stmt instanceof sol.UncheckedBlock) { + res.push(...linearizeStmts(stmt)); + } else if (stmt instanceof sol.Statement) { + res.push(stmt); + } + } + + return res; +} + function translateUnit(unit: sol.SourceUnit, infer: sol.InferType): string[] { const res: string[] = []; unit.walk((nd) => res.push(...translateNode(nd, infer))); + // Add firstStmt and nextStmt + unit.walk((nd) => { + if (!(nd instanceof sol.Block || nd instanceof sol.UncheckedBlock)) { + return; + } + + const stmts = linearizeStmts(nd); + + if (stmts.length > 0) { + res.push(`firstStmt(${nd.id}, ${stmts[0].id}).`); + res.push(`lastStmt(${nd.id}, ${stmts[stmts.length - 1].id}).`); + } + + for (let i = 0; i < stmts.length - 1; i++) { + res.push(`nextStmt(${stmts[i].id}, ${stmts[i + 1].id}).`); + } + }); + return res; } diff --git a/test/samples/analyses/cfg/do_while.sol b/test/samples/analyses/cfg/do_while.sol new file mode 100644 index 0000000..662bf6c --- /dev/null +++ b/test/samples/analyses/cfg/do_while.sol @@ -0,0 +1,15 @@ +pragma solidity 0.8.17; + +contract Foo { + function main() public returns (uint) { + uint x = 1; + uint sum = 0; + + do { + sum += x; + x = x + 1; + } while (x < 10); + + return sum; + } +} diff --git a/test/samples/analyses/cfg/for.sol b/test/samples/analyses/cfg/for.sol new file mode 100644 index 0000000..59fa067 --- /dev/null +++ b/test/samples/analyses/cfg/for.sol @@ -0,0 +1,109 @@ +pragma solidity 0.8.17; + +contract Foo { + function for1() public returns (uint) { + uint sum = 0; + + for (uint x = 1; x < 10; x++) { + sum += x; + } + + return sum; + } + + function for2() public returns (uint) { + uint x = 1; + uint sum = 0; + + for (; x < 10; x++) { + sum += x; + } + + return sum; + } + + function for3() public returns (uint) { + uint x = 1; + uint sum = 0; + + for (; x < 10;) { + sum += x; + x++; + } + + return sum; + } + + function for4() public returns (uint) { + uint x = 1; + uint sum = 0; + + for (; ;) { + sum += x; + x++; + + if (x >= 10) { + break; + } + } + + return sum; + } + + function for5() public returns (uint) { + uint x = 1; + uint sum = 0; + + for (; ; x++) { + sum += x; + + if (x >= 10) { + break; + } + } + + return sum; + } + + function for6() public returns (uint) { + + uint sum = 0; + + for (uint x = 1; ; x++) { + sum += x; + + if (x >= 10) { + break; + } + } + + return sum; + } + + function for7() public returns (uint) { + + uint sum = 0; + + for (uint x = 1; x < 10;) { + sum += x; + x++; + } + + return sum; + } + + function for8() public returns (uint) { + uint sum = 0; + + for (uint x = 1;;) { + sum += x; + x++; + + if (x >= 10) { + break; + } + } + + return sum; + } +} diff --git a/test/succ.spec.ts b/test/succ.spec.ts new file mode 100644 index 0000000..87eb590 --- /dev/null +++ b/test/succ.spec.ts @@ -0,0 +1,313 @@ +import expect from "expect"; +import fse from "fs-extra"; +import path, { join } from "path"; +import * as sol from "solc-typed-ast"; +import { SouffleCSVInstance, analyze } from "../src"; +import { searchRecursive } from "../src/lib/utils"; +import { Fact } from "../src/lib/souffle/fact"; + +require("dotenv").config(); + +// These files in solc-typed-ast don't compile on their own. So skip em. +const skipSamples: string[] = [ + "test/samples/solidity/error.sol", + "test/samples/solidity/latest_08.sourced.sol", + "test/samples/solidity/meta/complex_imports/c.sourced.sol", + "test/samples/solidity/meta/imports/lib/B.sol", + "test/samples/solidity/meta/imports/lib2/C.sol", + "test/samples/solidity/meta/imports/lib2/D.sol", + "test/samples/solidity/path_remapping/entry.sol" +]; + +const samples = searchRecursive( + path.join(process.env["SOLC_TYPED_AST_DIR"] as string, "../test/samples/solidity"), + (fileName) => + fileName.endsWith(".sol") && + !fileName.endsWith(".sourced.sol") && + !sol.forAny(skipSamples, (x) => fileName.endsWith(x)) +); + +samples.push(...searchRecursive("test/samples", (fileName) => fileName.endsWith(".sol"))); +//samples = ["/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/builtins_0426.sol"]; +/* +samples = samples.slice( + samples.indexOf( + "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/struct_docs_05.sol" + ) +); +*/ +const verbose = false; + +const MY_DIR = __dirname; +const DIST_SO_DIR = join(MY_DIR, "../dist/functors"); + +export type NdGraph = Map>; +export type Reachable = Set; + +// Legitimate reachability exceptions +const exceptions: Array<[string, string, number]> = [ + // do { break; } while (exp) - exp is unreachable + [ + "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/latest_08.sol", + "stmtStructDocs", + 181 + ], + [ + "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/struct_docs_04.sol", + "stmtStructDocs", + 39 + ], + [ + "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/struct_docs_05.sol", + "stmtStructDocs", + 39 + ], + [ + "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/unicode_big.sol", + "stmtStructDocs", + 141 + ] +]; + +function isException(sample: string, fun: sol.FunctionDefinition, element: sol.ASTNode): boolean { + for (const [excFile, excFun, excId] of exceptions) { + if (excFile === sample && excFun === fun.name && excId === element.id) { + return true; + } + } + + return false; +} + +/** + * Hacky helper to check if a (potentially compound) statement doesnt fall through + */ +function isFallThrough(s: sol.Statement | sol.Block | sol.UncheckedBlock): boolean { + if (s instanceof sol.Statement) { + if ( + s instanceof sol.Return || + s instanceof sol.RevertStatement || + s instanceof sol.Throw || + s instanceof sol.Break || + s instanceof sol.Continue + ) { + return false; + } + + if (s instanceof sol.IfStatement) { + if ( + !isFallThrough(s.vTrueBody) && + s.vFalseBody !== undefined && + !isFallThrough(s.vFalseBody) + ) { + return false; + } + } + + if (s instanceof sol.TryCatchClause && !isFallThrough(s.vBlock)) { + return false; + } + } else { + for (const child of s.vStatements) { + if (!isFallThrough(child)) { + return false; + } + } + } + + return true; +} + +function binIdRelnToGraph(facts: Fact[]): NdGraph { + const res = new Map(); + for (const f of facts) { + const [prev, next] = f.fields as [number, number]; + + if (!res.has(prev)) { + res.set(prev, new Set()); + } + + (res.get(prev) as Set).add(next); + } + + return res; +} + +function getReachability(g: NdGraph, start: number): Reachable { + const res: Reachable = new Set(); + const q: number[] = [start]; + + while (q.length > 0) { + const cur = q.pop() as number; + + if (res.has(cur)) { + continue; + } + + res.add(cur); + + let neighbors = g.get(cur); + neighbors = neighbors === undefined ? new Set() : neighbors; + + q.push(...neighbors); + } + + return res; +} + +export function dumpFacts(fs: Fact[]): void { + for (const f of fs) { + console.error(f.toJSON()); + } +} + +describe("Test succ relation for all samples", () => { + for (const sample of samples) { + describe(sample, () => { + let units: sol.SourceUnit[]; + let infer: sol.InferType; + let contents: string; + let succ: Fact[]; + let succFirst: NdGraph; + let g: NdGraph; + + before(async () => { + contents = fse.readFileSync(sample, { encoding: "utf-8" }); + const result = await sol.compileSol(sample, "auto"); + + const data = result.data; + const errors = sol.detectCompileErrors(data); + + expect(errors).toHaveLength(0); + + const reader = new sol.ASTReader(); + + units = reader.read(data); + + expect(units.length).toBeGreaterThanOrEqual(1); + + infer = new sol.InferType(result.compilerVersion as string); + + const instance = (await analyze( + units, + infer, + "csv", + ["succ", "succ_first"], + DIST_SO_DIR + )) as SouffleCSVInstance; + const analysisResults = instance.results(); + //instance.release(); + succ = analysisResults.get("succ") as Fact[]; + succFirst = binIdRelnToGraph(analysisResults.get("succ_first") as Fact[]); + g = binIdRelnToGraph(succ); + + if (verbose) { + const ctx = reader.context; + + console.error(`Succ: `); + for (const f of succ) { + const [prev, next] = f.fields as [number, number]; + + const prevNd = ctx.locate(prev) as sol.ASTNode; + const nextNd = ctx.locate(next) as sol.ASTNode; + + const prevStr = prevNd.extractSourceFragment(contents); + const nextStr = nextNd.extractSourceFragment(contents); + + console.error( + `${prevNd.id} -> ${nextNd.id} (prev: |${prevStr}| next: ${nextStr})` + ); + } + } + }); + + it("Every expression/statement inside a function body is reachable", async () => { + for (const unit of units) { + for (const fun of unit.getChildrenByType(sol.FunctionDefinition)) { + if (fun.vBody === undefined) { + continue; + } + + const firstIdSet = succFirst.get(fun.vBody.id); + + if (verbose && (firstIdSet === undefined || firstIdSet.size !== 1)) { + console.error( + `Couldnt find single entry for ${fun.name} body #${ + fun.vBody.id + }: ${sol.pp(firstIdSet)}` + ); + } + expect(firstIdSet !== undefined && firstIdSet.size === 1).toBeTruthy(); + + const firstId = [...(firstIdSet as Set)][0]; + const reachable = getReachability(g, firstId); + + for (const element of fun.vBody.getChildren(true)) { + // Only consider statements, blocks and expressions + if ( + !( + element instanceof sol.Expression || + element instanceof sol.Statement || + element instanceof sol.StatementWithChildren + ) + ) { + continue; + } + + // Ignore literals inside array typenames (e.g. uint[4]). + if (element.getClosestParentByType(sol.ArrayTypeName) !== undefined) { + continue; + } + + // Note sometimes array typenames for user-defined + // types appear as IndexExpressions + if (element.getClosestParentByType(sol.IndexAccess) !== undefined) { + const t = element.getClosestParentByType( + sol.IndexAccess + ) as sol.IndexAccess; + + if (t.typeString.startsWith("type(")) continue; + } + + // Skip blocks ending in a non-fallthrough statements -they are not reachable from the entry of the function + if ( + (element instanceof sol.Block || + element instanceof sol.UncheckedBlock || + element instanceof sol.TryCatchClause) && + !isFallThrough(element) + ) { + continue; + } + + // Skip empty blocks (they are not part of the succ relation) + if ( + (element instanceof sol.Block || + element instanceof sol.UncheckedBlock) && + element.vStatements.length === 0 + ) { + continue; + } + + // This is a legit exception + if (isException(sample, fun, element)) { + continue; + } + + if (verbose && !reachable.has(element.id)) { + console.error( + `Node ${element.extractSourceFragment(contents)} (${ + element.constructor.name + }#${element.id}) not reachable from body (#${firstId}) of ${ + fun.name + }` + ); + } + + expect(reachable.has(element.id)).toBeTruthy(); + } + } + } + }); + }); + } +}); From 0707beb35b6d4bc46150c9ab85bff52586c9d32e Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Tue, 23 Jan 2024 20:28:26 +0200 Subject: [PATCH 02/10] Remove the firstStmt,nextStmt,lastStmt relations; Simplify succ a little; Add test that only non-fallthrough nodes dont have successors --- scripts/gen_translation_modules.js | 3 - src/lib/analyses/cfg/succ.dl | 49 +++++++-------- src/lib/translate.ts | 45 -------------- test/succ.spec.ts | 99 +++++++++++++++++++++++------- 4 files changed, 101 insertions(+), 95 deletions(-) diff --git a/scripts/gen_translation_modules.js b/scripts/gen_translation_modules.js index 6c3f324..507c9bf 100644 --- a/scripts/gen_translation_modules.js +++ b/scripts/gen_translation_modules.js @@ -106,9 +106,6 @@ const staticPreamble = ` .decl ExternalCall(id: FunctionCallId) .decl ConstantExpression(id: id) .decl CompilerVersion(major: number, minor: number, patch: number) -.decl nextStmt(prev: StatementId, next: StatementId) -.decl firstStmt(block: id, next: StatementId) -.decl lastStmt(block: id, next: StatementId) .decl Expression(id: id) .decl Statement(id: id) .decl StatementWithChildren(id: id) diff --git a/src/lib/analyses/cfg/succ.dl b/src/lib/analyses/cfg/succ.dl index 4e7f997..03c5a6a 100644 --- a/src/lib/analyses/cfg/succ.dl +++ b/src/lib/analyses/cfg/succ.dl @@ -218,7 +218,7 @@ TupleExpression(teId), !TupleExpression_components(teId, _, _, _). -// Statements succ + // Statements succ // ---------- HELPERS ------------- // True if nd is a checked or unchecked block .decl isBlock(nd: id) @@ -229,24 +229,8 @@ // Non-block fall-through statements fallThrough(id) :- Statement(id), - !isBlock(id), !(Return(id) ; Break(id) ; Continue(id); RevertStatement(id); Throw(id)). - // Empty blocks are fall-through - fallThrough(id) :- - isBlock(id), - !lastStmt(id, _). - - // Blocks whose last statement is fall-through are also fall-through - fallThrough(id) :- - isBlock(id), - lastStmt(id, lastStmt), - fallThrough(lastStmt). - - // True if nd is not a "fall-through" statement (i.e. if control-flow does not continue to the next statement). - .decl noFallThrough(nd: id) - noFallThrough(nd) :- Statement(nd), !fallThrough(nd). - // True if nd is a loop statement. .decl isLoop(node: id) isLoop(id) :- (ForStatement(id) ; WhileStatement(id) ; DoWhileStatement(id)). @@ -264,25 +248,35 @@ // ---- Block or UncheckedBlock // For non-empty blocks the first thing in the first statement is first succ_first(bId, first) :- - firstStmt(bId, firstStmtId), // this ensures bId is a block + (Block_statements(bId, firstStmtId, 0) ; UncheckedBlock_statements(bId, firstStmtId, 0)), succ_first(firstStmtId, first). // For empty blocks we consider them immediately executed succ_first(bId, bId) :- - isBlock(bId), - !firstStmt(bId, _). + ((Block(bId), !Block_statements(bId, _, _)) ; (UncheckedBlock(bId), !UncheckedBlock_statements(bId, _, _))). // Control flow goes from one statement to the next in a block, if the prev - // is not a terminator + // is fall-through + succ(prev, next) :- + Block(bId), Block_statements(bId, prev, i), Block_statements(bId, nextStmt, i+1), + fallThrough(prev), + succ_first(nextStmt, next). + succ(prev, next) :- + UncheckedBlock(bId), UncheckedBlock_statements(bId, prev, i), UncheckedBlock_statements(bId, nextStmt, i+1), fallThrough(prev), - nextStmt(prev, nextStmt), succ_first(nextStmt, next). // The block is considered executed, after the last statement executes, if - // the last statement is not a terminator + // the last statement is fall-through succ(prev, next) :- - lastStmt(next, prev), + Block_statements(next, prev, i), + (!Block_statements(next, _, i+1)), + fallThrough(prev). + + succ(prev, next) :- + UncheckedBlock_statements(next, prev, i), + (!UncheckedBlock_statements(next, _, i+1)), fallThrough(prev). // ---- ExpressionStatement @@ -478,6 +472,13 @@ ForStatement_condition(fsId, condId, 1), succ_first(condId, next). + // After the loop expression we execute the body (if there is no condition) + succ(prev, next) :- + ForStatement_loopExpression(fsId, prev, 1), + ForStatement_condition(fsId, _, 0), + ForStatement_body(fsId, body), + succ_first(body, next). + // After the condition we may exit the loop succ(prev, next) :- ForStatement_condition(next, prev, 1). diff --git a/src/lib/translate.ts b/src/lib/translate.ts index ed040d9..7056b6e 100644 --- a/src/lib/translate.ts +++ b/src/lib/translate.ts @@ -37,55 +37,10 @@ function translateNode(nd: sol.ASTNode, infer: sol.InferType): string[] { return res; } -/** - * Walk a block, skipping any nested/empty blocks and return a list of the - * top-level statements in the block in order. So for example for: - * ``` - * {{}} - * i=0; - * unchecked {{ i++; {} }} - * i--; - * {} - * ``` - * - * This function will return [`i=0`, `i++`, `i--`] - */ -function linearizeStmts(nd: sol.Block | sol.UncheckedBlock): sol.Statement[] { - const res: sol.Statement[] = []; - - for (const stmt of nd.vStatements) { - if (stmt instanceof sol.Block || stmt instanceof sol.UncheckedBlock) { - res.push(...linearizeStmts(stmt)); - } else if (stmt instanceof sol.Statement) { - res.push(stmt); - } - } - - return res; -} - function translateUnit(unit: sol.SourceUnit, infer: sol.InferType): string[] { const res: string[] = []; unit.walk((nd) => res.push(...translateNode(nd, infer))); - // Add firstStmt and nextStmt - unit.walk((nd) => { - if (!(nd instanceof sol.Block || nd instanceof sol.UncheckedBlock)) { - return; - } - - const stmts = linearizeStmts(nd); - - if (stmts.length > 0) { - res.push(`firstStmt(${nd.id}, ${stmts[0].id}).`); - res.push(`lastStmt(${nd.id}, ${stmts[stmts.length - 1].id}).`); - } - - for (let i = 0; i < stmts.length - 1; i++) { - res.push(`nextStmt(${stmts[i].id}, ${stmts[i + 1].id}).`); - } - }); - return res; } diff --git a/test/succ.spec.ts b/test/succ.spec.ts index 87eb590..73e022f 100644 --- a/test/succ.spec.ts +++ b/test/succ.spec.ts @@ -32,7 +32,7 @@ samples.push(...searchRecursive("test/samples", (fileName) => fileName.endsWith( /* samples = samples.slice( samples.indexOf( - "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/struct_docs_05.sol" + "/home/dimo/work/consensys/solc-typed-ast/test/samples/solidity/statements/for_0413.sol" ) ); */ @@ -161,6 +161,25 @@ export function dumpFacts(fs: Fact[]): void { } } +function isInsideArrayTypename(element: sol.ASTNode): boolean { + // Ignore literals inside array typenames (e.g. uint[4]). + if (element.getClosestParentByType(sol.ArrayTypeName) !== undefined) { + return true; + } + + // Note sometimes array typenames for user-defined + // types appear as IndexExpressions + if (element.getClosestParentByType(sol.IndexAccess) !== undefined) { + const t = element.getClosestParentByType(sol.IndexAccess) as sol.IndexAccess; + + if (t.typeString.startsWith("type(")) { + return true; + } + } + + return false; +} + describe("Test succ relation for all samples", () => { for (const sample of samples) { describe(sample, () => { @@ -221,7 +240,7 @@ describe("Test succ relation for all samples", () => { } }); - it("Every expression/statement inside a function body is reachable", async () => { + it("Every expression/statement inside a function body is reachable", () => { for (const unit of units) { for (const fun of unit.getChildrenByType(sol.FunctionDefinition)) { if (fun.vBody === undefined) { @@ -254,21 +273,10 @@ describe("Test succ relation for all samples", () => { continue; } - // Ignore literals inside array typenames (e.g. uint[4]). - if (element.getClosestParentByType(sol.ArrayTypeName) !== undefined) { + if (isInsideArrayTypename(element)) { continue; } - // Note sometimes array typenames for user-defined - // types appear as IndexExpressions - if (element.getClosestParentByType(sol.IndexAccess) !== undefined) { - const t = element.getClosestParentByType( - sol.IndexAccess - ) as sol.IndexAccess; - - if (t.typeString.startsWith("type(")) continue; - } - // Skip blocks ending in a non-fallthrough statements -they are not reachable from the entry of the function if ( (element instanceof sol.Block || @@ -279,15 +287,6 @@ describe("Test succ relation for all samples", () => { continue; } - // Skip empty blocks (they are not part of the succ relation) - if ( - (element instanceof sol.Block || - element instanceof sol.UncheckedBlock) && - element.vStatements.length === 0 - ) { - continue; - } - // This is a legit exception if (isException(sample, fun, element)) { continue; @@ -308,6 +307,60 @@ describe("Test succ relation for all samples", () => { } } }); + + it("The only nodes without a succ are terminator nodes and the function body", () => { + for (const unit of units) { + for (const fun of unit.getChildrenByType(sol.FunctionDefinition)) { + if (fun.vBody === undefined) { + continue; + } + + for (const element of fun.vBody.getChildren()) { + if ( + !( + element instanceof sol.Expression || + element instanceof sol.Statement || + element instanceof sol.StatementWithChildren + ) + ) { + continue; + } + + if (isInsideArrayTypename(element)) { + continue; + } + + const succs = g.get(element.id); + + if (succs === undefined || succs.size === 0) { + if ( + verbose && + !( + element === fun.vBody || + element instanceof sol.Return || + element instanceof sol.Throw || + element instanceof sol.RevertStatement + ) + ) { + console.error( + `Unexpected element ${sol.pp( + element + )} (|${element.extractSourceFragment( + contents + )}|)without succ in ${fun.name}` + ); + } + expect( + element === fun.vBody || + element instanceof sol.Return || + element instanceof sol.Throw || + element instanceof sol.RevertStatement + ).toBeTruthy(); + } + } + } + } + }); }); } }); From 20b7194d493bb1d4797f1facc37763a55a3d5f09 Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Tue, 23 Jan 2024 21:04:00 +0200 Subject: [PATCH 03/10] nit --- src/lib/analyses/cfg/succ.dl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/analyses/cfg/succ.dl b/src/lib/analyses/cfg/succ.dl index 03c5a6a..a8c0de8 100644 --- a/src/lib/analyses/cfg/succ.dl +++ b/src/lib/analyses/cfg/succ.dl @@ -1,5 +1,5 @@ - .decl succ(prev: id, next: id) overridable - .decl succ_first(cId: id, fId: id) overridable + .decl succ(prev: id, next: id) + .decl succ_first(cId: id, fId: id) /// EXPRESSIONS @@ -556,4 +556,4 @@ succ_first(evCall, first). succ(prev, next) :- - EmitStatement_eventCall(next, prev). + EmitStatement_eventCall(next, prev). \ No newline at end of file From a5c8f4f118b5f0012fd74f9fa3de0686bb7a29f9 Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Fri, 1 Mar 2024 06:53:29 +0200 Subject: [PATCH 04/10] Added a Souffle AST; Added an adaptation of Souffles Bison parser --- src/lib/souffle/ast/declarations/adt.ts | 28 + .../souffle/ast/declarations/alias_type.ts | 25 + src/lib/souffle/ast/declarations/component.ts | 35 + .../ast/declarations/component_init.ts | 25 + .../souffle/ast/declarations/declaration.ts | 6 + src/lib/souffle/ast/declarations/directive.ts | 28 + src/lib/souffle/ast/declarations/fact.ts | 24 + src/lib/souffle/ast/declarations/functor.ts | 29 + src/lib/souffle/ast/declarations/index.ts | 16 + src/lib/souffle/ast/declarations/override.ts | 23 + src/lib/souffle/ast/declarations/pragma.ts | 24 + .../souffle/ast/declarations/record_type.ts | 27 + src/lib/souffle/ast/declarations/relation.ts | 55 + src/lib/souffle/ast/declarations/rule.ts | 37 + .../souffle/ast/declarations/subset_type.ts | 25 + .../souffle/ast/declarations/subsumption.ts | 38 + .../souffle/ast/declarations/union_type.ts | 25 + .../souffle/ast/expressions/adt_literal.ts | 24 + src/lib/souffle/ast/expressions/autoinc.ts | 20 + src/lib/souffle/ast/expressions/binary.ts | 27 + src/lib/souffle/ast/expressions/expression.ts | 3 + src/lib/souffle/ast/expressions/float.ts | 23 + .../souffle/ast/expressions/functor_call.ts | 25 + src/lib/souffle/ast/expressions/identifier.ts | 23 + src/lib/souffle/ast/expressions/index.ts | 15 + src/lib/souffle/ast/expressions/nil.ts | 20 + src/lib/souffle/ast/expressions/number.ts | 23 + .../souffle/ast/expressions/record_literal.ts | 23 + .../souffle/ast/expressions/string_literal.ts | 23 + src/lib/souffle/ast/expressions/type_cast.ts | 25 + src/lib/souffle/ast/expressions/unary.ts | 26 + .../souffle/ast/expressions/unnamed_var.ts | 20 + src/lib/souffle/ast/expressions/unsigned.ts | 23 + src/lib/souffle/ast/index.ts | 5 + src/lib/souffle/ast/node.ts | 19 + src/lib/souffle/ast/rules/atom.ts | 24 + .../ast/rules/constraints/bool_literal.ts | 23 + .../ast/rules/constraints/comparison.ts | 28 + .../ast/rules/constraints/constraint.ts | 3 + .../souffle/ast/rules/constraints/index.ts | 4 + .../rules/constraints/string_constraints.ts | 26 + src/lib/souffle/ast/rules/index.ts | 3 + .../souffle/ast/rules/logical/conjunction.ts | 23 + .../souffle/ast/rules/logical/disjunction.ts | 24 + src/lib/souffle/ast/rules/logical/index.ts | 12 + src/lib/souffle/ast/rules/logical/negation.ts | 23 + src/lib/souffle/ast/types/index.ts | 2 + src/lib/souffle/ast/types/named_type.ts | 23 + src/lib/souffle/ast/types/type.ts | 3 + src/lib/souffle/parser/index.ts | 1 + src/lib/souffle/parser/souffle.jison | 1569 +++++++++++++++++ src/lib/utils/eq.ts | 144 ++ src/lib/utils/index.ts | 3 + src/lib/utils/misc.ts | 122 ++ src/lib/utils/pp.ts | 103 ++ 55 files changed, 3000 insertions(+) create mode 100644 src/lib/souffle/ast/declarations/adt.ts create mode 100644 src/lib/souffle/ast/declarations/alias_type.ts create mode 100644 src/lib/souffle/ast/declarations/component.ts create mode 100644 src/lib/souffle/ast/declarations/component_init.ts create mode 100644 src/lib/souffle/ast/declarations/declaration.ts create mode 100644 src/lib/souffle/ast/declarations/directive.ts create mode 100644 src/lib/souffle/ast/declarations/fact.ts create mode 100644 src/lib/souffle/ast/declarations/functor.ts create mode 100644 src/lib/souffle/ast/declarations/index.ts create mode 100644 src/lib/souffle/ast/declarations/override.ts create mode 100644 src/lib/souffle/ast/declarations/pragma.ts create mode 100644 src/lib/souffle/ast/declarations/record_type.ts create mode 100644 src/lib/souffle/ast/declarations/relation.ts create mode 100644 src/lib/souffle/ast/declarations/rule.ts create mode 100644 src/lib/souffle/ast/declarations/subset_type.ts create mode 100644 src/lib/souffle/ast/declarations/subsumption.ts create mode 100644 src/lib/souffle/ast/declarations/union_type.ts create mode 100644 src/lib/souffle/ast/expressions/adt_literal.ts create mode 100644 src/lib/souffle/ast/expressions/autoinc.ts create mode 100644 src/lib/souffle/ast/expressions/binary.ts create mode 100644 src/lib/souffle/ast/expressions/expression.ts create mode 100644 src/lib/souffle/ast/expressions/float.ts create mode 100644 src/lib/souffle/ast/expressions/functor_call.ts create mode 100644 src/lib/souffle/ast/expressions/identifier.ts create mode 100644 src/lib/souffle/ast/expressions/index.ts create mode 100644 src/lib/souffle/ast/expressions/nil.ts create mode 100644 src/lib/souffle/ast/expressions/number.ts create mode 100644 src/lib/souffle/ast/expressions/record_literal.ts create mode 100644 src/lib/souffle/ast/expressions/string_literal.ts create mode 100644 src/lib/souffle/ast/expressions/type_cast.ts create mode 100644 src/lib/souffle/ast/expressions/unary.ts create mode 100644 src/lib/souffle/ast/expressions/unnamed_var.ts create mode 100644 src/lib/souffle/ast/expressions/unsigned.ts create mode 100644 src/lib/souffle/ast/index.ts create mode 100644 src/lib/souffle/ast/node.ts create mode 100644 src/lib/souffle/ast/rules/atom.ts create mode 100644 src/lib/souffle/ast/rules/constraints/bool_literal.ts create mode 100644 src/lib/souffle/ast/rules/constraints/comparison.ts create mode 100644 src/lib/souffle/ast/rules/constraints/constraint.ts create mode 100644 src/lib/souffle/ast/rules/constraints/index.ts create mode 100644 src/lib/souffle/ast/rules/constraints/string_constraints.ts create mode 100644 src/lib/souffle/ast/rules/index.ts create mode 100644 src/lib/souffle/ast/rules/logical/conjunction.ts create mode 100644 src/lib/souffle/ast/rules/logical/disjunction.ts create mode 100644 src/lib/souffle/ast/rules/logical/index.ts create mode 100644 src/lib/souffle/ast/rules/logical/negation.ts create mode 100644 src/lib/souffle/ast/types/index.ts create mode 100644 src/lib/souffle/ast/types/named_type.ts create mode 100644 src/lib/souffle/ast/types/type.ts create mode 100644 src/lib/souffle/parser/index.ts create mode 100644 src/lib/souffle/parser/souffle.jison create mode 100644 src/lib/utils/eq.ts create mode 100644 src/lib/utils/index.ts create mode 100644 src/lib/utils/misc.ts create mode 100644 src/lib/utils/pp.ts diff --git a/src/lib/souffle/ast/declarations/adt.ts b/src/lib/souffle/ast/declarations/adt.ts new file mode 100644 index 0000000..92b00e3 --- /dev/null +++ b/src/lib/souffle/ast/declarations/adt.ts @@ -0,0 +1,28 @@ +import { flatten } from "../../../utils"; +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export class AlgebraicDataType extends Declaration { + constructor( + public readonly name: string, + public readonly branches: Array<[string, Array<[string, Type]>]>, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.type ${this.name} = [${this.branches + .map((b) => `${b[0]} {${b[1].map((f) => `${f[0]}: ${f[1].pp()}`).join(", ")}}`) + .join(" | ")}]`; + } + + children(): Iterable { + return flatten(this.branches.map((b) => b[1].map((a) => a[1]))); + } + + getStructId(): any { + return [this.name, this.branches]; + } +} diff --git a/src/lib/souffle/ast/declarations/alias_type.ts b/src/lib/souffle/ast/declarations/alias_type.ts new file mode 100644 index 0000000..c6e41f4 --- /dev/null +++ b/src/lib/souffle/ast/declarations/alias_type.ts @@ -0,0 +1,25 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export class AliasType extends Declaration { + constructor( + public readonly name: string, + public readonly originalType: Type, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.type ${this.name} = ${this.originalType.pp()}`; + } + + children(): Iterable { + return [this.originalType]; + } + + getStructId(): any { + return [this.name, this.originalType]; + } +} diff --git a/src/lib/souffle/ast/declarations/component.ts b/src/lib/souffle/ast/declarations/component.ts new file mode 100644 index 0000000..ea6dee3 --- /dev/null +++ b/src/lib/souffle/ast/declarations/component.ts @@ -0,0 +1,35 @@ +import { Node, Src } from "../node"; +import { Declaration } from "./declaration"; + +export type ComponentBaseInvocation = [string, string[]]; +export class Component extends Declaration { + constructor( + public readonly name: string, + public readonly typeParams: string[], + public readonly bases: ComponentBaseInvocation[], + public readonly body: Declaration[], + src: Src + ) { + super(src); + } + + static ppCompInv(inv: ComponentBaseInvocation): string { + return `${inv[0]}${inv[1].length > 0 ? `<${inv[1].join(", ")}>` : ""}`; + } + + pp(indent: string = ""): string { + return `${indent}.comp ${Component.ppCompInv([this.name, this.typeParams])}${ + this.bases.length ? 0 : this.bases.map(Component.ppCompInv).join(", ") + } { + ${this.body.map((x) => x.pp(indent + " ")).join("\n")} + }`; + } + + children(): Iterable { + return this.body; + } + + getStructId(): any { + return [this.name, ...this.typeParams, ...this.bases, ...this.body]; + } +} diff --git a/src/lib/souffle/ast/declarations/component_init.ts b/src/lib/souffle/ast/declarations/component_init.ts new file mode 100644 index 0000000..71b9920 --- /dev/null +++ b/src/lib/souffle/ast/declarations/component_init.ts @@ -0,0 +1,25 @@ +import { Node, Src } from "../node"; +import { Component, ComponentBaseInvocation } from "./component"; +import { Declaration } from "./declaration"; + +export class ComponentInit extends Declaration { + constructor( + public readonly name: string, + public readonly inv: ComponentBaseInvocation, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.init ${this.name} = ${Component.ppCompInv(this.inv)}`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.name, this.inv[0], ...this.inv[1]]; + } +} diff --git a/src/lib/souffle/ast/declarations/declaration.ts b/src/lib/souffle/ast/declarations/declaration.ts new file mode 100644 index 0000000..091d893 --- /dev/null +++ b/src/lib/souffle/ast/declarations/declaration.ts @@ -0,0 +1,6 @@ +import { Node } from "../node"; + +export type Program = Declaration[]; + +// Abstrat base for all top-level declrations +export abstract class Declaration extends Node {} diff --git a/src/lib/souffle/ast/declarations/directive.ts b/src/lib/souffle/ast/declarations/directive.ts new file mode 100644 index 0000000..65c90ca --- /dev/null +++ b/src/lib/souffle/ast/declarations/directive.ts @@ -0,0 +1,28 @@ +import { Node, Src } from "../node"; +import { Declaration } from "./declaration"; + +export type DirectiveValue = string | boolean | number; +export class Directive extends Declaration { + constructor( + public readonly type: string, + public readonly name: string, + public readonly parameters: Array<[string, DirectiveValue]>, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}${this.type} ${this.name}(${this.parameters + .map(([name, val]) => `${name} = ${val}`) + .join(", ")})`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.type, this.name, ...this.parameters]; + } +} diff --git a/src/lib/souffle/ast/declarations/fact.ts b/src/lib/souffle/ast/declarations/fact.ts new file mode 100644 index 0000000..89004c0 --- /dev/null +++ b/src/lib/souffle/ast/declarations/fact.ts @@ -0,0 +1,24 @@ +import { Node, Src } from "../node"; +import { Atom } from "../rules"; +import { Declaration } from "./declaration"; + +export class Fact extends Declaration { + constructor( + public readonly atom: Atom, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}${this.atom.pp()}.`; + } + + children(): Iterable { + return [this.atom]; + } + + getStructId(): any { + return this.atom.getStructId(); + } +} diff --git a/src/lib/souffle/ast/declarations/functor.ts b/src/lib/souffle/ast/declarations/functor.ts new file mode 100644 index 0000000..cd89048 --- /dev/null +++ b/src/lib/souffle/ast/declarations/functor.ts @@ -0,0 +1,29 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export class Functor extends Declaration { + constructor( + public readonly name: string, + public readonly args: Array<[string, Type]>, + public readonly returnType: Type, + public readonly stateful: boolean, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.functor ${this.name}(${this.args + .map(([name, typ]) => `${name}: ${typ.pp()}`) + .join(", ")}): ${this.returnType.pp()}${this.stateful ? " stateful" : ""}`; + } + + children(): Iterable { + return [...this.args.map((x) => x[1]), this.returnType]; + } + + getStructId(): any { + return [this.name, ...this.args, this.returnType, this.stateful]; + } +} diff --git a/src/lib/souffle/ast/declarations/index.ts b/src/lib/souffle/ast/declarations/index.ts new file mode 100644 index 0000000..e90fe79 --- /dev/null +++ b/src/lib/souffle/ast/declarations/index.ts @@ -0,0 +1,16 @@ +export * from "./adt"; +export * from "./alias_type"; +export * from "./component_init"; +export * from "./component"; +export * from "./declaration"; +export * from "./directive"; +export * from "./fact"; +export * from "./functor"; +export * from "./override"; +export * from "./pragma"; +export * from "./record_type"; +export * from "./relation"; +export * from "./rule"; +export * from "./subset_type"; +export * from "./subsumption"; +export * from "./union_type"; diff --git a/src/lib/souffle/ast/declarations/override.ts b/src/lib/souffle/ast/declarations/override.ts new file mode 100644 index 0000000..86083a3 --- /dev/null +++ b/src/lib/souffle/ast/declarations/override.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Declaration } from "./declaration"; + +export class Override extends Declaration { + constructor( + public readonly relation: string, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.override ${this.relation}`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.relation]; + } +} diff --git a/src/lib/souffle/ast/declarations/pragma.ts b/src/lib/souffle/ast/declarations/pragma.ts new file mode 100644 index 0000000..7887ae5 --- /dev/null +++ b/src/lib/souffle/ast/declarations/pragma.ts @@ -0,0 +1,24 @@ +import { Node, Src } from "../node"; +import { Declaration } from "./declaration"; + +export class Pragma extends Declaration { + constructor( + public readonly name: string, + public readonly value: string | undefined, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.pragma ${this.name}${this.value ? " " + this.value : ""}`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.name, this.value]; + } +} diff --git a/src/lib/souffle/ast/declarations/record_type.ts b/src/lib/souffle/ast/declarations/record_type.ts new file mode 100644 index 0000000..d4b41a3 --- /dev/null +++ b/src/lib/souffle/ast/declarations/record_type.ts @@ -0,0 +1,27 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export class RecordType extends Declaration { + constructor( + public readonly name: string, + public readonly fields: Array<[string, Type]>, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.type ${this.name} = [${this.fields + .map((f) => `${f[0]}: ${f[1].pp()}`) + .join(", ")}]`; + } + + children(): Iterable { + return this.fields.map((x) => x[1]); + } + + getStructId(): any { + return [this.name, ...this.fields]; + } +} diff --git a/src/lib/souffle/ast/declarations/relation.ts b/src/lib/souffle/ast/declarations/relation.ts new file mode 100644 index 0000000..93c05b4 --- /dev/null +++ b/src/lib/souffle/ast/declarations/relation.ts @@ -0,0 +1,55 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export enum RelationTags { + Overridable = "overridable", + Inline = "inline", + NoInline = "no_inline", + Magic = "magic", + NoMagic = "no_magic", + Brie = "brie", + BTree = "btree", + BTreeDelete = "btree_delete", + EQRel = "eqrel" +} + +export type RelationChoiceDomain = string | string[]; + +export class Relation extends Declaration { + constructor( + public readonly name: string, + public readonly args: Array<[string, Type]>, + public readonly tags: Set, + public readonly choiceDomains: RelationChoiceDomain[], + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + const choiceStrs = []; + + for (const x of this.choiceDomains) { + if (typeof x === "string") { + choiceStrs.push(x); + } else { + choiceStrs.push(`(${x.join(", ")})`); + } + } + + return `${indent}.decl ${this.name}(${this.args + .map((a) => `${a[0]}: ${a[1].pp()}`) + .join(", ")}) ${[...this.tags].join(" ")}${ + choiceStrs.length > 0 ? `choice-domain ${choiceStrs.join(", ")}` : "" + }`; + } + + children(): Iterable { + return [...this.args.map((x) => x[1])]; + } + + getStructId(): any { + return [this.name, ...this.args, [...this.tags], this.choiceDomains]; + } +} diff --git a/src/lib/souffle/ast/declarations/rule.ts b/src/lib/souffle/ast/declarations/rule.ts new file mode 100644 index 0000000..9896c0b --- /dev/null +++ b/src/lib/souffle/ast/declarations/rule.ts @@ -0,0 +1,37 @@ +import { Node, Src } from "../node"; +import { Atom } from "../rules/atom"; +import { Disjunction } from "../rules/logical"; +import { Declaration } from "./declaration"; + +export type QueryPlan = Array<[number, number[]]>; + +export class Rule extends Declaration { + constructor( + public readonly head: Atom, + public readonly body: Disjunction, + public queryPlan: QueryPlan, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + let queryPlanStr = ""; + + if (this.queryPlan.length > 0) { + queryPlanStr += ".plan"; + queryPlanStr += this.queryPlan + .map(([num, nums]) => `${num}: (${nums.map((x) => `${x}`).join(", ")})`) + .join(", "); + } + return `${indent}${this.head.pp()} :- ${this.body.pp()}.${queryPlanStr}`; + } + + children(): Iterable { + return [this.head, this.body]; + } + + getStructId(): any { + return [this.head, this.body, this.queryPlan]; + } +} diff --git a/src/lib/souffle/ast/declarations/subset_type.ts b/src/lib/souffle/ast/declarations/subset_type.ts new file mode 100644 index 0000000..2b9d7cd --- /dev/null +++ b/src/lib/souffle/ast/declarations/subset_type.ts @@ -0,0 +1,25 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export class SubsetType extends Declaration { + constructor( + public readonly name: string, + public readonly originalType: Type, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.type ${this.name} <: ${this.originalType.pp()}`; + } + + children(): Iterable { + return [this.originalType]; + } + + getStructId(): any { + return [this.name, this.originalType]; + } +} diff --git a/src/lib/souffle/ast/declarations/subsumption.ts b/src/lib/souffle/ast/declarations/subsumption.ts new file mode 100644 index 0000000..2a3c43f --- /dev/null +++ b/src/lib/souffle/ast/declarations/subsumption.ts @@ -0,0 +1,38 @@ +import { Node, Src } from "../node"; +import { Atom } from "../rules/atom"; +import { Disjunction } from "../rules/logical"; +import { Declaration } from "./declaration"; +import { QueryPlan } from "./rule"; + +export class Subsumption extends Declaration { + constructor( + public readonly dominatedHead: Atom, + public readonly dominatingHead: Atom, + public readonly body: Disjunction, + public queryPlan: QueryPlan, + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + let queryPlanStr = ""; + + if (this.queryPlan.length > 0) { + queryPlanStr += ".plan"; + queryPlanStr += this.queryPlan + .map(([num, nums]) => `${num}: (${nums.map((x) => `${x}`).join(", ")})`) + .join(", "); + } + + return `${indent}${this.dominatedHead.pp()} <= ${this.dominatingHead.pp()} :- ${this.body.pp()}.${queryPlanStr}`; + } + + children(): Iterable { + return [this.dominatedHead, this.dominatingHead, this.body]; + } + + getStructId(): any { + return [this.dominatedHead, this.dominatingHead, this.body, this.queryPlan]; + } +} diff --git a/src/lib/souffle/ast/declarations/union_type.ts b/src/lib/souffle/ast/declarations/union_type.ts new file mode 100644 index 0000000..e5ad42a --- /dev/null +++ b/src/lib/souffle/ast/declarations/union_type.ts @@ -0,0 +1,25 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Declaration } from "./declaration"; + +export class UnionType extends Declaration { + constructor( + public readonly name: string, + public readonly types: Type[], + src: Src + ) { + super(src); + } + + pp(indent: string = ""): string { + return `${indent}.type ${this.name} = ${this.types.map((x) => x.pp()).join(" | ")}`; + } + + children(): Iterable { + return this.types; + } + + getStructId(): any { + return [this.name, this.types]; + } +} diff --git a/src/lib/souffle/ast/expressions/adt_literal.ts b/src/lib/souffle/ast/expressions/adt_literal.ts new file mode 100644 index 0000000..a82f1ac --- /dev/null +++ b/src/lib/souffle/ast/expressions/adt_literal.ts @@ -0,0 +1,24 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class ADTLiteral extends Expression { + constructor( + public readonly branch: string, + public readonly args: Expression[], + src: Src + ) { + super(src); + } + + pp(): string { + return `$${this.branch}(${this.args.map((a) => a.pp()).join(", ")})`; + } + + children(): Iterable { + return this.args; + } + + getStructId(): any { + return [this.branch, this.args]; + } +} diff --git a/src/lib/souffle/ast/expressions/autoinc.ts b/src/lib/souffle/ast/expressions/autoinc.ts new file mode 100644 index 0000000..f847d06 --- /dev/null +++ b/src/lib/souffle/ast/expressions/autoinc.ts @@ -0,0 +1,20 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class AutoIncrement extends Expression { + constructor(src: Src) { + super(src); + } + + pp(): string { + return "autoinc()"; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return []; + } +} diff --git a/src/lib/souffle/ast/expressions/binary.ts b/src/lib/souffle/ast/expressions/binary.ts new file mode 100644 index 0000000..16ab7cf --- /dev/null +++ b/src/lib/souffle/ast/expressions/binary.ts @@ -0,0 +1,27 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export type BinaryOp = "+"; + +export class BinaryOperator extends Expression { + constructor( + public readonly left: Expression, + public readonly op: BinaryOp, + public readonly right: Expression, + src: Src + ) { + super(src); + } + + pp(): string { + return `(${this.left.pp()} ${this.op} ${this.right.pp()})`; + } + + children(): Iterable { + return [this.left, this.right]; + } + + getStructId(): any { + return [this.left, this.op, this.right]; + } +} diff --git a/src/lib/souffle/ast/expressions/expression.ts b/src/lib/souffle/ast/expressions/expression.ts new file mode 100644 index 0000000..0c137ca --- /dev/null +++ b/src/lib/souffle/ast/expressions/expression.ts @@ -0,0 +1,3 @@ +import { Node } from "../node"; + +export abstract class Expression extends Node {} diff --git a/src/lib/souffle/ast/expressions/float.ts b/src/lib/souffle/ast/expressions/float.ts new file mode 100644 index 0000000..bb8cebc --- /dev/null +++ b/src/lib/souffle/ast/expressions/float.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class Float extends Expression { + constructor( + public readonly value: number, + src: Src + ) { + super(src); + } + + pp(): string { + return Number.isInteger(this.value) ? `${this.value}.0` : `${this.value}`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.value]; + } +} diff --git a/src/lib/souffle/ast/expressions/functor_call.ts b/src/lib/souffle/ast/expressions/functor_call.ts new file mode 100644 index 0000000..bbe2fc4 --- /dev/null +++ b/src/lib/souffle/ast/expressions/functor_call.ts @@ -0,0 +1,25 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class FunctorCall extends Expression { + constructor( + public readonly name: string, + public readonly args: Expression[], + public readonly builtin: boolean, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.name}(${this.args.map((a) => a.pp()).join(", ")})`; + } + + children(): Iterable { + return this.args; + } + + getStructId(): any { + return [this.name, ...this.args, this.builtin]; + } +} diff --git a/src/lib/souffle/ast/expressions/identifier.ts b/src/lib/souffle/ast/expressions/identifier.ts new file mode 100644 index 0000000..8cb0a3b --- /dev/null +++ b/src/lib/souffle/ast/expressions/identifier.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class Identifier extends Expression { + constructor( + public readonly name: string, + src: Src + ) { + super(src); + } + + pp(): string { + return this.name; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.name]; + } +} diff --git a/src/lib/souffle/ast/expressions/index.ts b/src/lib/souffle/ast/expressions/index.ts new file mode 100644 index 0000000..797fdac --- /dev/null +++ b/src/lib/souffle/ast/expressions/index.ts @@ -0,0 +1,15 @@ +export * from "./adt_literal"; +export * from "./autoinc"; +export * from "./binary"; +export * from "./expression"; +export * from "./float"; +export * from "./functor_call"; +export * from "./identifier"; +export * from "./nil"; +export * from "./number"; +export * from "./record_literal"; +export * from "./string_literal"; +export * from "./type_cast"; +export * from "./unary"; +export * from "./unnamed_var"; +export * from "./unsigned"; diff --git a/src/lib/souffle/ast/expressions/nil.ts b/src/lib/souffle/ast/expressions/nil.ts new file mode 100644 index 0000000..f81cded --- /dev/null +++ b/src/lib/souffle/ast/expressions/nil.ts @@ -0,0 +1,20 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class Nil extends Expression { + constructor(src: Src) { + super(src); + } + + pp(): string { + return `nil`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return []; + } +} diff --git a/src/lib/souffle/ast/expressions/number.ts b/src/lib/souffle/ast/expressions/number.ts new file mode 100644 index 0000000..bc500b5 --- /dev/null +++ b/src/lib/souffle/ast/expressions/number.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class Num extends Expression { + constructor( + public readonly value: bigint, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.value}`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.value]; + } +} diff --git a/src/lib/souffle/ast/expressions/record_literal.ts b/src/lib/souffle/ast/expressions/record_literal.ts new file mode 100644 index 0000000..a288df0 --- /dev/null +++ b/src/lib/souffle/ast/expressions/record_literal.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class RecordLiteral extends Expression { + constructor( + public readonly args: Expression[], + src: Src + ) { + super(src); + } + + pp(): string { + return `[${this.args.map((a) => a.pp()).join(", ")}]`; + } + + children(): Iterable { + return this.args; + } + + getStructId(): any { + return this.args; + } +} diff --git a/src/lib/souffle/ast/expressions/string_literal.ts b/src/lib/souffle/ast/expressions/string_literal.ts new file mode 100644 index 0000000..15c39e0 --- /dev/null +++ b/src/lib/souffle/ast/expressions/string_literal.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class StringLiteral extends Expression { + constructor( + public readonly value: string, + src: Src + ) { + super(src); + } + + pp(): string { + return `"${this.value}"`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.value]; + } +} diff --git a/src/lib/souffle/ast/expressions/type_cast.ts b/src/lib/souffle/ast/expressions/type_cast.ts new file mode 100644 index 0000000..1b6f4dd --- /dev/null +++ b/src/lib/souffle/ast/expressions/type_cast.ts @@ -0,0 +1,25 @@ +import { Node, Src } from "../node"; +import { Type } from "../types"; +import { Expression } from "./expression"; + +export class TypeCast extends Expression { + constructor( + public readonly subexpr: Expression, + public readonly type: Type, + src: Src + ) { + super(src); + } + + pp(): string { + return `as(${this.subexpr.pp()}, ${this.type.pp()})`; + } + + children(): Iterable { + return [this.subexpr, this.type]; + } + + getStructId(): any { + return [this.subexpr, this.type]; + } +} diff --git a/src/lib/souffle/ast/expressions/unary.ts b/src/lib/souffle/ast/expressions/unary.ts new file mode 100644 index 0000000..c7bbbff --- /dev/null +++ b/src/lib/souffle/ast/expressions/unary.ts @@ -0,0 +1,26 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export type UnaryOp = "-" | "~" | "!"; + +export class UnaryOperator extends Expression { + constructor( + public readonly op: UnaryOp, + public readonly subExpr: Expression, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.op}(${this.subExpr.pp()})`; + } + + children(): Iterable { + return [this.subExpr]; + } + + getStructId(): any { + return [this.op, this.subExpr]; + } +} diff --git a/src/lib/souffle/ast/expressions/unnamed_var.ts b/src/lib/souffle/ast/expressions/unnamed_var.ts new file mode 100644 index 0000000..28ab1e6 --- /dev/null +++ b/src/lib/souffle/ast/expressions/unnamed_var.ts @@ -0,0 +1,20 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class UnnamedVar extends Expression { + constructor(src: Src) { + super(src); + } + + pp(): string { + return "_"; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return []; + } +} diff --git a/src/lib/souffle/ast/expressions/unsigned.ts b/src/lib/souffle/ast/expressions/unsigned.ts new file mode 100644 index 0000000..093d84f --- /dev/null +++ b/src/lib/souffle/ast/expressions/unsigned.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Expression } from "./expression"; + +export class Unsigned extends Expression { + constructor( + public readonly value: bigint, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.value}u`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.value]; + } +} diff --git a/src/lib/souffle/ast/index.ts b/src/lib/souffle/ast/index.ts new file mode 100644 index 0000000..2980205 --- /dev/null +++ b/src/lib/souffle/ast/index.ts @@ -0,0 +1,5 @@ +export * from "./declarations"; +export * from "./expressions"; +export * from "./rules"; +export * from "./types"; +export * from "./node"; diff --git a/src/lib/souffle/ast/node.ts b/src/lib/souffle/ast/node.ts new file mode 100644 index 0000000..6be7703 --- /dev/null +++ b/src/lib/souffle/ast/node.ts @@ -0,0 +1,19 @@ +import { PPAble, StructEqualityComparable } from "../../utils"; + +let nodeCtr = 0; + +export type Src = any; + +export abstract class Node implements PPAble, StructEqualityComparable { + readonly id: number; + readonly src: Src; + + constructor(src: Src) { + this.id = nodeCtr++; + this.src = src; + } + + abstract pp(indent?: string): string; + abstract getStructId(): any; + abstract children(): Iterable; +} diff --git a/src/lib/souffle/ast/rules/atom.ts b/src/lib/souffle/ast/rules/atom.ts new file mode 100644 index 0000000..4a46e81 --- /dev/null +++ b/src/lib/souffle/ast/rules/atom.ts @@ -0,0 +1,24 @@ +import { Node, Src } from "../node"; +import { Expression } from "../expressions"; + +export class Atom extends Node { + constructor( + public readonly name: string, + public readonly args: Expression[], + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.name}(${this.args.map((x) => x.pp()).join(", ")})`; + } + + children(): Iterable { + return this.args; + } + + getStructId(): any { + return [this.name, ...this.args]; + } +} diff --git a/src/lib/souffle/ast/rules/constraints/bool_literal.ts b/src/lib/souffle/ast/rules/constraints/bool_literal.ts new file mode 100644 index 0000000..221909e --- /dev/null +++ b/src/lib/souffle/ast/rules/constraints/bool_literal.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../../node"; +import { Constraint } from "./constraint"; + +export class BoolLiteral extends Constraint { + constructor( + public readonly value: boolean, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.value}`; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.value]; + } +} diff --git a/src/lib/souffle/ast/rules/constraints/comparison.ts b/src/lib/souffle/ast/rules/constraints/comparison.ts new file mode 100644 index 0000000..6bfc642 --- /dev/null +++ b/src/lib/souffle/ast/rules/constraints/comparison.ts @@ -0,0 +1,28 @@ +import { Expression } from "../../expressions"; +import { Node, Src } from "../../node"; +import { Constraint } from "./constraint"; + +export type ComparisonOp = "<" | ">" | "<=" | ">=" | "=" | "!="; + +export class Comparison extends Constraint { + constructor( + public readonly lhs: Expression, + public readonly op: ComparisonOp, + public readonly rhs: Expression, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.lhs.pp()} ${this.op} ${this.rhs.pp()}`; + } + + children(): Iterable { + return [this.lhs, this.rhs]; + } + + getStructId(): any { + return [this.lhs, this.op, this.rhs]; + } +} diff --git a/src/lib/souffle/ast/rules/constraints/constraint.ts b/src/lib/souffle/ast/rules/constraints/constraint.ts new file mode 100644 index 0000000..4ca27f3 --- /dev/null +++ b/src/lib/souffle/ast/rules/constraints/constraint.ts @@ -0,0 +1,3 @@ +import { Node } from "../../node"; + +export abstract class Constraint extends Node {} diff --git a/src/lib/souffle/ast/rules/constraints/index.ts b/src/lib/souffle/ast/rules/constraints/index.ts new file mode 100644 index 0000000..4700385 --- /dev/null +++ b/src/lib/souffle/ast/rules/constraints/index.ts @@ -0,0 +1,4 @@ +export * from "./bool_literal"; +export * from "./comparison"; +export * from "./constraint"; +export * from "./string_constraints"; diff --git a/src/lib/souffle/ast/rules/constraints/string_constraints.ts b/src/lib/souffle/ast/rules/constraints/string_constraints.ts new file mode 100644 index 0000000..ceabd26 --- /dev/null +++ b/src/lib/souffle/ast/rules/constraints/string_constraints.ts @@ -0,0 +1,26 @@ +import { Expression } from "../../expressions"; +import { Node, Src } from "../../node"; +import { Constraint } from "./constraint"; + +export class StringConstraint extends Constraint { + constructor( + public readonly name: "match" | "contains", + public readonly lhs: Expression, + public readonly rhs: Expression, + src: Src + ) { + super(src); + } + + pp(): string { + return `${this.name}(${this.lhs.pp()}, ${this.rhs.pp()})`; + } + + children(): Iterable { + return [this.lhs, this.rhs]; + } + + getStructId(): any { + return [this.name, this.lhs, this.rhs]; + } +} diff --git a/src/lib/souffle/ast/rules/index.ts b/src/lib/souffle/ast/rules/index.ts new file mode 100644 index 0000000..c95666b --- /dev/null +++ b/src/lib/souffle/ast/rules/index.ts @@ -0,0 +1,3 @@ +export * from "./atom"; +export * from "./constraints"; +export * from "./logical"; diff --git a/src/lib/souffle/ast/rules/logical/conjunction.ts b/src/lib/souffle/ast/rules/logical/conjunction.ts new file mode 100644 index 0000000..05c90f3 --- /dev/null +++ b/src/lib/souffle/ast/rules/logical/conjunction.ts @@ -0,0 +1,23 @@ +import { Logical, Term } from "."; +import { Node, Src } from "../../node"; + +export class Conjunction extends Logical { + constructor( + public readonly conjuncts: Term[], + src: Src + ) { + super(src); + } + + pp(): string { + return this.conjuncts.map((x) => x.pp()).join(", "); + } + + children(): Iterable { + return this.conjuncts; + } + + getStructId(): any { + return this.conjuncts; + } +} diff --git a/src/lib/souffle/ast/rules/logical/disjunction.ts b/src/lib/souffle/ast/rules/logical/disjunction.ts new file mode 100644 index 0000000..6dff754 --- /dev/null +++ b/src/lib/souffle/ast/rules/logical/disjunction.ts @@ -0,0 +1,24 @@ +import { Logical } from "."; +import { Node, Src } from "../../node"; +import { Conjunction } from "./conjunction"; + +export class Disjunction extends Logical { + constructor( + public readonly conjuncts: Conjunction[], + src: Src + ) { + super(src); + } + + pp(): string { + return `(` + this.conjuncts.map((x) => x.pp()).join("; ") + `)`; + } + + children(): Iterable { + return this.conjuncts; + } + + getStructId(): any { + return this.conjuncts; + } +} diff --git a/src/lib/souffle/ast/rules/logical/index.ts b/src/lib/souffle/ast/rules/logical/index.ts new file mode 100644 index 0000000..a994a74 --- /dev/null +++ b/src/lib/souffle/ast/rules/logical/index.ts @@ -0,0 +1,12 @@ +import { Node } from "../../node"; +import { Atom } from "../atom"; +import { Constraint } from "../constraints"; +import { Disjunction } from "./disjunction"; + +export type Term = Atom | Constraint | Disjunction; + +export abstract class Logical extends Node {} + +export * from "./conjunction"; +export * from "./disjunction"; +export * from "./negation"; diff --git a/src/lib/souffle/ast/rules/logical/negation.ts b/src/lib/souffle/ast/rules/logical/negation.ts new file mode 100644 index 0000000..9277b82 --- /dev/null +++ b/src/lib/souffle/ast/rules/logical/negation.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../../node"; +import { Logical, Term } from "."; + +export class Negation extends Logical { + constructor( + public readonly inner: Term, + src: Src + ) { + super(src); + } + + pp(): string { + return `!${this.inner.pp()}`; + } + + children(): Iterable { + return [this.inner]; + } + + getStructId(): any { + return [this.inner]; + } +} diff --git a/src/lib/souffle/ast/types/index.ts b/src/lib/souffle/ast/types/index.ts new file mode 100644 index 0000000..b592379 --- /dev/null +++ b/src/lib/souffle/ast/types/index.ts @@ -0,0 +1,2 @@ +export * from "./type"; +export * from "./named_type"; diff --git a/src/lib/souffle/ast/types/named_type.ts b/src/lib/souffle/ast/types/named_type.ts new file mode 100644 index 0000000..a0967f9 --- /dev/null +++ b/src/lib/souffle/ast/types/named_type.ts @@ -0,0 +1,23 @@ +import { Node, Src } from "../node"; +import { Type } from "./type"; + +export class NamedType extends Type { + constructor( + public readonly name: string, + src: Src + ) { + super(src); + } + + pp(): string { + return this.name; + } + + children(): Iterable { + return []; + } + + getStructId(): any { + return [this.name]; + } +} diff --git a/src/lib/souffle/ast/types/type.ts b/src/lib/souffle/ast/types/type.ts new file mode 100644 index 0000000..043159b --- /dev/null +++ b/src/lib/souffle/ast/types/type.ts @@ -0,0 +1,3 @@ +import { Node } from "../node"; + +export abstract class Type extends Node {} diff --git a/src/lib/souffle/parser/index.ts b/src/lib/souffle/parser/index.ts new file mode 100644 index 0000000..5c58fd8 --- /dev/null +++ b/src/lib/souffle/parser/index.ts @@ -0,0 +1 @@ +export * from "./parser"; diff --git a/src/lib/souffle/parser/souffle.jison b/src/lib/souffle/parser/souffle.jison new file mode 100644 index 0000000..eb101bf --- /dev/null +++ b/src/lib/souffle/parser/souffle.jison @@ -0,0 +1,1569 @@ +%{ +/* tslint:disable */ + +const ast = require("../ast"); + +function lexError(err) { + throw new Error(err); +} + +function lexNYI(token) { + lexError(`Lexer NYI "${token}"`) +} + +function parseError(err) { + throw new Error(err); +} + +function parseNYI(token) { + lexError(`Parser NYI "${token}"`) +} +%} + +%lex +%x INCLUDE_TOK COMMENT_TOK +%% + +// Skip whitespace and comments +"//".*\n {} +"/*" this.begin("COMMENT_TOK"); +"*/" this.begin("INITIAL_TOK"); +[^*\n]+ {} +"*" {} +\n {} +<> lexError('Unterminated comment'); +{WS}+ {} +\"(\\.|[^"\\])*\" this.begin("INITIAL"); +. lexError(`Unexpected ${yytext} in include`); +\s+ {} +".decl" return "DECL_TOK" +".functor" return "FUNCTOR_TOK" +".input" return "INPUT_DECL_TOK" +".output" return "OUTPUT_DECL_TOK" +".printsize" return "PRINTSIZE_DECL_TOK" +".limitsize" return "LIMITSIZE_DECL_TOK" +".type" return "TYPE_TOK" +".comp" return "COMPONENT_TOK" +".init" return "INSTANTIATE_TOK" +".number_type" return "NUMBER_TYPE_TOK" +".symbol_type" return "SYMBOL_TYPE_TOK" +".override" return "OVERRIDE_TOK" +".pragma" return "PRAGMA_TOK" +".plan" return "PLAN_TOK" +".lattice" return "LATTICE_TOK" +".include" yy.LastIncludeDirectiveLoc = yylloc; this.begin("INCLUDE_TOK"); +".once" lexNYI(yytext); +"debug_delta" return "DEBUG_DELTA_TOK" +"autoinc" return "AUTOINC_TOK" +"band" return "BW_AND_TOK" +"bor" return "BW_OR_TOK" +"bxor" return "BW_XOR_TOK" +"bnot" return "BW_NOT_TOK" +"bshl" return "BW_SHIFT_L_TOK" +"bshr" return "BW_SHIFT_R_TOK" +"bshru" return "BW_SHIFT_R_UNSIGNED_TOK" +"lan" return "L_AND_TOK" +"lor" return "L_OR_TOK" +"lxor" return "L_XOR_TOK" +"lnot" return "L_NOT_TOK" +"match" return "TMATCH_TOK" +"mean" return "MEAN_TOK" +"cat" return "CAT_TOK" +"ord" return "ORD_TOK" +"fold" return "FOLD_TOK" +"range" return "RANGE_TOK" +"strlen" return "STRLEN_TOK" +"substr" return "SUBSTR_TOK" +"stateful" return "STATEFUL_TOK" +"contains" return "TCONTAINS_TOK" +"output" return "OUTPUT_QUALIFIER_TOK" +"input" return "INPUT_QUALIFIER_TOK" +"overridable" return "OVERRIDABLE_QUALIFIER_TOK" +"printsize" return "PRINTSIZE_QUALIFIER_TOK" +"eqrel" return "EQREL_QUALIFIER_TOK" +"inline" return "INLINE_QUALIFIER_TOK" +"no_inline" return "NO_INLINE_QUALIFIER_TOK" +"magic" return "MAGIC_QUALIFIER_TOK" +"no_magic" return "NO_MAGIC_QUALIFIER_TOK" +"brie" return "BRIE_QUALIFIER_TOK" +"btree_delete" return "BTREE_DELETE_QUALIFIER_TOK" +"btree" return "BTREE_QUALIFIER_TOK" +"min" return "MIN_TOK" +"max" return "MAX_TOK" +"as" return "AS_TOK" +"nil" return "NIL_TOK" +"_" return "UNDERSCORE_TOK" +"count" return "COUNT_TOK" +"sum" return "SUM_TOK" +"true" return "TRUELIT_TOK" +"false" return "FALSELIT_TOK" +"to_float" return "TOFLOAT_TOK" +"to_number" return "TONUMBER_TOK" +"to_string" return "TOSTRING_TOK" +"to_unsigned" return "TOUNSIGNED_TOK" +"choice-domain" return "CHOICEDOMAIN_TOK" +"recursive_iteration_cnt" return "ITERATION_TOK" +"__FILE__" lexNYI(yytext); +"__LINE__" lexNYI(yytext); +"__INCL__" lexNYI(yytext); +"|" return "PIPE_TOK" +"[" return "LBRACKET_TOK" +"]" return "RBRACKET_TOK" +"$" return "DOLLAR_TOK" +"+" return "PLUS_TOK" +"->" return "MAPSTO_TOK" +"-" return "MINUS_TOK" +"(" return "LPAREN_TOK" +")" return "RPAREN_TOK" +"," return "COMMA_TOK" +":-" return "IF_TOK" +":" return "COLON_TOK" +";" return "SEMICOLON_TOK" +"." return "DOT_TOK" +"<:" return "SUBTYPE_TOK" +"<=" return "LE_TOK" +">=" return "GE_TOK" +"!=" return "NE_TOK" +"=" return "EQUALS_TOK" +"!" return "EXCLAMATION_TOK" +"*" return "STAR_TOK" +"@" return "AT_TOK" +"/" return "SLASH_TOK" +"^" return "CARET_TOK" +"%" return "PERCENT_TOK" +"{" return "LBRACE_TOK" +"}" return "RBRACE_TOK" +"<" return "LT_TOK" +">" return "GT_TOK" +[0-9]+"."[0-9]+"."[0-9]+"."[0-9]+ lexNYI(yytext); +[0-9]+[.][0-9]+ return "FLOAT_TOK" +[0-9]+ return "NUMBER_TOK" +0b[0-1]+ return "NUMBER_TOK" +0x[a-fA-F0-9]+ return "NUMBER_TOK" +[0-9]+u return "UNSIGNED_TOK" +0b[0-1]+u return "UNSIGNED_TOK" +0x[a-fA-F0-9]+u return "UNSIGNED_TOK" +[_\?a-zA-Z][_\?a-zA-Z0-9]* return "IDENT_TOK"; +\"(\\.|[^"\\])*\" return "STRING_TOK"; +\#.*$ lexNYI(yytext); +<> {} +. lexError(`Unexpected token "${yytext}"`); + +/lex + +%token "END_TOK" 0 "end of file" +%token "STRING_TOK" "symbol" +%token "IDENT_TOK" "identifier" +%token "NUMBER_TOK" "number" +%token "UNSIGNED_TOK" "unsigned number" +%token "FLOAT_TOK" "float" +%token "AUTOINC_TOK" "auto-increment functor" +%token "PRAGMA_TOK" "pragma directive" +%token "OUTPUT_QUALIFIER_TOK" "relation qualifier output" +%token "INPUT_QUALIFIER_TOK" "relation qualifier input" +%token "PRINTSIZE_QUALIFIER_TOK" "relation qualifier printsize" +%token "BRIE_QUALIFIER_TOK" "BRIE datastructure qualifier" +%token "BTREE_QUALIFIER_TOK" "BTREE datastructure qualifier" +%token "BTREE_DELETE_QUALIFIER_TOK" "BTREE_DELETE datastructure qualifier" +%token "EQREL_QUALIFIER_TOK" "equivalence relation qualifier" +%token "OVERRIDABLE_QUALIFIER_TOK" "relation qualifier overidable" +%token "INLINE_QUALIFIER_TOK" "relation qualifier inline" +%token "NO_INLINE_QUALIFIER_TOK" "relation qualifier no_inline" +%token "MAGIC_QUALIFIER_TOK" "relation qualifier magic" +%token "NO_MAGIC_QUALIFIER_TOK" "relation qualifier no_magic" +%token "TMATCH_TOK" "match predicate" +%token "TCONTAINS_TOK" "checks whether substring is contained in a string" +%token "STATEFUL_TOK" "stateful functor" +%token "CAT_TOK" "concatenation of strings" +%token "ORD_TOK" "ordinal number of a string" +%token "RANGE_TOK" "range" +%token "STRLEN_TOK" "length of a string" +%token "SUBSTR_TOK" "sub-string of a string" +%token "MEAN_TOK" "mean aggregator" +%token "MIN_TOK" "min aggregator" +%token "MAX_TOK" "max aggregator" +%token "COUNT_TOK" "count aggregator" +%token "SUM_TOK" "sum aggregator" +%token "TRUELIT_TOK" "true literal constraint" +%token "FALSELIT_TOK" "false literal constraint" +%token "PLAN_TOK" "plan keyword" +%token "ITERATION_TOK" "recursive iteration keyword" +%token "CHOICEDOMAIN_TOK" "choice-domain" +%token "IF_TOK" ":-" +%token "DECL_TOK" "relation declaration" +%token "FUNCTOR_TOK" "functor declaration" +%token "INPUT_DECL_TOK" "input directives declaration" +%token "OUTPUT_DECL_TOK" "output directives declaration" +%token "DEBUG_DELTA_TOK" "debug_delta" +%token "UNIQUE_TOK" "unique" +%token "PRINTSIZE_DECL_TOK" "printsize directives declaration" +%token "LIMITSIZE_DECL_TOK" "limitsize directives declaration" +%token "OVERRIDE_TOK" "override rules of super-component" +%token "TYPE_TOK" "type declaration" +%token "LATTICE_TOK" "lattice declaration" +%token "COMPONENT_TOK" "component declaration" +%token "INSTANTIATE_TOK" "component instantiation" +%token "NUMBER_TYPE_TOK" "numeric type declaration" +%token "SYMBOL_TYPE_TOK" "symbolic type declaration" +%token "TOFLOAT_TOK" "convert to float" +%token "TONUMBER_TOK" "convert to signed integer" +%token "TOSTRING_TOK" "convert to string" +%token "TOUNSIGNED_TOK" "convert to unsigned integer" +%token "ITOU_TOK" "convert int to unsigned" +%token "ITOF_TOK" "convert int to float" +%token "UTOI_TOK" "convert unsigned to int" +%token "UTOF_TOK" "convert unsigned to float" +%token "FTOI_TOK" "convert float to int" +%token "FTOU_TOK" "convert float to unsigned" +%token "AS_TOK" "type cast" +%token "AT_TOK" "@" +%token "NIL_TOK" "nil reference" +%token "PIPE_TOK" "|" +%token "LBRACKET_TOK" "[" +%token "RBRACKET_TOK" "]" +%token "UNDERSCORE_TOK" "_" +%token "DOLLAR_TOK" "$" +%token "EXCLAMATION_TOK" "!" +%token "LPAREN_TOK" "(" +%token "RPAREN_TOK" ")" +%token "COMMA_TOK" "," +%token "COLON_TOK" ":" +%token "DOUBLECOLON_TOK" "::" +%token "SEMICOLON_TOK" ";" +%token "DOT_TOK" "." +%token "EQUALS_TOK" "=" +%token "LBRACE_TOK" "{" +%token "RBRACE_TOK" "}" +%token "SUBTYPE_TOK" "<:" +%token "LT_TOK" "<" +%token "GT_TOK" ">" +%token "LE_TOK" "<=" +%token "GE_TOK" ">=" +%token "NE_TOK" "!=" +%token "MAPSTO_TOK" "->" +%token "FOLD_TOK" "fold" + +/* -- Operator precedence -- */ +%left "L_OR_TOK" +%left "L_XOR_TOK" +%left "L_AND_TOK" +%left "BW_OR_TOK" +%left "BW_XOR_TOK" +%left "BW_AND_TOK" +%left "BW_SHIFT_L_TOK" "BW_SHIFT_R_TOK" "BW_SHIFT_R_UNSIGNED_TOK" +%left "PLUS_TOK" "MINUS_TOK" +%left "STAR_TOK" "SLASH_TOK" "PERCENT_TOK" +%nonassoc "NEG_TOK" "BW_NOT_TOK" "L_NOT_TOK" +%right "CARET_TOK" + +%start program + +%% + +/** + * Terminal symbols + */ + +DECL: "DECL_TOK"; +FUNCTOR: "FUNCTOR_TOK"; +INPUT_DECL: "INPUT_DECL_TOK"; +OUTPUT_DECL: "OUTPUT_DECL_TOK"; +PRINTSIZE_DECL: "PRINTSIZE_DECL_TOK"; +LIMITSIZE_DECL: "LIMITSIZE_DECL_TOK"; +TYPE: "TYPE_TOK"; +COMPONENT: "COMPONENT_TOK"; +INSTANTIATE: "INSTANTIATE_TOK"; +NUMBER_TYPE: "NUMBER_TYPE_TOK"; +SYMBOL_TYPE: "SYMBOL_TYPE_TOK"; +OVERRIDE: "OVERRIDE_TOK"; +PRAGMA: "PRAGMA_TOK"; +PLAN: "PLAN_TOK"; +LATTICE: "LATTICE_TOK"; +INCLUDE: "INCLUDE_TOK"; +DEBUG_DELTA: "DEBUG_DELTA_TOK"; +AUTOINC: "AUTOINC_TOK"; +TMATCH: "TMATCH_TOK"; +MEAN: "MEAN_TOK"; +CAT: "CAT_TOK"; +ORD: "ORD_TOK"; +FOLD: "FOLD_TOK"; +RANGE: "RANGE_TOK"; +STRLEN: "STRLEN_TOK"; +SUBSTR: "SUBSTR_TOK"; +STATEFUL: "STATEFUL_TOK"; +TCONTAINS: "TCONTAINS_TOK"; +OUTPUT_QUALIFIER: "OUTPUT_QUALIFIER_TOK"; +INPUT_QUALIFIER: "INPUT_QUALIFIER_TOK"; +OVERRIDABLE_QUALIFIER: "OVERRIDABLE_QUALIFIER_TOK"; +PRINTSIZE_QUALIFIER: "PRINTSIZE_QUALIFIER_TOK"; +EQREL_QUALIFIER: "EQREL_QUALIFIER_TOK"; +INLINE_QUALIFIER: "INLINE_QUALIFIER_TOK"; +NO_INLINE_QUALIFIER: "NO_INLINE_QUALIFIER_TOK"; +MAGIC_QUALIFIER: "MAGIC_QUALIFIER_TOK"; +NO_MAGIC_QUALIFIER: "NO_MAGIC_QUALIFIER_TOK"; +BRIE_QUALIFIER: "BRIE_QUALIFIER_TOK"; +BTREE_DELETE_QUALIFIER: "BTREE_DELETE_QUALIFIER_TOK"; +BTREE_QUALIFIER: "BTREE_QUALIFIER_TOK"; +MIN: "MIN_TOK"; +MAX: "MAX_TOK"; +AS: "AS_TOK"; +NIL: "NIL_TOK"; +UNDERSCORE: "UNDERSCORE_TOK"; +COUNT: "COUNT_TOK"; +SUM: "SUM_TOK"; +TRUELIT: "TRUELIT_TOK"; +FALSELIT: "FALSELIT_TOK"; +TOFLOAT: "TOFLOAT_TOK"; +TONUMBER: "TONUMBER_TOK"; +TOSTRING: "TOSTRING_TOK"; +TOUNSIGNED: "TOUNSIGNED_TOK"; +CHOICEDOMAIN: "CHOICEDOMAIN_TOK"; +ITERATION: "ITERATION_TOK"; +PIPE: "PIPE_TOK"; +LBRACKET: "LBRACKET_TOK"; +RBRACKET: "RBRACKET_TOK"; +DOLLAR: "DOLLAR_TOK"; +MAPSTO: "MAPSTO_TOK"; +LPAREN: "LPAREN_TOK"; +RPAREN: "RPAREN_TOK"; +COMMA: "COMMA_TOK"; +COLON: "COLON_TOK"; +SEMICOLON: "SEMICOLON_TOK"; +SUBTYPE: "SUBTYPE_TOK"; +LE: "LE_TOK"; +GE: "GE_TOK"; +NE: "NE_TOK"; +EQUALS: "EQUALS_TOK"; +AT: "AT_TOK"; +LBRACE: "LBRACE_TOK"; +RBRACE: "RBRACE_TOK"; +LT: "LT_TOK"; +GT: "GT_TOK"; +IF: "IF_TOK"; +END: "END_TOK"; +FLOAT + : "FLOAT_TOK" + { + $$ = Number(yytext); + } + ; +NUMBER + : "NUMBER_TOK" + { + $$ = BigInt(yytext); + } + ; +UNSIGNED + : "UNSIGNED_TOK" + { + $$ = BigInt(yytext.slice(0, -1)); + } + ; +STRING + : "STRING_TOK" + { + $$ = yytext; + } + ; +IDENT + : "IDENT_TOK" + { + $$ = yytext; + } + ; + +/** + * Program + */ +program + : unit + { + return $1; + } + ; + +/** + * Top-level Program Elements + */ +unit + : %empty + { $$ = []; } + | unit directive_head + { + $$ = $1; + $$.push(...$2); + } + | unit rule + { + $$ = $1; + $$.push(...$2); + } + | unit fact + { + $$ = $1; + $$.push($2); + } + | unit component_decl + { + $$ = $1; + $$.push($2); + } + | unit component_init + { + $$ = $1; + $$.push($2); + } + | unit pragma + { + $$ = $1; + $$.push($2); + } + | unit type_decl + { + $$ = $1; + $$.push($2); + } + | unit lattice_decl + { + $$ = $1; + $$.push($2); + } + | unit functor_decl + { + $$ = $1; + $$.push($2); + } + | unit relation_decl + { + $$ = $1; + $$.push(...$2); + } + ; + +/** + * A Qualified Name + */ + +qualified_name + : IDENT + { + $$ = $1; + } + | qualified_name DOT_TOK IDENT + { + $$ = $1 + "." + $3; + } + ; + +/** + * Type Declarations + */ +type_decl + : TYPE IDENT SUBTYPE qualified_name + { + $$ = new ast.SubsetType($2, $4, @$); + } + | TYPE IDENT EQUALS union_type_list + { + if ($4.length > 1) { + $$ = new ast.UnionType($2, $4, @$); + } else { + assert($4.length == 1); + $$ = new ast.AliasType($2, $4[0], @$); + } + } + | TYPE IDENT EQUALS record_type_list + { + $$ = new ast.RecordType($2, $4, @$); + } + | TYPE IDENT EQUALS adt_branch_list + { + $$ = new ast.AlgebraicDataType($2, $4, @$); + } + /* Deprecated Type Declarations */ + | NUMBER_TYPE IDENT + { + parseNYI(`Deprecated number type ${yytext}`); + } + | SYMBOL_TYPE IDENT + { + parseNYI(`Deprecated symbol type ${yytext}`); + } + | TYPE IDENT + { + parseNYI(`Deprecated sub type ${yytext}`); + } + ; + +/* Attribute definition of a relation */ +/* specific wrapper to ensure the err msg says "expected ',' or ')'" */ +record_type_list + : LBRACKET RBRACKET + { $$ = []; } + | LBRACKET non_empty_attributes RBRACKET + { + $$ = $2; + } + ; + +/* Union type argument declarations */ +union_type_list + : qualified_name + { + $$ = [$1]; + } + | union_type_list PIPE qualified_name + { + $$ = $1; + $$.push($3); + } + ; + +adt_branch_list + : adt_branch + { + $$ = [$1]; + } + | adt_branch_list PIPE adt_branch + { + $$ = $1; + $$.push($3); + } + ; + +adt_branch + : IDENT LBRACE RBRACE + { + $$ = [$1, []]; + } + | IDENT LBRACE non_empty_attributes RBRACE + { + $$ = [$1, $3]; + } + ; + +/** + * Lattice Declarations + */ + +lattice_decl + : LATTICE IDENT LT GT LBRACE lattice_operator_list RBRACE + { + parseNYI(`Lattice decl ${yytext}`); + } + ; + +lattice_operator_list + : lattice_operator COMMA lattice_operator_list + { + parseNYI(`Lattice operator list ${yytext}`); + } + | lattice_operator + { + parseNYI(`Lattice operator list ${yytext}`); + } + ; + +lattice_operator + : IDENT MAPSTO arg + { + parseNYI(`Lattice operator ${yytext}`); + } + ; + +/** + * Relations + */ + +/** + * Relation Declaration + */ +relation_decl + : DECL relation_names attributes_list relation_tags dependency_list + { + $$ = []; + + for (const name of $2) { + $$.push(new ast.Relation(name, $3, new Set($4), $5)); + } + } + | DECL IDENT[delta] EQUALS DEBUG_DELTA LPAREN IDENT[name] RPAREN relation_tags + { + parseNYI('Debug delta: ${yytext}'); + } + ; + +/** + * Relation Names + */ +relation_names + : IDENT + { + $$ = [$1]; + } + | relation_names COMMA IDENT + { + $$ = $1; + $$.push($3); + } + ; + +/** + * Attributes + */ +attributes_list + : LPAREN RPAREN + { + $$ = []; + } + | LPAREN non_empty_attributes RPAREN + { + $$ = $2; + } + ; + +non_empty_attributes + : attribute + { + $$ = [$1]; + } + | non_empty_attributes COMMA attribute + { + $$ = $1; + $$.push($3); + } + ; + +attribute + : IDENT COLON qualified_name + { + $$ = [$1, new ast.NamedType($3, @3), false]; + } + | IDENT COLON qualified_name LT GT + { + parseNYI("Attribute with <>: ${yytext}"); + $$ = [$1, new ast.NamedType($3, @3), true]; + } + ; + +/** + * Relation Tags + */ +relation_tags + : %empty + { $$ = []; } + | relation_tags OVERRIDABLE_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags INLINE_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags NO_INLINE_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags MAGIC_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags NO_MAGIC_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags BRIE_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags BTREE_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags BTREE_DELETE_QUALIFIER + { + $$ = $1; + $$.push($2); + } + | relation_tags EQREL_QUALIFIER + { + $$ = $1; + $$.push($2); + } + /* Deprecated Qualifiers */ + | relation_tags OUTPUT_QUALIFIER + { + parseNYI(`Deprecated relation tag ${yytext}`); + } + | relation_tags INPUT_QUALIFIER + { + parseNYI(`Deprecated relation tag ${yytext}`); + } + | relation_tags PRINTSIZE_QUALIFIER + { + parseNYI(`Deprecated relation tag ${yytext}`); + } + ; + +/** + * Attribute Name List + */ +non_empty_attribute_names + : IDENT + { + $$ = [$1]; + } + + | non_empty_attribute_names COMMA IDENT + { + $$ = $1; + $$.push($3); + } + ; + +/** + * Functional Dependency Constraint + */ +dependency + : IDENT + { + $$ = $1; + } + | LPAREN non_empty_attribute_names RPAREN + { + $$ = $2; + } + ; + +dependency_list_aux + : dependency + { + $$ = [$1]; + } + | dependency_list_aux COMMA dependency + { + $$ = $1; + $$.push($3); + } + ; + +dependency_list + : %empty + { $$ = []; } + | CHOICEDOMAIN dependency_list_aux + { + $$ = $2; + } + ; + +/** + * Datalog Rule Structure + */ + +/** + * Fact + */ +fact + : atom DOT_TOK + { + $$ = new ast.Fact($1, @$); + } + ; + +/** + * Rule + */ +rule + : rule_def + { + $$ = $1; + } + | rule_def query_plan + { + $$ = $1; + for (const rule of $$) { + rule.queryPlan = $2; + } + } + | atom LE atom IF body DOT_TOK + { + $$ = [new ast.Subsumption($1, $3, $5, [], @$)]; + } + | atom LE atom IF body DOT_TOK query_plan + { + $$ = [new ast.Subsumption($1, $3, $5, $7, @$)]; + } + ; + +/** + * Rule Definition + */ +rule_def + : head IF body DOT_TOK + { + $$ = []; + for (const head of $1) { + $$.push(new ast.Rule(head, $3, [])) + } + } + ; + +/** + * Rule Head + */ +head + : atom + { + $$ = [$1]; + } + | head COMMA atom + { + $$ = $1; $$.push($3); + } + ; + +/** + * Rule Body + */ +body + : disjunction + { + $$ = new ast.Disjunction($1, @$); + } + ; + +disjunction + : conjunction + { + $$ = [new ast.Conjunction($1, @$)]; + } + | disjunction SEMICOLON conjunction + { + $$ = $1; + $$.push(new ast.Conjunction($3, @3)); + } + ; + +conjunction + : term + { + $$ = [$1]; + } + | conjunction COMMA term + { + $$ = $1; + $$.push($3); + } + ; + +/** + * Terms in Rule Bodies + */ +term + : atom + { + $$ = $1; + } + | constraint + { + $$ = $1; + } + | LPAREN disjunction RPAREN + { + $$ = new ast.Disjunction($2, @2); + } + | EXCLAMATION_TOK term + { + $$ = new ast.Negation($2, @$); + } + ; + +/** + * Rule body atom + */ +atom + : IDENT LPAREN arg_list RPAREN + { + $$ = new ast.Atom($1, $3, @$); + } + /* This is a hack to work around a stupid R/R ambiguity in JISON. Probably cleaner ways to do this*/ + | IDENT DOT_TOK qualified_name LPAREN arg_list RPAREN + { + $$ = new ast.Atom(`${$1}.${$3}`, $5, @$); + } + ; + +/** + * Literal Constraints + */ +constraint + /* binary infix constraints */ + : arg LT arg + { + $$ = new ast.Comparison($1, "<", $3, @$); + } + | arg GT arg + { + $$ = new ast.Comparison($1, ">", $3, @$); + } + | arg LE arg + { + $$ = new ast.Comparison($1, "<=", $3, @$); + } + | arg GE arg + { + $$ = new ast.Comparison($1, ">=", $3, @$); + } + | arg EQUALS arg + { + $$ = new ast.Comparison($1, "=", $3, @$); + } + | arg NE arg + { + $$ = new ast.Comparison($1, "!=", $3, @$); + } + + /* binary prefix constraints */ + | TMATCH LPAREN arg COMMA arg RPAREN + { + $$ = new ast.StringConstraint("match", $3, $5, @$); + } + | TCONTAINS LPAREN arg COMMA arg RPAREN + { + $$ = new ast.StringConstraint("contains", $3, $5, @$); + } + + /* zero-arity constraints */ + | TRUELIT + { + $$ = new ast.BoolLiteral(true, @$); + } + | FALSELIT + { + $$ = new ast.BoolLiteral(false, @$); + } + ; + +/** + * Argument List + */ +arg_list + : %empty + { + $$ = []; + } + | non_empty_arg_list + { + $$ = $1; + } ; + +non_empty_arg_list + : arg + { + $$ = [$1]; + } + | non_empty_arg_list COMMA arg + { + $$ = $1; $$.push($3); + } + ; + + +/** + * Atom argument + */ +arg + : STRING + { + $$ = new ast.StringLiteral($1.slice(1, -1), @$); + } + | FLOAT + { + $$ = new ast.Float($1, @$); + } + | UNSIGNED + { + $$ = new ast.Unsigned($1, @$); + } + | NUMBER + { + $$ = new ast.Num($1, @$); + } + | ITERATION LPAREN RPAREN + { + parseNYI(`Iteration: ${yytext}`); + } + | UNDERSCORE + { + $$ = new ast.UnnamedVar(@$); + } + | DOLLAR + { + $$ = new ast.AutoIncrement(@$); + } + | AUTOINC LPAREN RPAREN + { + $$ = new ast.AutoIncrement(@$); + } + | IDENT + { + $$ = new ast.Identifier($1, @$); + } + | NIL + { + $$ = new ast.Nil(@$); + } + | LBRACKET arg_list RBRACKET + { + $$ = new ast.RecordLiteral($2, @$); + } + | DOLLAR qualified_name LPAREN arg_list RPAREN + { + $$ = new ast.ADTLiteral($2, $4, @$); + } + | LPAREN arg RPAREN + { + $$ = $2; + } + | AS LPAREN arg COMMA qualified_name RPAREN + { + $$ = new ast.TypeCast($3, new ast.NamedType($5), @$); + } + | AT IDENT LPAREN arg_list RPAREN + { + $$ = new ast.FunctorCall($2, $4, false, @$); + } + | functor_built_in LPAREN arg_list RPAREN + { + $$ = new ast.FunctorCall($1, $3, true, @$); + } + + /* some aggregates have the same name as functors */ + | aggregate_func LPAREN arg[first] COMMA non_empty_arg_list[rest] RPAREN + { + parseNYI(`Aggregators ${yytext}`) + } + + /* -- intrinsic functor -- */ + /* unary functors */ + | MINUS_TOK arg %prec NEG_TOK + { + $$ = new ast.UnaryOperator("-", $2, @$); + } + | BW_NOT_TOK arg + { + $$ = new ast.UnaryOperator("~", $2, @$); + } + | L_NOT_TOK arg + { + $$ = new ast.UnaryOperator("!", $2, @$); + } + + /* binary infix functors */ + | arg PLUS_TOK arg + { + $$ = new ast.BinaryOperator($1, "+", $3, @$); + } + | arg MINUS_TOK arg + { + $$ = new ast.BinaryOperator($1, "-", $3, @$); + } + | arg STAR_TOK arg + { + $$ = new ast.BinaryOperator($1, "*", $3, @$); + } + | arg SLASH_TOK arg + { + $$ = new ast.BinaryOperator($1, "/", $3, @$); + } + | arg PERCENT_TOK arg + { + $$ = new ast.BinaryOperator($1, "%", $3, @$); + } + | arg CARET_TOK arg + { + $$ = new ast.BinaryOperator($1, "**", $3, @$); + } + | arg L_AND_TOK arg + { + $$ = new ast.BinaryOperator($1, "&&", $3, @$); + } + | arg L_OR_TOK arg + { + $$ = new ast.BinaryOperator($1, "||", $3, @$); + } + | arg L_XOR_TOK arg + { + $$ = new ast.BinaryOperator($1, "^^", $3, @$); + } + | arg BW_AND_TOK arg + { + $$ = new ast.BinaryOperator($1, "&", $3, @$); + } + | arg BW_OR_TOK arg + { + $$ = new ast.BinaryOperator($1, "|", $3, @$); + } + | arg BW_XOR_TOK arg + { + $$ = new ast.BinaryOperator($1, "^", $3, @$); + } + | arg BW_SHIFT_L_TOK arg + { + $$ = new ast.BinaryOperator($1, "<<", $3, @$); + } + | arg BW_SHIFT_R_TOK arg + { + $$ = new ast.BinaryOperator($1, ">>", $3, @$); + } + | arg BW_SHIFT_R_UNSIGNED_TOK arg + { + $$ = new ast.BinaryOperator($1, ">>>", $3, @$); + } + /* -- User-defined aggregators -- */ + | AT AT IDENT arg_list COLON arg COMMA aggregate_body + { + parseNYI(`User-defined Aggregators ${yytext}`) + } + /* -- aggregators -- */ + | aggregate_func arg_list COLON aggregate_body + { + parseNYI(`Aggregators ${yytext}`) + } + ; + +functor_built_in + : CAT + { + $$ = "cat"; + } + | ORD + { + $$ = "ord"; + } + | RANGE + { + $$ = "range"; + } + | STRLEN + { + $$ = "strlen"; + } + | SUBSTR + { + $$ = "substr"; + } + | TOFLOAT + { + $$ = "to_float"; + } + | TONUMBER + { + $$ = "to_number"; + } + | TOSTRING + { + $$ = "to_string"; + } + | TOUNSIGNED + { + $$ = "to_unsigned"; + } + ; + +aggregate_func + : COUNT + { + $$ = "count"; + } + | MAX + { + $$ = "max"; + } + | MEAN + { + $$ = "mean"; + } + | MIN + { + $$ = "min"; + } + | SUM + { + $$ = "sum"; + } + ; + +aggregate_body + : LBRACE body RBRACE + { + $$ = $2; + } + | atom + { + $$ = $1; + } + ; + +/** + * Query Plan + */ +query_plan + : PLAN query_plan_list + { + $$ = $1; + }; + +query_plan_list + : NUMBER COLON plan_order + { + $$ = [$1, $3]; + } + | query_plan_list COMMA NUMBER COLON plan_order + { + $$ = $1; + $$.push([$3, $5]); + } + ; + +plan_order + : LPAREN RPAREN + { + $$ = []; + } + | LPAREN non_empty_plan_order_list RPAREN + { + $$ = $2; + } + ; + +non_empty_plan_order_list + : NUMBER + { + $$ = [$1]; + } + | non_empty_plan_order_list COMMA NUMBER + { + $$ = $1; $$.push($3); + } + ; + +/** + * Components + */ + +/** + * Component Declaration + */ +component_decl + : component_head LBRACE component_body RBRACE + { + const [[name, typeParams], baseInvocations] = $1; + + $$ = new ast.Component(name, typeParams, baseInvocations, $3); + } + ; + +/** + * Component Head + */ +component_head + : COMPONENT component_type + { + $$ = [$2, []]; + } + | component_head COLON component_type + { + $$ = $1; + $$[1].push($3); + } + | component_head COMMA component_type + { + $$ = $1; + $$[1].push($3); + } + ; + +/** + * Component Type + */ +component_type + : IDENT component_type_params + { + $$ = [$1, $2]; + }; + +/** + * Component Parameters + */ +component_type_params + : %empty + { $$ = []; } + | LT component_param_list GT + { + $$ = $2; + } + ; + +/** + * Component Parameter List + */ +component_param_list + : IDENT + { + $$ = $1; + } + | component_param_list COMMA IDENT + { + $$ = $1; + $$.push($3); + } + ; + +/** + * Component body + */ +component_body + : %empty + { + $$ = []; + } + | component_body directive_head + { + $$ = $1; + $$.push(...$2); + } + | component_body rule + { + $$ = $1; + $$.push($2); + } + | component_body fact + { + $$ = $1; + $$.push($2); + } + | component_body OVERRIDE IDENT + { + $$ = $1; + $$.push(new ast.Override($3, @3)); + } + | component_body component_init + { + $$ = $1; + $$.push($2); + } + | component_body component_decl + { + $$ = $1; + $$.push($2); + } + | component_body type_decl + { + $$ = $1; + $$.push($2); + } + | component_body lattice_decl + { + $$ = $1; + $$.push($2); + } + | component_body relation_decl + { + $$ = $1; + $$.push(...$2); + } + ; + +/** + * Component Initialisation + */ +component_init + : INSTANTIATE IDENT EQUALS component_type + { + $$ = new ast.ComponentInit($2, $4, @$); + } + ; + +/** + * User-Defined Functors + */ + +/** + * Functor declaration + */ +functor_decl + : FUNCTOR IDENT LPAREN functor_arg_type_list RPAREN COLON qualified_name + { + $$ = new ast.Functor($2, $4, new ast.NamedType($7, @7), false, @$); + } + | FUNCTOR IDENT LPAREN functor_arg_type_list RPAREN COLON qualified_name STATEFUL + { + $$ = new ast.Functor($2, $4, new ast.NamedType($7, @7), true, @$); + } + ; + +/** + * Functor argument list type + */ +functor_arg_type_list + : %empty + { + return []; + } + | non_empty_functor_arg_type_list + { + $$ = $1; + } + ; + +non_empty_functor_arg_type_list + : functor_attribute + { + $$ = [$1]; + } + | non_empty_functor_arg_type_list COMMA functor_attribute + { + $$ = $1; $$.push($3); + } + ; + +functor_attribute + : qualified_name + { + $$ = ["", new ast.NamedType($1, @1)]; + } + | IDENT COLON qualified_name + { + $$ = [$1, new ast.NamedType($3, @3)]; + } + ; + +/** + * Other Directives + */ + +/** + * Pragma Directives + */ +pragma + : PRAGMA STRING STRING + { + $$ = new ast.Pragma($2, $3, @$); + } + | PRAGMA STRING + { + $$ = new ast.Pragma($2, undefined, @$); + } + ; + +/** + * Directives + */ +directive_head + : directive_head_decl directive_list + { + $$ = $2.map(([name, args]) => + new ast.Directive($1, name, args) + ) + } + ; + +directive_head_decl + : INPUT_DECL + { + $$ = yytext; + } + | OUTPUT_DECL + { + $$ = yytext; + } + | PRINTSIZE_DECL + { + $$ = yytext; + } + | LIMITSIZE_DECL + { + $$ = yytext; + } + ; + +/** + * Directive List + */ +directive_list + : relation_directive_list + { + $$ = $1.map((x) => [x, []]); + } + | relation_directive_list LPAREN RPAREN + { + $$ = $1.map((x) => [x, []]); + } + | relation_directive_list LPAREN non_empty_key_value_pairs RPAREN + { + $$ = $1.map((x) => [x, [...$3]]); + } + ; + +/** + * Directive List + */ +relation_directive_list + : qualified_name + { + return [ $1 ]; + } + | relation_directive_list COMMA qualified_name + { + $$ = $1; + $$.push($3); + } + ; + +/** + * Key-value Pairs + */ +non_empty_key_value_pairs + : IDENT EQUALS kvp_value + { + $$ = [[$1, $3]]; + } + | non_empty_key_value_pairs COMMA IDENT EQUALS kvp_value + { + $$ = $1; + $$.push([$3, $5]); + } + ; + +kvp_value + : STRING + { + $$ = new ast.StringLiteral($1.slice(1, -1), @$); + } + | IDENT + { + $$ = new ast.Identifier($1, @$); + } + | NUMBER + { + $$ = new ast.Num($1, @$); + } + | TRUELIT + { + $$ = new ast.BoolLiteral(true, @$); + } + | FALSELIT + { + $$ = new ast.BoolLiteral(false, @$); + } + ; + +%% \ No newline at end of file diff --git a/src/lib/utils/eq.ts b/src/lib/utils/eq.ts new file mode 100644 index 0000000..6f93eb5 --- /dev/null +++ b/src/lib/utils/eq.ts @@ -0,0 +1,144 @@ +export function isPrimitive(a: any): boolean { + return ( + typeof a === "bigint" || + typeof a === "boolean" || + typeof a === "number" || + typeof a === "string" || + a === undefined || + a === null + ); +} + +// Hack to recognize big ints +export function isBigInt(a: any): boolean { + return typeof a === "number" || typeof a === "bigint"; +} + +export function hasKeysOf(a: Record, b: Record): boolean { + const hasProperty = Object.prototype.hasOwnProperty; + + for (const key in a) { + if (!hasProperty.call(b, key)) { + return false; + } + } + + return true; +} + +export interface StructEqualityComparable { + getStructId(): any; +} + +export function isStructEqualityComparable(a: any): a is StructEqualityComparable { + return typeof a.getStructId === "function"; +} + +/** + * Computes structural equality between two JavaScript objects. + * Handles only primitive types and JSON-style objects + * (i.e. object whose constructor is `Object`). + * + * To handle any other kind of objects, you need to make sure it inherits + * from `StructEqualityComparable` and implement `getFields()` + * for that object correctly. + */ +export function eq(a: any, b: any, visited?: Map): boolean { + if (a === b) { + return true; + } + + if (visited === undefined) { + visited = new Map(); + } + + if (visited.has(a)) { + /** + * Note identity equality here + */ + return visited.get(a) === b; + } + + visited.set(a, b); + + if (isPrimitive(a) || isPrimitive(b)) { + return a === b; + } + + if (isBigInt(a) && isBigInt(b)) { + return a === b; + } + + if (a instanceof Array && b instanceof Array) { + if (a.length !== b.length) { + return false; + } + + for (const key in a) { + if (!eq(a[key], b[key], visited)) { + return false; + } + } + + return true; + } + + if (a instanceof Set && b instanceof Set) { + if (a.size !== b.size) { + return false; + } + + for (const key of a.keys()) { + if (!b.has(key)) { + return false; + } + } + + return true; + } + + if (a.constructor === Object && b.constructor === Object) { + if (!hasKeysOf(a, b) || !hasKeysOf(b, a)) { + return false; + } + + for (const key in a) { + if (!eq(a[key], b[key], visited)) { + return false; + } + } + + return true; + } + + if (isStructEqualityComparable(a) && isStructEqualityComparable(b)) { + if (a.constructor !== b.constructor) { + return false; + } + + const fieldsA = a.getStructId(); + const fieldsB = b.getStructId(); + + if (fieldsA.length !== fieldsB.length) { + return false; + } + + /** + * Note here we rely on getFields always returning fields in the same order + * to avoid having to sort fieldsA and fieldsB. + */ + for (let i = 0; i < fieldsA.length; i++) { + if (!eq(fieldsA[i], fieldsB[i], visited)) { + return false; + } + } + + return true; + } + + throw new Error( + `Cannot compare ${a} (type ${typeof a} constr ${ + a.constructor + }) and ${b} (type ${typeof b} constr ${b.constructor}) structurally` + ); +} diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts new file mode 100644 index 0000000..e4ef27f --- /dev/null +++ b/src/lib/utils/index.ts @@ -0,0 +1,3 @@ +export * from "./misc"; +export * from "./pp"; +export * from "./eq"; diff --git a/src/lib/utils/misc.ts b/src/lib/utils/misc.ts new file mode 100644 index 0000000..80b98df --- /dev/null +++ b/src/lib/utils/misc.ts @@ -0,0 +1,122 @@ +import * as sol from "solc-typed-ast"; +import fse from "fs-extra"; +import path from "path"; + +export function flatten(arg: T[][]): T[] { + const res: T[] = []; + for (const x of arg) { + res.push(...x); + } + + return res; +} + +export function zip(x: T1[], y: T2[]): Array<[T1, T2]> { + const res: Array<[T1, T2]> = []; + + for (let i = 0; i < x.length; i++) { + res.push([x[i], y[i]]); + } + + return res; +} + +export function chunk(arr: T[], chunkSize: number): T[][] { + const res: T[][] = []; + let chunk: T[] = []; + + for (const x of arr) { + if (chunk.length === chunkSize) { + res.push(chunk); + chunk = []; + } + + chunk.push(x); + } + + if (chunk.length > 0) { + res.push(chunk); + } + + return res; +} + +/** + * Convert a TS list into a datalog "recursive" list. + */ +export function listify(lst: string[]): string { + if (lst.length === 0) { + return `nil`; + } + + return lst.reduceRight((x, y) => `[${y}, ${x}]`, "nil"); +} + +/** + * Convert a TS bool into a datalog "bool" + */ +export function boolify(b: boolean): string { + // For now we define bool in datalog as number + return b ? "1" : "0"; +} + +export function sanitizeString(s: string): string { + // For various compiler versions a string may be missing in the AST + if (s === null || s === undefined) { + s = ""; + } + + return s + .replaceAll('"', "'") // Only single quotes + .replaceAll("\n", "\\n") // Escape new lines + .replaceAll("\r", "\\r") // Escape carriage return + .replaceAll(/[^\x20-\x7E]+/g, ""); // Remove remaining unicode characters +} + +export function translateVal(a: any): string { + if (typeof a === "string") { + return `"${a}"`; + } + + if (typeof a === "boolean") { + return boolify(a); + } + + if (typeof a === "number") { + return `${a}`; + } + + if (a instanceof sol.ASTNode) { + return `${a.id}`; + } + + console.trace(); + + throw new Error(`Don't know how to translate ${a}`); +} + +export function searchRecursive(targetPath: string, filter: (entry: string) => boolean): string[] { + const stat = fse.statSync(targetPath); + const results: string[] = []; + + if (stat.isFile()) { + if (filter(targetPath)) { + results.push(path.resolve(targetPath)); + } + + return results; + } + + for (const entry of fse.readdirSync(targetPath)) { + const resolvedEntry = path.resolve(targetPath, entry); + const stat = fse.statSync(resolvedEntry); + + if (stat.isDirectory()) { + results.push(...searchRecursive(resolvedEntry, filter)); + } else if (stat.isFile() && filter(resolvedEntry)) { + results.push(resolvedEntry); + } + } + + return results; +} diff --git a/src/lib/utils/pp.ts b/src/lib/utils/pp.ts new file mode 100644 index 0000000..91fc53b --- /dev/null +++ b/src/lib/utils/pp.ts @@ -0,0 +1,103 @@ +export interface PPAble { + pp(): string; +} + +export type PPIsh = + | PPAble + | string + | number + | boolean + | bigint + | null + | undefined + | PPIsh[] + | Set + | Map + | Iterable; + +export function isPPAble(value: any): value is PPAble { + return value ? typeof value.pp === "function" : false; +} + +export function pp(value: PPIsh): string { + if (value === undefined) { + return ""; + } + + if ( + value === null || + typeof value === "string" || + typeof value === "number" || + typeof value === "boolean" || + typeof value === "bigint" + ) { + return String(value); + } + + if (isPPAble(value)) { + return value.pp(); + } + + if (value instanceof Array) { + return ppArr(value); + } + + if (value instanceof Set) { + return ppSet(value); + } + + if (value instanceof Map) { + return ppMap(value); + } + + if (typeof value[Symbol.iterator] === "function") { + return ppIter(value); + } + + throw new Error("Unhandled value in pp(): " + String(value)); +} + +export function ppArr(array: PPIsh[], separator = ",", start = "[", end = "]"): string { + return start + array.map(pp).join(separator) + end; +} + +export function ppIter(iter: Iterable, separator = ",", start = "[", end = "]"): string { + const parts: string[] = []; + + for (const part of iter) { + parts.push(pp(part)); + } + + return start + parts.join(separator) + end; +} + +export function ppSet(set: Set, separator = ",", start = "{", end = "}"): string { + return ppIter(set, separator, start, end); +} + +export function ppMap( + map: Map, + separator = ",", + keyValueSeparator = ":", + start = "{", + end = "}" +): string { + const parts: string[] = []; + + for (const [name, val] of map.entries()) { + parts.push(pp(name) + keyValueSeparator + pp(val)); + } + + return start + parts.join(separator) + end; +} + +export function fmt(message: string, ...details: PPIsh[]): string { + for (let i = 0; i < details.length; i++) { + const detail = details[i]; + const part = pp(detail); + + message = message.replace(new RegExp("\\{" + i + "\\}", "g"), part); + } + + return message; +} From 167164aa120c9228ee12428b06baecfd5f0b52c1 Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Fri, 1 Mar 2024 06:59:53 +0200 Subject: [PATCH 05/10] nit --- src/lib/utils.ts | 122 ----------------------------------------------- 1 file changed, 122 deletions(-) delete mode 100644 src/lib/utils.ts diff --git a/src/lib/utils.ts b/src/lib/utils.ts deleted file mode 100644 index 80b98df..0000000 --- a/src/lib/utils.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as sol from "solc-typed-ast"; -import fse from "fs-extra"; -import path from "path"; - -export function flatten(arg: T[][]): T[] { - const res: T[] = []; - for (const x of arg) { - res.push(...x); - } - - return res; -} - -export function zip(x: T1[], y: T2[]): Array<[T1, T2]> { - const res: Array<[T1, T2]> = []; - - for (let i = 0; i < x.length; i++) { - res.push([x[i], y[i]]); - } - - return res; -} - -export function chunk(arr: T[], chunkSize: number): T[][] { - const res: T[][] = []; - let chunk: T[] = []; - - for (const x of arr) { - if (chunk.length === chunkSize) { - res.push(chunk); - chunk = []; - } - - chunk.push(x); - } - - if (chunk.length > 0) { - res.push(chunk); - } - - return res; -} - -/** - * Convert a TS list into a datalog "recursive" list. - */ -export function listify(lst: string[]): string { - if (lst.length === 0) { - return `nil`; - } - - return lst.reduceRight((x, y) => `[${y}, ${x}]`, "nil"); -} - -/** - * Convert a TS bool into a datalog "bool" - */ -export function boolify(b: boolean): string { - // For now we define bool in datalog as number - return b ? "1" : "0"; -} - -export function sanitizeString(s: string): string { - // For various compiler versions a string may be missing in the AST - if (s === null || s === undefined) { - s = ""; - } - - return s - .replaceAll('"', "'") // Only single quotes - .replaceAll("\n", "\\n") // Escape new lines - .replaceAll("\r", "\\r") // Escape carriage return - .replaceAll(/[^\x20-\x7E]+/g, ""); // Remove remaining unicode characters -} - -export function translateVal(a: any): string { - if (typeof a === "string") { - return `"${a}"`; - } - - if (typeof a === "boolean") { - return boolify(a); - } - - if (typeof a === "number") { - return `${a}`; - } - - if (a instanceof sol.ASTNode) { - return `${a.id}`; - } - - console.trace(); - - throw new Error(`Don't know how to translate ${a}`); -} - -export function searchRecursive(targetPath: string, filter: (entry: string) => boolean): string[] { - const stat = fse.statSync(targetPath); - const results: string[] = []; - - if (stat.isFile()) { - if (filter(targetPath)) { - results.push(path.resolve(targetPath)); - } - - return results; - } - - for (const entry of fse.readdirSync(targetPath)) { - const resolvedEntry = path.resolve(targetPath, entry); - const stat = fse.statSync(resolvedEntry); - - if (stat.isDirectory()) { - results.push(...searchRecursive(resolvedEntry, filter)); - } else if (stat.isFile() && filter(resolvedEntry)) { - results.push(resolvedEntry); - } - } - - return results; -} From 33c229b43960d98d336843bb13d5766fd60f8654 Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Sat, 2 Mar 2024 02:28:50 +0200 Subject: [PATCH 06/10] Replace old type parsing logic with new paser; Fix parser bugs; Get tests to run --- .gitignore | 1 + package.json | 8 +- src/lib/analyses/calltree.dl | 2 +- src/lib/souffle/fact.ts | 86 ++++++++------ src/lib/souffle/instance.ts | 44 ++++---- src/lib/souffle/parser/souffle.jison | 6 +- src/lib/souffle/relation.ts | 31 +++-- src/lib/souffle/types.ts | 163 +++++++++++++++++---------- 8 files changed, 200 insertions(+), 141 deletions(-) diff --git a/.gitignore b/.gitignore index dd3e193..7cef8e0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,6 @@ tmp/ src/gen/translate.ts src/gen/declarations.ts src/lib/souffle/value_parser.ts +src/lib/souffle/parser/souffle_parser_gen.js functors/functors.o functors/libfunctors.so diff --git a/package.json b/package.json index b276589..104650c 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,10 @@ "gen-translation-modules": "node scripts/gen_translation_modules.js && eslint --fix src/gen/translate.ts src/gen/declarations.ts", "copy-dl": "cp -r src/lib/analyses dist/lib && cp -r src/lib/detectors dist/lib", "copy-functors": "cp -r functors dist/", - "build-parser": "tspegjs -o src/lib/souffle/value_parser.ts --custom-header-file src/lib/souffle/value_header.ts --allowed-start-rules Value --cache src/lib/souffle/values.pegjs", + "build-parser": "jison src/lib/souffle/parser/souffle.jison -o src/lib/souffle/parser/souffle_parser_gen.js -m commonjs && cp src/lib/souffle/parser/souffle_parser_gen.js dist/lib/souffle/parser/souffle_parser_gen.js", + "build-value-parser": "tspegjs -o src/lib/souffle/value_parser.ts --custom-header-file src/lib/souffle/value_header.ts --allowed-start-rules Value --cache src/lib/souffle/values.pegjs", "build-functors": "./scripts/build_functors.sh", - "build": "npm run clean && npm run gen-translation-modules && npm run build-parser && npm run transpile && chmod a+x dist/bin/cli.js && npm run copy-dl && npm run build-functors && npm run copy-functors", + "build": "npm run clean && npm run gen-translation-modules && npm run build-value-parser && npm run transpile && npm run build-parser && chmod a+x dist/bin/cli.js && npm run copy-dl && npm run build-functors && npm run copy-functors", "test": "c8 mocha", "lint": "eslint src/ test/ --ext=ts", "lint:fix": "eslint src/ test/ --ext=ts --fix", @@ -51,8 +52,7 @@ "prettier": "3.2.5", "ts-node": "^10.9.2", "typescript": "^5.3.3", - "peggy": "^2.0.1", - "ts-pegjs": "^3.1.0" + "jison": "^0.4.18" }, "repository": { "type": "git", diff --git a/src/lib/analyses/calltree.dl b/src/lib/analyses/calltree.dl index 7d09900..c6d1ed9 100644 --- a/src/lib/analyses/calltree.dl +++ b/src/lib/analyses/calltree.dl @@ -8,7 +8,7 @@ callsDirectly(caller, callee) :- ancestor(caller, callId). .type CallPath = [ head: FunctionDefinitionId, tail: CallPath ] -.functor isSubsequence(CallPath, CallPath):number stateful +.functor isSubsequence(a: CallPath, b: CallPath):number stateful .decl callsPath(caller: FunctionDefinitionId, callee: FunctionDefinitionId, path: CallPath) diff --git a/src/lib/souffle/fact.ts b/src/lib/souffle/fact.ts index b9cc0a3..255cbe2 100644 --- a/src/lib/souffle/fact.ts +++ b/src/lib/souffle/fact.ts @@ -1,27 +1,27 @@ import * as sol from "solc-typed-ast"; import { Relation } from "./relation"; -import { - DatalogRecordType, - DatalogSubtype, - DatalogType, - DatalogNumber, - DatalogSymbol -} from "./types"; +import { RecordT, SubT, DatalogType, NumberT, SymbolT, AliasT } from "./types"; import { ParsedFieldVal, parseValue } from "./value_parser"; import { zip } from "../utils"; export type FieldVal = string | number | bigint | { [field: string]: FieldVal } | null; +// TODO: A lot of functions with very similar structure. Code duplication probably here + function fieldValToJSON(val: FieldVal, typ: DatalogType): any { - if (typ === DatalogSymbol || typ == DatalogNumber) { + if (typ === SymbolT || typ == NumberT) { return val; } - if (typ instanceof DatalogSubtype) { - return fieldValToJSON(val, typ.baseType()); + if (typ instanceof SubT) { + return fieldValToJSON(val, typ.parentT); + } + + if (typ instanceof AliasT) { + return fieldValToJSON(val, typ.originalT); } - if (typ instanceof DatalogRecordType) { + if (typ instanceof RecordT) { if (val === null) { return null; } @@ -34,19 +34,23 @@ function fieldValToJSON(val: FieldVal, typ: DatalogType): any { } export function ppFieldVal(val: FieldVal, typ: DatalogType): string { - if (typ === DatalogSymbol) { + if (typ === SymbolT) { return val as string; } - if (typ === DatalogNumber) { + if (typ === NumberT) { return `${val as number | bigint}`; } - if (typ instanceof DatalogSubtype) { - return ppFieldVal(val, typ.baseType()); + if (typ instanceof SubT) { + return ppFieldVal(val, typ.parentT); } - if (typ instanceof DatalogRecordType) { + if (typ instanceof AliasT) { + return ppFieldVal(val, typ.originalT); + } + + if (typ instanceof RecordT) { if (val === null) { return `nil`; } @@ -59,7 +63,7 @@ export function ppFieldVal(val: FieldVal, typ: DatalogType): string { } export function translateVal(raw: ParsedFieldVal, typ: DatalogType): FieldVal { - if (typ === DatalogNumber) { + if (typ === NumberT) { sol.assert( typeof raw === "number", `Expected a number when translating a number, not {0}`, @@ -68,16 +72,20 @@ export function translateVal(raw: ParsedFieldVal, typ: DatalogType): FieldVal { return raw; } - if (typ === DatalogSymbol) { + if (typ === SymbolT) { sol.assert(typeof raw === "string", `Expected a string when translating a symbol`); return raw; } - if (typ instanceof DatalogSubtype) { - return translateVal(raw, typ.baseType()); + if (typ instanceof SubT) { + return translateVal(raw, typ.parentT); + } + + if (typ instanceof AliasT) { + return translateVal(raw, typ.originalT); } - if (typ instanceof DatalogRecordType) { + if (typ instanceof RecordT) { if (raw === null) { return null; } @@ -96,20 +104,24 @@ export function translateVal(raw: ParsedFieldVal, typ: DatalogType): FieldVal { } function parseFieldValFromCsv(val: any, typ: DatalogType): FieldVal { - if (typ === DatalogNumber) { + if (typ === NumberT) { sol.assert(typeof val === "number", `Expected a number`); return val; } - if (typ === DatalogSymbol) { + if (typ === SymbolT) { return String(val); } - if (typ instanceof DatalogSubtype) { - return parseFieldValFromCsv(val, typ.baseType()); + if (typ instanceof SubT) { + return parseFieldValFromCsv(val, typ.parentT); } - if (typ instanceof DatalogRecordType) { + if (typ instanceof AliasT) { + return parseFieldValFromCsv(val, typ.originalT); + } + + if (typ instanceof RecordT) { sol.assert(typeof val === "string", `Expected a string`); return translateVal(parseValue(val), typ); } @@ -118,21 +130,25 @@ function parseFieldValFromCsv(val: any, typ: DatalogType): FieldVal { } function parseFieldValFromSQL(val: any, typ: DatalogType): FieldVal { - if (typ === DatalogNumber) { + if (typ === NumberT) { sol.assert(typeof val === "number", `Expected a number`); return val; } - if (typ === DatalogSymbol) { + if (typ === SymbolT) { sol.assert(typeof val === "string", `Expected a string`); return val; } - if (typ instanceof DatalogSubtype) { - return parseFieldValFromCsv(val, typ.baseType()); + if (typ instanceof SubT) { + return parseFieldValFromCsv(val, typ.parentT); + } + + if (typ instanceof AliasT) { + return parseFieldValFromCsv(val, typ.originalT); } - if (typ instanceof DatalogRecordType) { + if (typ instanceof RecordT) { if (typeof val === "string") { return translateVal(parseValue(val), typ); } @@ -158,15 +174,11 @@ export class Fact { } static fromCSVRow(rel: Relation, cols: string[]): Fact { - const primitiveTypes = rel.fields.map(([, typ]) => - typ instanceof DatalogSubtype ? typ.baseType() : typ - ); - - sol.assert(cols.length === primitiveTypes.length, ``); + sol.assert(cols.length === rel.fields.length, ``); return new Fact( rel, - cols.map((val, idx) => parseFieldValFromCsv(val, primitiveTypes[idx])) + cols.map((val, idx) => parseFieldValFromCsv(val, rel.fields[idx][1])) ); } diff --git a/src/lib/souffle/instance.ts b/src/lib/souffle/instance.ts index a340f76..dd94c41 100644 --- a/src/lib/souffle/instance.ts +++ b/src/lib/souffle/instance.ts @@ -8,17 +8,11 @@ import { chunk, searchRecursive } from "../utils"; import { parse } from "csv-parse/sync"; import sqlite3 from "sqlite3"; import { open, Database } from "sqlite"; -import { - DatalogNumber, - DatalogRecordType, - DatalogSubtype, - DatalogSymbol, - DatalogType, - TypeEnv, - buildTypeEnv -} from "./types"; +import { NumberT, RecordT, SubT, SymbolT, DatalogType, TypeEnv, AliasT } from "./types"; import { Relation, getRelations } from "./relation"; import { Fact, FieldVal, ppFieldVal } from "./fact"; +import * as ast from "./ast"; +import { parseProgram } from "./parser"; export type SouffleOutputType = "csv" | "sqlite"; @@ -47,6 +41,7 @@ export abstract class SouffleInstance { protected env: TypeEnv; protected _relations: Map; protected soDir: string; + protected program: ast.Program; constructor( private readonly datalog: string, @@ -55,8 +50,9 @@ export abstract class SouffleInstance { ) { this.success = false; - this.env = buildTypeEnv(this.datalog); - this._relations = new Map(getRelations(this.datalog, this.env).map((r) => [r.name, r])); + this.program = parseProgram(this.datalog); + this.env = TypeEnv.buildTypeEnv(this.program); + this._relations = new Map(getRelations(this.program, this.env).map((r) => [r.name, r])); this.soDir = soDir ? soDir : DEFAULT_SO_DIR; } @@ -176,19 +172,23 @@ export class SouffleCSVInstance extends BaseSouffleCSVInstance implements Souffl } function datalogToSQLType(typ: DatalogType): string { - if (typ === DatalogNumber) { + if (typ === NumberT) { return "INTEGER"; } - if (typ === DatalogSymbol) { + if (typ === SymbolT) { return "TEXT"; } - if (typ instanceof DatalogSubtype) { - return datalogToSQLType(typ.baseType()); + if (typ instanceof SubT) { + return datalogToSQLType(typ.parentT); } - if (typ instanceof DatalogRecordType) { + if (typ instanceof AliasT) { + return datalogToSQLType(typ.originalT); + } + + if (typ instanceof RecordT) { return "TEXT"; } @@ -196,15 +196,19 @@ function datalogToSQLType(typ: DatalogType): string { } function fieldValToSQLVal(val: FieldVal, typ: DatalogType): string { - if (typ === DatalogNumber) { + if (typ === NumberT) { return ppFieldVal(val, typ); } - if (typ instanceof DatalogSubtype) { - return fieldValToSQLVal(val, typ.baseType()); + if (typ instanceof SubT) { + return fieldValToSQLVal(val, typ.parentT); + } + + if (typ instanceof AliasT) { + return fieldValToSQLVal(val, typ.originalT); } - if (typ === DatalogSymbol || typ instanceof DatalogRecordType) { + if (typ === SymbolT || typ instanceof RecordT) { return `"${ppFieldVal(val, typ)}"`; } diff --git a/src/lib/souffle/parser/souffle.jison b/src/lib/souffle/parser/souffle.jison index eb101bf..d03e580 100644 --- a/src/lib/souffle/parser/souffle.jison +++ b/src/lib/souffle/parser/souffle.jison @@ -461,7 +461,7 @@ qualified_name type_decl : TYPE IDENT SUBTYPE qualified_name { - $$ = new ast.SubsetType($2, $4, @$); + $$ = new ast.SubsetType($2, new ast.NamedType($4, @4), @$); } | TYPE IDENT EQUALS union_type_list { @@ -510,12 +510,12 @@ record_type_list union_type_list : qualified_name { - $$ = [$1]; + $$ = [new ast.NamedType($1, @1)]; } | union_type_list PIPE qualified_name { $$ = $1; - $$.push($3); + $$.push(new ast.NamedType($3, @3)); } ; diff --git a/src/lib/souffle/relation.ts b/src/lib/souffle/relation.ts index e447103..bbe8ca9 100644 --- a/src/lib/souffle/relation.ts +++ b/src/lib/souffle/relation.ts @@ -1,6 +1,5 @@ -import { DatalogType, TypeEnv, mustLookupType } from "./types"; - -const declRX = /\.decl *([a-zA-Z0-9_]*) *\(([^)]*)\)/g; +import { DatalogType, TypeEnv } from "./types"; +import * as ast from "./ast"; export class Relation { constructor( @@ -9,21 +8,21 @@ export class Relation { ) {} } -export function getRelations(dl: string, env: TypeEnv): Relation[] { +export function getRelations(prog: ast.Program, env: TypeEnv): Relation[] { const res: Relation[] = []; - for (const m of dl.matchAll(declRX)) { - const name = m[1]; - const args = ( - m[2] - .split(",") - .map((x) => x.trim()) - .map((x) => x.split(":")) as Array<[string, string]> - ).map(([name, rawT]) => [name.trim(), mustLookupType(rawT.trim(), env)]) as Array< - [string, DatalogType] - >; - - res.push(new Relation(name, args)); + for (const d of prog) { + if (d instanceof ast.Relation) { + res.push( + new Relation( + d.name, + d.args.map(([name, typ]) => [ + name, + env.mustLookupType((typ as ast.NamedType).name) + ]) + ) + ); + } } return res; diff --git a/src/lib/souffle/types.ts b/src/lib/souffle/types.ts index 3539fc8..9805be2 100644 --- a/src/lib/souffle/types.ts +++ b/src/lib/souffle/types.ts @@ -1,89 +1,132 @@ import * as sol from "solc-typed-ast"; +import * as ast from "./ast"; -export type TypeEnv = Map; +// In-memory representation of Datalog types. +// Unlike the AST nodes DatalogType objects may be +// recursive for recusrively defined types. export abstract class DatalogType { constructor(public readonly name: string) {} } -class DatalogPrimitiveType extends DatalogType {} +class PrimitiveT extends DatalogType {} +export class NamedT extends DatalogType {} -export const DatalogNumber = new DatalogPrimitiveType("number"); -export const DatalogSymbol = new DatalogPrimitiveType("symbol"); +export const NumberT = new PrimitiveT("number"); +export const UnsignedT = new PrimitiveT("unsigned"); +export const SymbolT = new PrimitiveT("symbol"); +export const FloatT = new PrimitiveT("float"); -const subtypeDeclRx = /.type *([a-zA-Z0-9_]*) *<: *([a-zA-Z0-9_]*)/g; -const recordTypeDeclRx = /.type *([a-zA-Z0-9_]*) *= *\[([^\]]*)\]/g; - -export function lookupType(name: string, env: TypeEnv): DatalogType | undefined { - if (name === "number") { - return DatalogNumber; - } - - if (name === "symbol") { - return DatalogSymbol; +export class AliasT extends DatalogType { + constructor( + name: string, + public readonly originalT: DatalogType + ) { + super(name); } - - return env.get(name); } -export function mustLookupType(name: string, env: TypeEnv): DatalogType { - const res = lookupType(name, env); - sol.assert(res !== undefined, `Unexpected missing type ${name}.`); - return res; -} - -export function buildTypeEnv(dl: string): TypeEnv { - const env: TypeEnv = new Map(); - - for (const m of dl.matchAll(subtypeDeclRx)) { - const name = m[1]; - const parentT = lookupType(m[2], env); - - sol.assert(parentT !== undefined, ``); - - env.set(name, new DatalogSubtype(name, parentT)); - } - - for (const m of dl.matchAll(recordTypeDeclRx)) { - const name = m[1]; - const fields: Array<[string, string]> = m[2].split(",").map((x) => - x - .trim() - .split(":") - .map((y) => y.trim()) - ) as Array<[string, string]>; - - const newT = new DatalogRecordType(name, []); - // First register as record types are recursive - env.set(name, newT); - - newT.fields = fields.map(([name, typ]) => [name, lookupType(typ, env) as DatalogType]); +export class UnionT extends DatalogType { + constructor( + name: string, + public readonly optionTs: DatalogType[] + ) { + super(name); } - - return env; } -export class DatalogSubtype extends DatalogType { +export class SubT extends DatalogType { constructor( name: string, public readonly parentT: DatalogType ) { super(name); } +} - baseType(): DatalogType { - let t: DatalogType = this; - while (t instanceof DatalogSubtype) { - t = t.parentT; - } - - return t; +export class RecordT extends DatalogType { + constructor( + name: string, + public fields: Array<[string, DatalogType]> + ) { + super(name); } } -export class DatalogRecordType extends DatalogType { +export class ADTT extends DatalogType { constructor( name: string, - public fields: Array<[string, DatalogType]> + public branches: Array<[string, Array<[string, DatalogType]>]> ) { super(name); } } + +export class TypeEnv { + private env: Map = new Map(); + + private constructor() {} + + lookupType(name: string): DatalogType | undefined { + return this.env.get(name); + } + + mustLookupType(name: string): DatalogType { + const res = this.lookupType(name); + sol.assert(res !== undefined, `Unexpected missing type ${name}.`); + return res; + } + + static buildTypeEnv(prog: ast.Program): TypeEnv { + const res = new TypeEnv(); + + // Builtin Types + res.env.set("number", NumberT); + res.env.set("unsigned", UnsignedT); + res.env.set("float", FloatT); + res.env.set("symbol", SymbolT); + + for (const d of prog) { + if (d instanceof ast.SubsetType) { + res.env.set( + d.name, + new SubT(d.name, res.mustLookupType((d.originalType as ast.NamedType).name)) + ); + } else if (d instanceof ast.AliasType) { + res.env.set( + d.name, + new AliasT(d.name, res.mustLookupType((d.originalType as ast.NamedType).name)) + ); + } else if (d instanceof ast.UnionType) { + res.env.set( + d.name, + new UnionT( + d.name, + d.types.map((t) => res.mustLookupType((t as ast.NamedType).name)) + ) + ); + } else if (d instanceof ast.RecordType) { + // Since record/adt types can be recursive we first register the type, then set fields + const t = new RecordT(d.name, []); + res.env.set(d.name, t); + + t.fields = d.fields.map(([name, typ]) => [ + name, + res.mustLookupType((typ as ast.NamedType).name) + ]); + } else if (d instanceof ast.AlgebraicDataType) { + // Since record/adt types can be recursive we first register the type, then set fields + const t = new ADTT(d.name, []); + res.env.set(d.name, t); + + t.branches = d.branches.map(([branch, fields]) => [ + branch, + fields.map(([name, typ]) => [ + name, + res.mustLookupType((typ as ast.NamedType).name) + ]) + ]); + } + } + + return res; + } +} From 239d19744523e5e37f8d21757611c9b541a48bef Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Sat, 2 Mar 2024 02:29:09 +0200 Subject: [PATCH 07/10] forgot a file --- src/lib/souffle/parser/parser.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/lib/souffle/parser/parser.ts diff --git a/src/lib/souffle/parser/parser.ts b/src/lib/souffle/parser/parser.ts new file mode 100644 index 0000000..a9d48dc --- /dev/null +++ b/src/lib/souffle/parser/parser.ts @@ -0,0 +1,8 @@ +import { Program } from "../ast"; + +const Parser = (require("./souffle_parser_gen") as any).Parser; +const parser = new Parser(); + +export function parseProgram(s: string): Program { + return parser.parse(s); +} From 457acd24fb6c5b5a5bcc2f6b100b569138066180 Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Fri, 8 Mar 2024 07:58:38 +0200 Subject: [PATCH 08/10] Replace value_parser with JISON parser --- .gitignore | 1 + package.json | 4 +- src/lib/souffle/fact.ts | 136 +++-- src/lib/souffle/index.ts | 1 - src/lib/souffle/parser/index.ts | 2 +- src/lib/souffle/parser/parser.ts | 8 - src/lib/souffle/parser/parsers.ts | 14 + src/lib/souffle/parser/souffle_value.jison | 643 +++++++++++++++++++++ 8 files changed, 748 insertions(+), 61 deletions(-) delete mode 100644 src/lib/souffle/parser/parser.ts create mode 100644 src/lib/souffle/parser/parsers.ts create mode 100644 src/lib/souffle/parser/souffle_value.jison diff --git a/.gitignore b/.gitignore index 7cef8e0..ceb5f6f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,6 @@ src/gen/translate.ts src/gen/declarations.ts src/lib/souffle/value_parser.ts src/lib/souffle/parser/souffle_parser_gen.js +src/lib/souffle/parser/souffle_value_parser_gen.js functors/functors.o functors/libfunctors.so diff --git a/package.json b/package.json index 104650c..e2aee9c 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "copy-dl": "cp -r src/lib/analyses dist/lib && cp -r src/lib/detectors dist/lib", "copy-functors": "cp -r functors dist/", "build-parser": "jison src/lib/souffle/parser/souffle.jison -o src/lib/souffle/parser/souffle_parser_gen.js -m commonjs && cp src/lib/souffle/parser/souffle_parser_gen.js dist/lib/souffle/parser/souffle_parser_gen.js", + "build-expr-parser": "jison src/lib/souffle/parser/souffle_value.jison -o src/lib/souffle/parser/souffle_value_parser_gen.js -m commonjs && cp src/lib/souffle/parser/souffle_value_parser_gen.js dist/lib/souffle/parser/souffle_value_parser_gen.js", "build-value-parser": "tspegjs -o src/lib/souffle/value_parser.ts --custom-header-file src/lib/souffle/value_header.ts --allowed-start-rules Value --cache src/lib/souffle/values.pegjs", + "build-parsers": "npm run build-parser && npm run build-expr-parser", "build-functors": "./scripts/build_functors.sh", - "build": "npm run clean && npm run gen-translation-modules && npm run build-value-parser && npm run transpile && npm run build-parser && chmod a+x dist/bin/cli.js && npm run copy-dl && npm run build-functors && npm run copy-functors", + "build": "npm run clean && npm run gen-translation-modules && npm run build-value-parser && npm run transpile && npm run build-parsers && chmod a+x dist/bin/cli.js && npm run copy-dl && npm run build-functors && npm run copy-functors", "test": "c8 mocha", "lint": "eslint src/ test/ --ext=ts", "lint:fix": "eslint src/ test/ --ext=ts --fix", diff --git a/src/lib/souffle/fact.ts b/src/lib/souffle/fact.ts index 255cbe2..66b9e5a 100644 --- a/src/lib/souffle/fact.ts +++ b/src/lib/souffle/fact.ts @@ -1,18 +1,95 @@ import * as sol from "solc-typed-ast"; import { Relation } from "./relation"; -import { RecordT, SubT, DatalogType, NumberT, SymbolT, AliasT } from "./types"; -import { ParsedFieldVal, parseValue } from "./value_parser"; -import { zip } from "../utils"; +import { RecordT, SubT, DatalogType, NumberT, SymbolT, AliasT, ADTT } from "./types"; +import { parseExpression } from "./parser"; +import * as ast from "./ast"; + +function getBranch(typ: ADTT, branch: string): [string, Array<[string, DatalogType]>] { + const filtered = typ.branches.filter(([name]) => name === branch); + sol.assert( + filtered.length === 1, + `Couldn't find branch hamed {0} in ADT {1}`, + branch, + typ.name + ); + + return filtered[0]; +} + +/** + * Convert a literal Expression AST to a FieldVal. + */ +function literalExprToVal(expr: ast.Expression, typ: DatalogType): FieldVal { + if (expr instanceof ast.Num) { + return expr.value; + } + + if (expr instanceof ast.StringLiteral) { + return expr.value; + } + + if (expr instanceof ast.Nil) { + sol.assert(typ instanceof RecordT, ``); + return null; + } -export type FieldVal = string | number | bigint | { [field: string]: FieldVal } | null; + if (expr instanceof ast.RecordLiteral) { + sol.assert(typ instanceof RecordT, ``); + sol.assert(typ.fields.length === expr.args.length, ``); + + return Object.fromEntries( + expr.args.map((_, i) => [ + typ.fields[i][0], + literalExprToVal(expr.args[i], typ.fields[i][1]) + ]) + ); + } + + if (expr instanceof ast.ADTLiteral) { + sol.assert(typ instanceof ADTT, ``); + const branchT = getBranch(typ, expr.branch); + + return [ + expr.branch, + Object.fromEntries( + expr.args.map((_, i) => [ + branchT[1][i][0], + literalExprToVal(expr.args[i], branchT[1][i][1]) + ]) + ) + ]; + } + + throw new Error(`NYI translating ${expr.pp()} of type ${typ.name} to FieldVal`); +} + +export function parseValueInt(source: string, typ: DatalogType): FieldVal { + return literalExprToVal(parseExpression(source), typ); +} + +export type RecordVal = { [field: string]: FieldVal }; +export type ADTVal = [string, RecordVal]; +export type FieldVal = string | bigint | number | RecordVal | ADTVal | null; + +function isADT(v: FieldVal): v is ADTVal { + return v instanceof Array; +} + +function isRecord(v: FieldVal): v is RecordVal { + return v instanceof Object && !isADT(v); +} // TODO: A lot of functions with very similar structure. Code duplication probably here function fieldValToJSON(val: FieldVal, typ: DatalogType): any { - if (typ === SymbolT || typ == NumberT) { + if (typ === SymbolT) { return val; } + if (typ == NumberT) { + return Number(val); + } + if (typ instanceof SubT) { return fieldValToJSON(val, typ.parentT); } @@ -26,7 +103,7 @@ function fieldValToJSON(val: FieldVal, typ: DatalogType): any { return null; } - sol.assert(val instanceof Object, `Expected an object in fieldValToJSON, not ${val}`); + sol.assert(isRecord(val), `Expected a Record in fieldValToJSON, not ${val}`); return typ.fields.map(([name, fieldT]) => fieldValToJSON(val[name], fieldT)); } @@ -55,54 +132,13 @@ export function ppFieldVal(val: FieldVal, typ: DatalogType): string { return `nil`; } - sol.assert(val instanceof Object, `Expected an object in ppFieldVal`); + sol.assert(isRecord(val), `Expected an object in ppFieldVal`); return `[${typ.fields.map(([name, fieldT]) => ppFieldVal(val[name], fieldT)).join(", ")}]`; } throw new Error(`NYI type ${typ.name}`); } -export function translateVal(raw: ParsedFieldVal, typ: DatalogType): FieldVal { - if (typ === NumberT) { - sol.assert( - typeof raw === "number", - `Expected a number when translating a number, not {0}`, - typeof raw - ); - return raw; - } - - if (typ === SymbolT) { - sol.assert(typeof raw === "string", `Expected a string when translating a symbol`); - return raw; - } - - if (typ instanceof SubT) { - return translateVal(raw, typ.parentT); - } - - if (typ instanceof AliasT) { - return translateVal(raw, typ.originalT); - } - - if (typ instanceof RecordT) { - if (raw === null) { - return null; - } - - sol.assert(raw instanceof Array && raw.length === typ.fields.length, ``); - - return Object.fromEntries( - zip( - typ.fields.map((x) => x[0]), - raw.map((x, i) => translateVal(x, typ.fields[i][1])) - ) - ); - } - - throw new Error(`NYI type ${typ.name}`); -} - function parseFieldValFromCsv(val: any, typ: DatalogType): FieldVal { if (typ === NumberT) { sol.assert(typeof val === "number", `Expected a number`); @@ -123,7 +159,7 @@ function parseFieldValFromCsv(val: any, typ: DatalogType): FieldVal { if (typ instanceof RecordT) { sol.assert(typeof val === "string", `Expected a string`); - return translateVal(parseValue(val), typ); + return parseValueInt(val, typ); } throw new Error(`NYI datalog type ${typ}`); @@ -150,7 +186,7 @@ function parseFieldValFromSQL(val: any, typ: DatalogType): FieldVal { if (typ instanceof RecordT) { if (typeof val === "string") { - return translateVal(parseValue(val), typ); + return parseValueInt(val, typ); } throw new Error(`NYI parsing record types from ${val}`); diff --git a/src/lib/souffle/index.ts b/src/lib/souffle/index.ts index 51342ca..2fd0995 100644 --- a/src/lib/souffle/index.ts +++ b/src/lib/souffle/index.ts @@ -2,4 +2,3 @@ export * from "./instance"; export * from "./souffle"; export * from "./types"; export * from "./relation"; -export { parseValue } from "./value_parser"; diff --git a/src/lib/souffle/parser/index.ts b/src/lib/souffle/parser/index.ts index 5c58fd8..c75bcc9 100644 --- a/src/lib/souffle/parser/index.ts +++ b/src/lib/souffle/parser/index.ts @@ -1 +1 @@ -export * from "./parser"; +export * from "./parsers"; diff --git a/src/lib/souffle/parser/parser.ts b/src/lib/souffle/parser/parser.ts deleted file mode 100644 index a9d48dc..0000000 --- a/src/lib/souffle/parser/parser.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Program } from "../ast"; - -const Parser = (require("./souffle_parser_gen") as any).Parser; -const parser = new Parser(); - -export function parseProgram(s: string): Program { - return parser.parse(s); -} diff --git a/src/lib/souffle/parser/parsers.ts b/src/lib/souffle/parser/parsers.ts new file mode 100644 index 0000000..57e0392 --- /dev/null +++ b/src/lib/souffle/parser/parsers.ts @@ -0,0 +1,14 @@ +import * as ast from "../ast"; + +const ProgramParser = (require("./souffle_parser_gen") as any).Parser; +const ExprParser = (require("./souffle_value_parser_gen") as any).Parser; +const programParser = new ProgramParser(); +const exprParser = new ExprParser(); + +export function parseProgram(s: string): ast.Program { + return programParser.parse(s); +} + +export function parseExpression(s: string): ast.Expression { + return exprParser.parse(s); +} diff --git a/src/lib/souffle/parser/souffle_value.jison b/src/lib/souffle/parser/souffle_value.jison new file mode 100644 index 0000000..191fe0e --- /dev/null +++ b/src/lib/souffle/parser/souffle_value.jison @@ -0,0 +1,643 @@ +%{ +/* tslint:disable */ + +const ast = require("../ast"); + +function lexError(err) { + throw new Error(err); +} + +function lexNYI(token) { + lexError(`Lexer NYI "${token}"`) +} + +function parseError(err) { + throw new Error(err); +} + +function parseNYI(token) { + lexError(`Parser NYI "${token}"`) +} +%} + +%lex +%x INCLUDE_TOK COMMENT_TOK +%% + +// Skip whitespace and comments +"//".*\n {} +"/*" this.begin("COMMENT_TOK"); +"*/" this.begin("INITIAL_TOK"); +[^*\n]+ {} +"*" {} +\n {} +<> lexError('Unterminated comment'); +{WS}+ {} +\"(\\.|[^"\\])*\" this.begin("INITIAL"); +. lexError(`Unexpected ${yytext} in include`); +\s+ {} +".decl" return "DECL_TOK" +".functor" return "FUNCTOR_TOK" +".input" return "INPUT_DECL_TOK" +".output" return "OUTPUT_DECL_TOK" +".printsize" return "PRINTSIZE_DECL_TOK" +".limitsize" return "LIMITSIZE_DECL_TOK" +".type" return "TYPE_TOK" +".comp" return "COMPONENT_TOK" +".init" return "INSTANTIATE_TOK" +".number_type" return "NUMBER_TYPE_TOK" +".symbol_type" return "SYMBOL_TYPE_TOK" +".override" return "OVERRIDE_TOK" +".pragma" return "PRAGMA_TOK" +".plan" return "PLAN_TOK" +".lattice" return "LATTICE_TOK" +".include" yy.LastIncludeDirectiveLoc = yylloc; this.begin("INCLUDE_TOK"); +".once" lexNYI(yytext); +"debug_delta" return "DEBUG_DELTA_TOK" +"autoinc" return "AUTOINC_TOK" +"band" return "BW_AND_TOK" +"bor" return "BW_OR_TOK" +"bxor" return "BW_XOR_TOK" +"bnot" return "BW_NOT_TOK" +"bshl" return "BW_SHIFT_L_TOK" +"bshr" return "BW_SHIFT_R_TOK" +"bshru" return "BW_SHIFT_R_UNSIGNED_TOK" +"lan" return "L_AND_TOK" +"lor" return "L_OR_TOK" +"lxor" return "L_XOR_TOK" +"lnot" return "L_NOT_TOK" +"match" return "TMATCH_TOK" +"mean" return "MEAN_TOK" +"cat" return "CAT_TOK" +"ord" return "ORD_TOK" +"fold" return "FOLD_TOK" +"range" return "RANGE_TOK" +"strlen" return "STRLEN_TOK" +"substr" return "SUBSTR_TOK" +"stateful" return "STATEFUL_TOK" +"contains" return "TCONTAINS_TOK" +"output" return "OUTPUT_QUALIFIER_TOK" +"input" return "INPUT_QUALIFIER_TOK" +"overridable" return "OVERRIDABLE_QUALIFIER_TOK" +"printsize" return "PRINTSIZE_QUALIFIER_TOK" +"eqrel" return "EQREL_QUALIFIER_TOK" +"inline" return "INLINE_QUALIFIER_TOK" +"no_inline" return "NO_INLINE_QUALIFIER_TOK" +"magic" return "MAGIC_QUALIFIER_TOK" +"no_magic" return "NO_MAGIC_QUALIFIER_TOK" +"brie" return "BRIE_QUALIFIER_TOK" +"btree_delete" return "BTREE_DELETE_QUALIFIER_TOK" +"btree" return "BTREE_QUALIFIER_TOK" +"min" return "MIN_TOK" +"max" return "MAX_TOK" +"as" return "AS_TOK" +"nil" return "NIL_TOK" +"_" return "UNDERSCORE_TOK" +"count" return "COUNT_TOK" +"sum" return "SUM_TOK" +"true" return "TRUELIT_TOK" +"false" return "FALSELIT_TOK" +"to_float" return "TOFLOAT_TOK" +"to_number" return "TONUMBER_TOK" +"to_string" return "TOSTRING_TOK" +"to_unsigned" return "TOUNSIGNED_TOK" +"choice-domain" return "CHOICEDOMAIN_TOK" +"recursive_iteration_cnt" return "ITERATION_TOK" +"__FILE__" lexNYI(yytext); +"__LINE__" lexNYI(yytext); +"__INCL__" lexNYI(yytext); +"|" return "PIPE_TOK" +"[" return "LBRACKET_TOK" +"]" return "RBRACKET_TOK" +"$" return "DOLLAR_TOK" +"+" return "PLUS_TOK" +"->" return "MAPSTO_TOK" +"-" return "MINUS_TOK" +"(" return "LPAREN_TOK" +")" return "RPAREN_TOK" +"," return "COMMA_TOK" +":-" return "IF_TOK" +":" return "COLON_TOK" +";" return "SEMICOLON_TOK" +"." return "DOT_TOK" +"<:" return "SUBTYPE_TOK" +"<=" return "LE_TOK" +">=" return "GE_TOK" +"!=" return "NE_TOK" +"=" return "EQUALS_TOK" +"!" return "EXCLAMATION_TOK" +"*" return "STAR_TOK" +"@" return "AT_TOK" +"/" return "SLASH_TOK" +"^" return "CARET_TOK" +"%" return "PERCENT_TOK" +"{" return "LBRACE_TOK" +"}" return "RBRACE_TOK" +"<" return "LT_TOK" +">" return "GT_TOK" +[0-9]+"."[0-9]+"."[0-9]+"."[0-9]+ lexNYI(yytext); +[0-9]+[.][0-9]+ return "FLOAT_TOK" +[0-9]+ return "NUMBER_TOK" +0b[0-1]+ return "NUMBER_TOK" +0x[a-fA-F0-9]+ return "NUMBER_TOK" +[0-9]+u return "UNSIGNED_TOK" +0b[0-1]+u return "UNSIGNED_TOK" +0x[a-fA-F0-9]+u return "UNSIGNED_TOK" +[_\?a-zA-Z][_\?a-zA-Z0-9]* return "IDENT_TOK"; +\"(\\.|[^"\\])*\" return "STRING_TOK"; +\#.*$ lexNYI(yytext); +<> {} +. lexError(`Unexpected token "${yytext}"`); + +/lex + +%token "END_TOK" 0 "end of file" +%token "STRING_TOK" "symbol" +%token "IDENT_TOK" "identifier" +%token "NUMBER_TOK" "number" +%token "UNSIGNED_TOK" "unsigned number" +%token "FLOAT_TOK" "float" +%token "AUTOINC_TOK" "auto-increment functor" +%token "PRAGMA_TOK" "pragma directive" +%token "OUTPUT_QUALIFIER_TOK" "relation qualifier output" +%token "INPUT_QUALIFIER_TOK" "relation qualifier input" +%token "PRINTSIZE_QUALIFIER_TOK" "relation qualifier printsize" +%token "BRIE_QUALIFIER_TOK" "BRIE datastructure qualifier" +%token "BTREE_QUALIFIER_TOK" "BTREE datastructure qualifier" +%token "BTREE_DELETE_QUALIFIER_TOK" "BTREE_DELETE datastructure qualifier" +%token "EQREL_QUALIFIER_TOK" "equivalence relation qualifier" +%token "OVERRIDABLE_QUALIFIER_TOK" "relation qualifier overidable" +%token "INLINE_QUALIFIER_TOK" "relation qualifier inline" +%token "NO_INLINE_QUALIFIER_TOK" "relation qualifier no_inline" +%token "MAGIC_QUALIFIER_TOK" "relation qualifier magic" +%token "NO_MAGIC_QUALIFIER_TOK" "relation qualifier no_magic" +%token "TMATCH_TOK" "match predicate" +%token "TCONTAINS_TOK" "checks whether substring is contained in a string" +%token "STATEFUL_TOK" "stateful functor" +%token "CAT_TOK" "concatenation of strings" +%token "ORD_TOK" "ordinal number of a string" +%token "RANGE_TOK" "range" +%token "STRLEN_TOK" "length of a string" +%token "SUBSTR_TOK" "sub-string of a string" +%token "MEAN_TOK" "mean aggregator" +%token "MIN_TOK" "min aggregator" +%token "MAX_TOK" "max aggregator" +%token "COUNT_TOK" "count aggregator" +%token "SUM_TOK" "sum aggregator" +%token "TRUELIT_TOK" "true literal constraint" +%token "FALSELIT_TOK" "false literal constraint" +%token "PLAN_TOK" "plan keyword" +%token "ITERATION_TOK" "recursive iteration keyword" +%token "CHOICEDOMAIN_TOK" "choice-domain" +%token "IF_TOK" ":-" +%token "DECL_TOK" "relation declaration" +%token "FUNCTOR_TOK" "functor declaration" +%token "INPUT_DECL_TOK" "input directives declaration" +%token "OUTPUT_DECL_TOK" "output directives declaration" +%token "DEBUG_DELTA_TOK" "debug_delta" +%token "UNIQUE_TOK" "unique" +%token "PRINTSIZE_DECL_TOK" "printsize directives declaration" +%token "LIMITSIZE_DECL_TOK" "limitsize directives declaration" +%token "OVERRIDE_TOK" "override rules of super-component" +%token "TYPE_TOK" "type declaration" +%token "LATTICE_TOK" "lattice declaration" +%token "COMPONENT_TOK" "component declaration" +%token "INSTANTIATE_TOK" "component instantiation" +%token "NUMBER_TYPE_TOK" "numeric type declaration" +%token "SYMBOL_TYPE_TOK" "symbolic type declaration" +%token "TOFLOAT_TOK" "convert to float" +%token "TONUMBER_TOK" "convert to signed integer" +%token "TOSTRING_TOK" "convert to string" +%token "TOUNSIGNED_TOK" "convert to unsigned integer" +%token "ITOU_TOK" "convert int to unsigned" +%token "ITOF_TOK" "convert int to float" +%token "UTOI_TOK" "convert unsigned to int" +%token "UTOF_TOK" "convert unsigned to float" +%token "FTOI_TOK" "convert float to int" +%token "FTOU_TOK" "convert float to unsigned" +%token "AS_TOK" "type cast" +%token "AT_TOK" "@" +%token "NIL_TOK" "nil reference" +%token "PIPE_TOK" "|" +%token "LBRACKET_TOK" "[" +%token "RBRACKET_TOK" "]" +%token "UNDERSCORE_TOK" "_" +%token "DOLLAR_TOK" "$" +%token "EXCLAMATION_TOK" "!" +%token "LPAREN_TOK" "(" +%token "RPAREN_TOK" ")" +%token "COMMA_TOK" "," +%token "COLON_TOK" ":" +%token "DOUBLECOLON_TOK" "::" +%token "SEMICOLON_TOK" ";" +%token "DOT_TOK" "." +%token "EQUALS_TOK" "=" +%token "LBRACE_TOK" "{" +%token "RBRACE_TOK" "}" +%token "SUBTYPE_TOK" "<:" +%token "LT_TOK" "<" +%token "GT_TOK" ">" +%token "LE_TOK" "<=" +%token "GE_TOK" ">=" +%token "NE_TOK" "!=" +%token "MAPSTO_TOK" "->" +%token "FOLD_TOK" "fold" + +/* -- Operator precedence -- */ +%left "L_OR_TOK" +%left "L_XOR_TOK" +%left "L_AND_TOK" +%left "BW_OR_TOK" +%left "BW_XOR_TOK" +%left "BW_AND_TOK" +%left "BW_SHIFT_L_TOK" "BW_SHIFT_R_TOK" "BW_SHIFT_R_UNSIGNED_TOK" +%left "PLUS_TOK" "MINUS_TOK" +%left "STAR_TOK" "SLASH_TOK" "PERCENT_TOK" +%nonassoc "NEG_TOK" "BW_NOT_TOK" "L_NOT_TOK" +%right "CARET_TOK" + +%start value + +%% + +/** + * Terminal symbols + */ + +value + : arg + { + return $1; + } + ; + +NUMBER_TYPE: "NUMBER_TYPE_TOK"; +SYMBOL_TYPE: "SYMBOL_TYPE_TOK"; +AUTOINC: "AUTOINC_TOK"; +TMATCH: "TMATCH_TOK"; +MEAN: "MEAN_TOK"; +CAT: "CAT_TOK"; +ORD: "ORD_TOK"; +FOLD: "FOLD_TOK"; +RANGE: "RANGE_TOK"; +STRLEN: "STRLEN_TOK"; +SUBSTR: "SUBSTR_TOK"; +STATEFUL: "STATEFUL_TOK"; +TCONTAINS: "TCONTAINS_TOK"; +OUTPUT_QUALIFIER: "OUTPUT_QUALIFIER_TOK"; +INPUT_QUALIFIER: "INPUT_QUALIFIER_TOK"; +OVERRIDABLE_QUALIFIER: "OVERRIDABLE_QUALIFIER_TOK"; +PRINTSIZE_QUALIFIER: "PRINTSIZE_QUALIFIER_TOK"; +EQREL_QUALIFIER: "EQREL_QUALIFIER_TOK"; +INLINE_QUALIFIER: "INLINE_QUALIFIER_TOK"; +NO_INLINE_QUALIFIER: "NO_INLINE_QUALIFIER_TOK"; +MAGIC_QUALIFIER: "MAGIC_QUALIFIER_TOK"; +NO_MAGIC_QUALIFIER: "NO_MAGIC_QUALIFIER_TOK"; +BRIE_QUALIFIER: "BRIE_QUALIFIER_TOK"; +BTREE_DELETE_QUALIFIER: "BTREE_DELETE_QUALIFIER_TOK"; +BTREE_QUALIFIER: "BTREE_QUALIFIER_TOK"; +MIN: "MIN_TOK"; +MAX: "MAX_TOK"; +AS: "AS_TOK"; +NIL: "NIL_TOK"; +UNDERSCORE: "UNDERSCORE_TOK"; +COUNT: "COUNT_TOK"; +SUM: "SUM_TOK"; +TRUELIT: "TRUELIT_TOK"; +FALSELIT: "FALSELIT_TOK"; +TOFLOAT: "TOFLOAT_TOK"; +TONUMBER: "TONUMBER_TOK"; +TOSTRING: "TOSTRING_TOK"; +TOUNSIGNED: "TOUNSIGNED_TOK"; +CHOICEDOMAIN: "CHOICEDOMAIN_TOK"; +ITERATION: "ITERATION_TOK"; +PIPE: "PIPE_TOK"; +LBRACKET: "LBRACKET_TOK"; +RBRACKET: "RBRACKET_TOK"; +DOLLAR: "DOLLAR_TOK"; +MAPSTO: "MAPSTO_TOK"; +LPAREN: "LPAREN_TOK"; +RPAREN: "RPAREN_TOK"; +COMMA: "COMMA_TOK"; +COLON: "COLON_TOK"; +SEMICOLON: "SEMICOLON_TOK"; +SUBTYPE: "SUBTYPE_TOK"; +LE: "LE_TOK"; +GE: "GE_TOK"; +NE: "NE_TOK"; +EQUALS: "EQUALS_TOK"; +AT: "AT_TOK"; +LBRACE: "LBRACE_TOK"; +RBRACE: "RBRACE_TOK"; +LT: "LT_TOK"; +GT: "GT_TOK"; +IF: "IF_TOK"; +END: "END_TOK"; +FLOAT + : "FLOAT_TOK" + { + $$ = Number(yytext); + } + ; +NUMBER + : "NUMBER_TOK" + { + $$ = BigInt(yytext); + } + ; +UNSIGNED + : "UNSIGNED_TOK" + { + $$ = BigInt(yytext.slice(0, -1)); + } + ; +STRING + : "STRING_TOK" + { + $$ = yytext; + } + ; +IDENT + : "IDENT_TOK" + { + $$ = yytext; + } + ; + +/** + * A Qualified Name + */ + +qualified_name + : IDENT + { + $$ = $1; + } + | qualified_name DOT_TOK IDENT + { + $$ = $1 + "." + $3; + } + ; + + +/** + * Argument List + */ +arg_list + : %empty + { + $$ = []; + } + | non_empty_arg_list + { + $$ = $1; + } ; + +non_empty_arg_list + : arg + { + $$ = [$1]; + } + | non_empty_arg_list COMMA arg + { + $$ = $1; $$.push($3); + } + ; + + +/** + * Atom argument + */ +arg + : STRING + { + $$ = new ast.StringLiteral($1.slice(1, -1), @$); + } + | FLOAT + { + $$ = new ast.Float($1, @$); + } + | UNSIGNED + { + $$ = new ast.Unsigned($1, @$); + } + | NUMBER + { + $$ = new ast.Num($1, @$); + } + | ITERATION LPAREN RPAREN + { + parseNYI(`Iteration: ${yytext}`); + } + | UNDERSCORE + { + $$ = new ast.UnnamedVar(@$); + } + | DOLLAR + { + $$ = new ast.AutoIncrement(@$); + } + | AUTOINC LPAREN RPAREN + { + $$ = new ast.AutoIncrement(@$); + } + | IDENT + { + $$ = new ast.Identifier($1, @$); + } + | NIL + { + $$ = new ast.Nil(@$); + } + | LBRACKET arg_list RBRACKET + { + $$ = new ast.RecordLiteral($2, @$); + } + | DOLLAR qualified_name LPAREN arg_list RPAREN + { + $$ = new ast.ADTLiteral($2, $4, @$); + } + | LPAREN arg RPAREN + { + $$ = $2; + } + | AS LPAREN arg COMMA qualified_name RPAREN + { + $$ = new ast.TypeCast($3, new ast.NamedType($5), @$); + } + | AT IDENT LPAREN arg_list RPAREN + { + $$ = new ast.FunctorCall($2, $4, false, @$); + } + | functor_built_in LPAREN arg_list RPAREN + { + $$ = new ast.FunctorCall($1, $3, true, @$); + } + + /* some aggregates have the same name as functors */ + | aggregate_func LPAREN arg[first] COMMA non_empty_arg_list[rest] RPAREN + { + parseNYI(`Aggregators ${yytext}`) + } + + /* -- intrinsic functor -- */ + /* unary functors */ + | MINUS_TOK arg %prec NEG_TOK + { + $$ = new ast.UnaryOperator("-", $2, @$); + } + | BW_NOT_TOK arg + { + $$ = new ast.UnaryOperator("~", $2, @$); + } + | L_NOT_TOK arg + { + $$ = new ast.UnaryOperator("!", $2, @$); + } + + /* binary infix functors */ + | arg PLUS_TOK arg + { + $$ = new ast.BinaryOperator($1, "+", $3, @$); + } + | arg MINUS_TOK arg + { + $$ = new ast.BinaryOperator($1, "-", $3, @$); + } + | arg STAR_TOK arg + { + $$ = new ast.BinaryOperator($1, "*", $3, @$); + } + | arg SLASH_TOK arg + { + $$ = new ast.BinaryOperator($1, "/", $3, @$); + } + | arg PERCENT_TOK arg + { + $$ = new ast.BinaryOperator($1, "%", $3, @$); + } + | arg CARET_TOK arg + { + $$ = new ast.BinaryOperator($1, "**", $3, @$); + } + | arg L_AND_TOK arg + { + $$ = new ast.BinaryOperator($1, "&&", $3, @$); + } + | arg L_OR_TOK arg + { + $$ = new ast.BinaryOperator($1, "||", $3, @$); + } + | arg L_XOR_TOK arg + { + $$ = new ast.BinaryOperator($1, "^^", $3, @$); + } + | arg BW_AND_TOK arg + { + $$ = new ast.BinaryOperator($1, "&", $3, @$); + } + | arg BW_OR_TOK arg + { + $$ = new ast.BinaryOperator($1, "|", $3, @$); + } + | arg BW_XOR_TOK arg + { + $$ = new ast.BinaryOperator($1, "^", $3, @$); + } + | arg BW_SHIFT_L_TOK arg + { + $$ = new ast.BinaryOperator($1, "<<", $3, @$); + } + | arg BW_SHIFT_R_TOK arg + { + $$ = new ast.BinaryOperator($1, ">>", $3, @$); + } + | arg BW_SHIFT_R_UNSIGNED_TOK arg + { + $$ = new ast.BinaryOperator($1, ">>>", $3, @$); + } + /* -- User-defined aggregators -- */ + | AT AT IDENT arg_list COLON arg COMMA aggregate_body + { + parseNYI(`User-defined Aggregators ${yytext}`) + } + /* -- aggregators -- */ + | aggregate_func arg_list COLON aggregate_body + { + parseNYI(`Aggregators ${yytext}`) + } + ; + +functor_built_in + : CAT + { + $$ = "cat"; + } + | ORD + { + $$ = "ord"; + } + | RANGE + { + $$ = "range"; + } + | STRLEN + { + $$ = "strlen"; + } + | SUBSTR + { + $$ = "substr"; + } + | TOFLOAT + { + $$ = "to_float"; + } + | TONUMBER + { + $$ = "to_number"; + } + | TOSTRING + { + $$ = "to_string"; + } + | TOUNSIGNED + { + $$ = "to_unsigned"; + } + ; + +aggregate_func + : COUNT + { + $$ = "count"; + } + | MAX + { + $$ = "max"; + } + | MEAN + { + $$ = "mean"; + } + | MIN + { + $$ = "min"; + } + | SUM + { + $$ = "sum"; + } + ; + +aggregate_body + : LBRACE body RBRACE + { + $$ = $2; + } + | atom + { + $$ = $1; + } + ; +%% \ No newline at end of file From a6c3c7bf7dfb4e7ca474225ec33f11c9071939b1 Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Fri, 8 Mar 2024 08:12:23 +0200 Subject: [PATCH 09/10] remove peggy packages --- package-lock.json | 2101 ++++++++++++++++++++++++++++++--------------- package.json | 5 +- tsconfig.json | 2 +- 3 files changed, 1414 insertions(+), 694 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02614c0..ac2d4e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,11 +33,10 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "expect": "^29.7.0", + "jison": "^0.4.18", "mocha": "^10.3.0", - "peggy": "^2.0.1", "prettier": "3.2.5", "ts-node": "^10.9.2", - "ts-pegjs": "^3.1.0", "typescript": "^5.3.3" } }, @@ -51,12 +50,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -144,9 +143,9 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -293,10 +292,32 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -309,19 +330,41 @@ "optional": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -336,9 +379,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@istanbuljs/schema": { @@ -392,9 +435,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" @@ -549,9 +592,9 @@ "dev": true }, "node_modules/@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, "engines": { "node": ">=18" @@ -634,24 +677,24 @@ } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz", - "integrity": "sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz", - "integrity": "sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -664,9 +707,9 @@ "dev": true }, "node_modules/@types/jsonfile": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.3.tgz", - "integrity": "sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", "dev": true, "dependencies": { "@types/node": "*" @@ -679,18 +722,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/sqlite3": { @@ -703,37 +746,37 @@ } }, "node_modules/@types/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.29", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.29.tgz", - "integrity": "sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==", + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.2.tgz", - "integrity": "sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==", + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", - "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz", + "integrity": "sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/scope-manager": "7.1.1", + "@typescript-eslint/type-utils": "7.1.1", + "@typescript-eslint/utils": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -759,15 +802,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", - "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.1.tgz", + "integrity": "sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/scope-manager": "7.1.1", + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/typescript-estree": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1", "debug": "^4.3.4" }, "engines": { @@ -787,13 +830,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", - "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.1.tgz", + "integrity": "sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -804,13 +847,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", - "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.1.tgz", + "integrity": "sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", + "@typescript-eslint/typescript-estree": "7.1.1", + "@typescript-eslint/utils": "7.1.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -831,9 +874,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", - "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.1.tgz", + "integrity": "sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -844,13 +887,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", - "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.1.tgz", + "integrity": "sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -871,15 +914,6 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -900,33 +934,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, "node_modules/@typescript-eslint/utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", - "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.1.tgz", + "integrity": "sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/scope-manager": "7.1.1", + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/typescript-estree": "7.1.1", "semver": "^7.5.4" }, "engines": { @@ -941,12 +969,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", - "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.1.tgz", + "integrity": "sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/types": "7.1.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -984,9 +1012,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1005,9 +1033,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", - "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" @@ -1066,6 +1094,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.4.2" + } + }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -1118,6 +1156,19 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "optional": true }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1145,9 +1196,12 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -1218,13 +1272,12 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -1321,15 +1374,58 @@ "node": ">= 10" } }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/call-bind": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", - "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "set-function-length": "^1.2.0" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -1437,6 +1533,18 @@ "node": ">=8" } }, + "node_modules/cjson": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.3.0.tgz", + "integrity": "sha512-bBRQcCIHzI1IVH59fR0bwGrFmi3Btb/JNwM/n401i1DnYgWndpsUBiQRAddLflkZage20A2d25OAWZZk0vBRlA==", + "dev": true, + "dependencies": { + "jsonlint": "1.6.0" + }, + "engines": { + "node": ">= 0.3.0" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1487,6 +1595,15 @@ "color-support": "bin.js" } }, + "node_modules/colors": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz", + "integrity": "sha512-XjsuUwpDeY98+yz959OlUK6m7mLBM+1MEG5oaenfuQnNnrQk1WvtcvFgN3FNDP3f2NmZ211t0mNEfSEN1h0eIg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1550,9 +1667,9 @@ } }, "node_modules/csv-parse": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.3.tgz", - "integrity": "sha512-v0KW6C0qlZzoGjk6u5tLmVfyZxNgPGXZsWTXshpAgKVGmGXzaVWGdlCFxNx5iuzcXT/oJN1HHM9DZKwtAtYa+A==" + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.5.tgz", + "integrity": "sha512-erCk7tyU3yLWAhk6wvKxnyPtftuy/6Ak622gOO7BCJ05+TYffnPCJF905wmOQm+BpkX54OdAl8pveJwUdpnCXQ==" }, "node_modules/debug": { "version": "4.3.4", @@ -1617,17 +1734,19 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", - "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.2", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/delayed-stream": { @@ -1722,6 +1841,12 @@ "url": "https://dotenvx.com" } }, + "node_modules/ebnf-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz", + "integrity": "sha512-urvSxVQ6XJcoTpc+/x2pWhhuOX4aljCNQpwzw+ifZvV1andZkAmiJc3Rq1oGEAQmcjiLceyMXOy1l8ms8qs2fQ==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1760,6 +1885,17 @@ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "optional": true }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -1769,9 +1905,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -1789,17 +1925,56 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.3.3.tgz", + "integrity": "sha512-z9FWgKc48wjMlpzF5ymKS1AF8OIgnKLp9VyN7KbdtyrP/9lndwUFqCtMm+TAJmJf7KJFFYc4cFJfVTTGkKEwsA==", + "dev": true, + "dependencies": { + "esprima": "~1.1.1", + "estraverse": "~1.5.0", + "esutils": "~1.0.0" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.10.0" + }, + "optionalDependencies": { + "source-map": "~0.1.33" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz", + "integrity": "sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/escodegen/node_modules/esutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz", + "integrity": "sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -1914,6 +2089,28 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -1931,6 +2128,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz", + "integrity": "sha512-qxxB994/7NtERxgXdFgLHIs9M6bhLXc6qtUmWZ3L8+gTQ9qaoyki2887P2IqAYsoENyr8SUbTutStDniOHSDHg==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -2072,9 +2282,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -2148,9 +2358,9 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", @@ -2158,13 +2368,13 @@ "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/follow-redirects": { @@ -2210,18 +2420,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -2292,6 +2490,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2325,20 +2548,19 @@ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "devOptional": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2356,6 +2578,18 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -2411,12 +2645,12 @@ } }, "node_modules/globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dev": true, "dependencies": { - "@sindresorhus/merge-streams": "^1.0.0", + "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", "ignore": "^5.2.4", "path-type": "^5.0.0", @@ -2430,18 +2664,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -2474,20 +2696,20 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "engines": { "node": ">= 0.4" }, @@ -2527,9 +2749,9 @@ "optional": true }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dependencies": { "function-bind": "^1.1.2" }, @@ -2637,9 +2859,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -2705,11 +2927,18 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "optional": true + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "optional": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } }, "node_modules/is-arguments": { "version": "1.1.1", @@ -2863,9 +3092,9 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { "node": ">=8" @@ -2886,9 +3115,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -2957,6 +3186,15 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -2974,6 +3212,44 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jison": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz", + "integrity": "sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w==", + "dev": true, + "dependencies": { + "cjson": "0.3.0", + "ebnf-parser": "0.1.10", + "escodegen": "1.3.x", + "esprima": "1.1.x", + "jison-lex": "0.3.x", + "JSONSelect": "0.4.0", + "lex-parser": "~0.1.3", + "nomnom": "1.5.2" + }, + "bin": { + "jison": "lib/cli.js" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/jison-lex": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.3.4.tgz", + "integrity": "sha512-EBh5wrXhls1cUwROd5DcDHR1sG7CdsCFSqY1027+YA1RGxz+BX2TDLAhdsQf40YEtFDGoiO0Qm8PpnBl2EzDJw==", + "dev": true, + "dependencies": { + "lex-parser": "0.1.x", + "nomnom": "1.5.2" + }, + "bin": { + "jison-lex": "cli.js" + }, + "engines": { + "node": ">=0.4" + } + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -2997,6 +3273,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "optional": true + }, "node_modules/jsel": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/jsel/-/jsel-1.1.6.tgz", @@ -3034,6 +3316,40 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonlint": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.0.tgz", + "integrity": "sha512-x6YLBe6NjdpmIeiklwQOxsZuYj/SOWkT33GlTpaG1UdFGjdWjPcxJ1CWZAX3wA7tarz8E2YHF6KiW5HTapPlXw==", + "dev": true, + "dependencies": { + "JSV": ">= 4.0.x", + "nomnom": ">= 1.5.x" + }, + "bin": { + "jsonlint": "lib/cli.js" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/JSONSelect": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", + "integrity": "sha512-VRLR3Su35MH+XV2lrvh9O7qWoug/TUyj9tLDjn9rtpUCNnILLrHjgd/tB0KrhugCxUpj3UqoLqfYb3fLJdIQQQ==", + "dev": true, + "engines": { + "node": ">=0.4.7" + } + }, + "node_modules/JSV": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", + "integrity": "sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -3056,6 +3372,12 @@ "node": ">= 0.8.0" } }, + "node_modules/lex-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz", + "integrity": "sha512-DuAEISsr1H4LOpmFLkyMc8YStiRWZCO8hMsoXAXSbgyfvs2WQhSt0+/FBv3ZU/JBFZMGcE+FWzEBSzwUU7U27w==", + "dev": true + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3212,15 +3534,18 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -3370,15 +3695,6 @@ "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3390,25 +3706,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -3496,9 +3793,9 @@ } }, "node_modules/node-abi": { - "version": "3.54.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", - "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", + "version": "3.56.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", + "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", "dependencies": { "semver": "^7.3.5" }, @@ -3538,51 +3835,60 @@ "node": ">= 10.12.0" } }, - "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "optional": true, "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "optional": true, "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "*" } }, - "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "optional": true, + "node_modules/nomnom": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha512-fiVbT7BqxiQqjlR9U3FDGOSERFCKoXVCdxV2FwZuNN7/cmJ42iQx35nUFOAFDcyvemu9Adp+IlsCGlKQYLmBKw==", + "deprecated": "Package no longer supported. Contact support@npmjs.com for more info.", + "dev": true, "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" + "colors": "0.5.x", + "underscore": "1.1.x" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "*" } }, "node_modules/nopt": { @@ -3609,6 +3915,21 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3737,44 +4058,19 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/peggy": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/peggy/-/peggy-2.0.1.tgz", - "integrity": "sha512-mBqfmdUAOVn7RILpXTbcRBhLfTR4Go0SresSnivGDdRylBOyVFJncFiVyCNNpPWq8HmgeRleXHs/Go4o8kQVXA==", - "dev": true, - "dependencies": { - "commander": "^9.3.0", - "source-map-generator": "0.8.0" - }, - "bin": { - "peggy": "bin/peggy.js" - }, - "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/peggy/node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { - "node": "^12.20.0 || >=14" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/picomatch": { @@ -3788,10 +4084,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", @@ -4063,6 +4367,48 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "devOptional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4178,10 +4524,16 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "optional": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/simple-concat": { "version": "1.0.1", @@ -4227,12 +4579,15 @@ } }, "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/smart-buffer": { @@ -4246,16 +4601,16 @@ } }, "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", "optional": true, "dependencies": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, @@ -4329,15 +4684,25 @@ "semver": "bin/semver" } }, - "node_modules/source-map-generator": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz", - "integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==", + "node_modules/source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==", "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, "engines": { - "node": ">= 10" + "node": ">=0.8.0" } }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "optional": true + }, "node_modules/sqlite": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-5.1.1.tgz", @@ -4547,6 +4912,48 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4639,18 +5046,6 @@ "node": ">=0.3.1" } }, - "node_modules/ts-pegjs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ts-pegjs/-/ts-pegjs-3.1.0.tgz", - "integrity": "sha512-CZ80MYdzoh/setHAcrOdWh7ws4GsIPAahFEZ1019xPLe2snSzwuCLDAwQ0r7xHLIuOuRJ7v87jvz/Lr5YTLN4g==", - "dev": true, - "bin": { - "tspegjs": "src/cli.js" - }, - "peerDependencies": { - "peggy": "^2.0.1" - } - }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -4704,6 +5099,15 @@ "node": ">=14.17" } }, + "node_modules/underscore": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha512-w4QtCHoLBXw1mjofIDoMyexaEdWGMedWNDhlWTtT1V1lCRqi65Pnoygkh6+WRdr+Bm8ldkBNkNeCsXGMlQS9HQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -4781,9 +5185,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", - "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -4795,9 +5199,9 @@ } }, "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -4833,22 +5237,22 @@ } }, "node_modules/web3-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.3.1.tgz", - "integrity": "sha512-8fXi7h/t95VKRtgU4sxprLPZpsTh3jYDfSghshIDBgUD/OoGe5S+syP24SUzBZYllZ/L+hMr2gdp/0bGJa8pYQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.4.0.tgz", + "integrity": "sha512-QnGDNredYqtZ49YD1pIPhsQTJJTOnYPCOnvrUs4/3XzeQLuDM+bAJ8fZ6U2nGEV77h81z2Ins6RE/f40yltvww==", "engines": { "node": ">=14", "npm": ">=6.12.0" } }, "node_modules/web3-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.1.1.tgz", - "integrity": "sha512-5AOmLKH6QuwHunLCNdVFlPSDE+T88bJYRQP+HWYoKNbI4STALCYQiJvj7LXE+Ed6cPfqANaK/LwKNbMPLCPFwA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.2.0.tgz", + "integrity": "sha512-UE7tmqPnC6sD0kpHhZiO9Zu8q7hiBItCQhnmxoMxk8OI91qlBWw6L7w1VNZo7TMBWH1Qe4R5l8h2vaoQCizVyA==", "dependencies": { "ethereum-cryptography": "^2.0.0", "web3-errors": "^1.1.4", - "web3-types": "^1.3.1", + "web3-types": "^1.4.0", "web3-validator": "^2.0.4" }, "engines": { @@ -5036,12 +5440,12 @@ "dev": true }, "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "requires": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "dependencies": { @@ -5110,9 +5514,9 @@ "dev": true }, "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.20", @@ -5223,12 +5627,33 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@gar/promisify": { @@ -5238,14 +5663,35 @@ "optional": true }, "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "@humanwhocodes/module-importer": { @@ -5255,9 +5701,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "@istanbuljs/schema": { @@ -5299,9 +5745,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true }, "@jridgewell/sourcemap-codec": { @@ -5416,9 +5862,9 @@ "dev": true }, "@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true }, "@tootallnate/once": { @@ -5483,24 +5929,24 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true }, "@types/istanbul-lib-report": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz", - "integrity": "sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } }, "@types/istanbul-reports": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz", - "integrity": "sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -5513,9 +5959,9 @@ "dev": true }, "@types/jsonfile": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.3.tgz", - "integrity": "sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", "dev": true, "requires": { "@types/node": "*" @@ -5528,18 +5974,18 @@ "dev": true }, "@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", "dev": true, "requires": { "undici-types": "~5.26.4" } }, "@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "@types/sqlite3": { @@ -5552,37 +5998,37 @@ } }, "@types/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, "@types/yargs": { - "version": "17.0.29", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.29.tgz", - "integrity": "sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==", + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.2.tgz", - "integrity": "sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==", + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", - "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz", + "integrity": "sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/scope-manager": "7.1.1", + "@typescript-eslint/type-utils": "7.1.1", + "@typescript-eslint/utils": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -5592,54 +6038,54 @@ } }, "@typescript-eslint/parser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", - "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.1.tgz", + "integrity": "sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/scope-manager": "7.1.1", + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/typescript-estree": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", - "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.1.tgz", + "integrity": "sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA==", "dev": true, "requires": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1" } }, "@typescript-eslint/type-utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", - "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.1.tgz", + "integrity": "sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", + "@typescript-eslint/typescript-estree": "7.1.1", + "@typescript-eslint/utils": "7.1.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", - "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.1.tgz", + "integrity": "sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", - "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.1.tgz", + "integrity": "sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==", "dev": true, "requires": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/visitor-keys": "7.1.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -5648,15 +6094,6 @@ "ts-api-utils": "^1.0.1" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -5671,39 +6108,36 @@ "slash": "^3.0.0" } }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true } } }, "@typescript-eslint/utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", - "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.1.tgz", + "integrity": "sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/scope-manager": "7.1.1", + "@typescript-eslint/types": "7.1.1", + "@typescript-eslint/typescript-estree": "7.1.1", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", - "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.1.tgz", + "integrity": "sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/types": "7.1.1", "eslint-visitor-keys": "^3.4.1" } }, @@ -5726,9 +6160,9 @@ "requires": {} }, "acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -5739,9 +6173,9 @@ "requires": {} }, "acorn-walk": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", - "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true }, "agent-base": { @@ -5784,6 +6218,13 @@ "uri-js": "^4.2.2" } }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "optional": true + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -5821,6 +6262,16 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "optional": true }, + "are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -5845,9 +6296,12 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } }, "axios": { "version": "1.6.7", @@ -5895,13 +6349,12 @@ } }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "devOptional": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "braces": { @@ -5970,17 +6423,53 @@ "ssri": "^8.0.1", "tar": "^6.0.2", "unique-filename": "^1.1.1" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "call-bind": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", - "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "requires": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "set-function-length": "^1.2.0" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -6043,6 +6532,15 @@ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true }, + "cjson": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.3.0.tgz", + "integrity": "sha512-bBRQcCIHzI1IVH59fR0bwGrFmi3Btb/JNwM/n401i1DnYgWndpsUBiQRAddLflkZage20A2d25OAWZZk0vBRlA==", + "dev": true, + "requires": { + "jsonlint": "1.6.0" + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -6081,6 +6579,12 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "optional": true }, + "colors": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz", + "integrity": "sha512-XjsuUwpDeY98+yz959OlUK6m7mLBM+1MEG5oaenfuQnNnrQk1WvtcvFgN3FNDP3f2NmZ211t0mNEfSEN1h0eIg==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -6135,9 +6639,9 @@ } }, "csv-parse": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.3.tgz", - "integrity": "sha512-v0KW6C0qlZzoGjk6u5tLmVfyZxNgPGXZsWTXshpAgKVGmGXzaVWGdlCFxNx5iuzcXT/oJN1HHM9DZKwtAtYa+A==" + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.5.tgz", + "integrity": "sha512-erCk7tyU3yLWAhk6wvKxnyPtftuy/6Ak622gOO7BCJ05+TYffnPCJF905wmOQm+BpkX54OdAl8pveJwUdpnCXQ==" }, "debug": { "version": "4.3.4", @@ -6179,14 +6683,13 @@ "dev": true }, "define-data-property": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", - "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "requires": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.2", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" } }, "delayed-stream": { @@ -6253,6 +6756,12 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" }, + "ebnf-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz", + "integrity": "sha512-urvSxVQ6XJcoTpc+/x2pWhhuOX4aljCNQpwzw+ifZvV1andZkAmiJc3Rq1oGEAQmcjiLceyMXOy1l8ms8qs2fQ==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -6288,15 +6797,23 @@ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "optional": true }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, "es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "escape-string-regexp": { @@ -6305,17 +6822,43 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "escodegen": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.3.3.tgz", + "integrity": "sha512-z9FWgKc48wjMlpzF5ymKS1AF8OIgnKLp9VyN7KbdtyrP/9lndwUFqCtMm+TAJmJf7KJFFYc4cFJfVTTGkKEwsA==", + "dev": true, + "requires": { + "esprima": "~1.1.1", + "estraverse": "~1.5.0", + "esutils": "~1.0.0", + "source-map": "~0.1.33" + }, + "dependencies": { + "estraverse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz", + "integrity": "sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ==", + "dev": true + }, + "esutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz", + "integrity": "sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg==", + "dev": true + } + } + }, "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -6349,6 +6892,27 @@ "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "eslint-config-prettier": { @@ -6395,6 +6959,12 @@ "eslint-visitor-keys": "^3.4.1" } }, + "esprima": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz", + "integrity": "sha512-qxxB994/7NtERxgXdFgLHIs9M6bhLXc6qtUmWZ3L8+gTQ9qaoyki2887P2IqAYsoENyr8SUbTutStDniOHSDHg==", + "dev": true + }, "esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -6511,9 +7081,9 @@ "dev": true }, "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -6569,9 +7139,9 @@ "dev": true }, "flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { "flatted": "^3.2.9", @@ -6580,9 +7150,9 @@ } }, "flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "follow-redirects": { @@ -6606,14 +7176,6 @@ "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } } }, "form-data": { @@ -6667,6 +7229,30 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, + "gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "optional": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "dependencies": { + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + } + } + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -6691,17 +7277,27 @@ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "devOptional": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "dependencies": { + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "glob-parent": { @@ -6755,25 +7351,17 @@ } }, "globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dev": true, "requires": { - "@sindresorhus/merge-streams": "^1.0.0", + "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", "ignore": "^5.2.4", "path-type": "^5.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.1.0" - }, - "dependencies": { - "slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true - } } }, "gopd": { @@ -6802,17 +7390,17 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "requires": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" } }, "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" }, "has-symbols": { "version": "1.0.3", @@ -6834,9 +7422,9 @@ "optional": true }, "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "requires": { "function-bind": "^1.1.2" } @@ -6912,9 +7500,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "import-fresh": { @@ -6965,11 +7553,15 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "optional": true + "ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "optional": true, + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + } }, "is-arguments": { "version": "1.1.1", @@ -7069,9 +7661,9 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true }, "istanbul-lib-report": { @@ -7086,9 +7678,9 @@ } }, "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -7140,6 +7732,14 @@ "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } } }, "jest-util": { @@ -7156,6 +7756,32 @@ "picomatch": "^2.2.3" } }, + "jison": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz", + "integrity": "sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w==", + "dev": true, + "requires": { + "cjson": "0.3.0", + "ebnf-parser": "0.1.10", + "escodegen": "1.3.x", + "esprima": "1.1.x", + "jison-lex": "0.3.x", + "JSONSelect": "0.4.0", + "lex-parser": "~0.1.3", + "nomnom": "1.5.2" + } + }, + "jison-lex": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.3.4.tgz", + "integrity": "sha512-EBh5wrXhls1cUwROd5DcDHR1sG7CdsCFSqY1027+YA1RGxz+BX2TDLAhdsQf40YEtFDGoiO0Qm8PpnBl2EzDJw==", + "dev": true, + "requires": { + "lex-parser": "0.1.x", + "nomnom": "1.5.2" + } + }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -7176,6 +7802,12 @@ "argparse": "^2.0.1" } }, + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "optional": true + }, "jsel": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/jsel/-/jsel-1.1.6.tgz", @@ -7208,6 +7840,28 @@ "universalify": "^2.0.0" } }, + "jsonlint": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.0.tgz", + "integrity": "sha512-x6YLBe6NjdpmIeiklwQOxsZuYj/SOWkT33GlTpaG1UdFGjdWjPcxJ1CWZAX3wA7tarz8E2YHF6KiW5HTapPlXw==", + "dev": true, + "requires": { + "JSV": ">= 4.0.x", + "nomnom": ">= 1.5.x" + } + }, + "JSONSelect": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", + "integrity": "sha512-VRLR3Su35MH+XV2lrvh9O7qWoug/TUyj9tLDjn9rtpUCNnILLrHjgd/tB0KrhugCxUpj3UqoLqfYb3fLJdIQQQ==", + "dev": true + }, + "JSV": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", + "integrity": "sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw==", + "dev": true + }, "keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -7227,6 +7881,12 @@ "type-check": "~0.4.0" } }, + "lex-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz", + "integrity": "sha512-DuAEISsr1H4LOpmFLkyMc8YStiRWZCO8hMsoXAXSbgyfvs2WQhSt0+/FBv3ZU/JBFZMGcE+FWzEBSzwUU7U27w==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7338,12 +7998,12 @@ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "devOptional": true, + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "minimist": { @@ -7454,15 +8114,6 @@ "yargs-unparser": "2.0.0" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -7474,19 +8125,6 @@ "wrap-ansi": "^7.0.0" } }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, "minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -7558,9 +8196,9 @@ "optional": true }, "node-abi": { - "version": "3.54.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", - "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", + "version": "3.56.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", + "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", "requires": { "semver": "^7.3.5" } @@ -7588,46 +8226,51 @@ "which": "^2.0.2" }, "dependencies": { - "are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "optional": true, "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "optional": true, "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" + "brace-expansion": "^1.1.7" } } } }, + "nomnom": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz", + "integrity": "sha512-fiVbT7BqxiQqjlR9U3FDGOSERFCKoXVCdxV2FwZuNN7/cmJ42iQx35nUFOAFDcyvemu9Adp+IlsCGlKQYLmBKw==", + "dev": true, + "requires": { + "colors": "0.5.x", + "underscore": "1.1.x" + } + }, "nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -7643,6 +8286,18 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "optional": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7741,33 +8396,20 @@ "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true }, - "peggy": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/peggy/-/peggy-2.0.1.tgz", - "integrity": "sha512-mBqfmdUAOVn7RILpXTbcRBhLfTR4Go0SresSnivGDdRylBOyVFJncFiVyCNNpPWq8HmgeRleXHs/Go4o8kQVXA==", - "dev": true, - "requires": { - "commander": "^9.3.0", - "source-map-generator": "0.8.0" - }, - "dependencies": { - "commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true - } - } - }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==" + }, "prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "requires": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", @@ -7957,6 +8599,41 @@ "devOptional": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "devOptional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "run-parallel": { @@ -8031,10 +8708,10 @@ "dev": true }, "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "optional": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true }, "simple-concat": { "version": "1.0.1", @@ -8052,9 +8729,9 @@ } }, "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true }, "smart-buffer": { @@ -8064,12 +8741,12 @@ "optional": true }, "socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", "optional": true, "requires": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" } }, @@ -8127,11 +8804,21 @@ "web3-eth-abi": "^4.2.0" } }, - "source-map-generator": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz", - "integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==", - "dev": true + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "optional": true }, "sqlite": { "version": "5.1.1", @@ -8293,6 +8980,41 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "text-table": { @@ -8353,13 +9075,6 @@ } } }, - "ts-pegjs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ts-pegjs/-/ts-pegjs-3.1.0.tgz", - "integrity": "sha512-CZ80MYdzoh/setHAcrOdWh7ws4GsIPAahFEZ1019xPLe2snSzwuCLDAwQ0r7xHLIuOuRJ7v87jvz/Lr5YTLN4g==", - "dev": true, - "requires": {} - }, "tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -8394,6 +9109,12 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==" }, + "underscore": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz", + "integrity": "sha512-w4QtCHoLBXw1mjofIDoMyexaEdWGMedWNDhlWTtT1V1lCRqi65Pnoygkh6+WRdr+Bm8ldkBNkNeCsXGMlQS9HQ==", + "dev": true + }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -8462,9 +9183,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", - "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.12", @@ -8473,9 +9194,9 @@ }, "dependencies": { "@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.1.0", @@ -8505,18 +9226,18 @@ } }, "web3-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.3.1.tgz", - "integrity": "sha512-8fXi7h/t95VKRtgU4sxprLPZpsTh3jYDfSghshIDBgUD/OoGe5S+syP24SUzBZYllZ/L+hMr2gdp/0bGJa8pYQ==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.4.0.tgz", + "integrity": "sha512-QnGDNredYqtZ49YD1pIPhsQTJJTOnYPCOnvrUs4/3XzeQLuDM+bAJ8fZ6U2nGEV77h81z2Ins6RE/f40yltvww==" }, "web3-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.1.1.tgz", - "integrity": "sha512-5AOmLKH6QuwHunLCNdVFlPSDE+T88bJYRQP+HWYoKNbI4STALCYQiJvj7LXE+Ed6cPfqANaK/LwKNbMPLCPFwA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.2.0.tgz", + "integrity": "sha512-UE7tmqPnC6sD0kpHhZiO9Zu8q7hiBItCQhnmxoMxk8OI91qlBWw6L7w1VNZo7TMBWH1Qe4R5l8h2vaoQCizVyA==", "requires": { "ethereum-cryptography": "^2.0.0", "web3-errors": "^1.1.4", - "web3-types": "^1.3.1", + "web3-types": "^1.4.0", "web3-validator": "^2.0.4" } }, diff --git a/package.json b/package.json index e2aee9c..bbd2b25 100644 --- a/package.json +++ b/package.json @@ -11,17 +11,16 @@ "sol-datalog-cli": "dist/bin/cli.js" }, "scripts": { - "clean": "rm -rf dist/ && rm -rf src/gen/declarations.ts src/gen/translate.ts", + "clean": "rm -rf dist/ && rm -rf src/gen/declarations.ts src/gen/translate.ts souffle_parser_gen.js souffle_value_parser_gen.js", "transpile": "tsc", "gen-translation-modules": "node scripts/gen_translation_modules.js && eslint --fix src/gen/translate.ts src/gen/declarations.ts", "copy-dl": "cp -r src/lib/analyses dist/lib && cp -r src/lib/detectors dist/lib", "copy-functors": "cp -r functors dist/", "build-parser": "jison src/lib/souffle/parser/souffle.jison -o src/lib/souffle/parser/souffle_parser_gen.js -m commonjs && cp src/lib/souffle/parser/souffle_parser_gen.js dist/lib/souffle/parser/souffle_parser_gen.js", "build-expr-parser": "jison src/lib/souffle/parser/souffle_value.jison -o src/lib/souffle/parser/souffle_value_parser_gen.js -m commonjs && cp src/lib/souffle/parser/souffle_value_parser_gen.js dist/lib/souffle/parser/souffle_value_parser_gen.js", - "build-value-parser": "tspegjs -o src/lib/souffle/value_parser.ts --custom-header-file src/lib/souffle/value_header.ts --allowed-start-rules Value --cache src/lib/souffle/values.pegjs", "build-parsers": "npm run build-parser && npm run build-expr-parser", "build-functors": "./scripts/build_functors.sh", - "build": "npm run clean && npm run gen-translation-modules && npm run build-value-parser && npm run transpile && npm run build-parsers && chmod a+x dist/bin/cli.js && npm run copy-dl && npm run build-functors && npm run copy-functors", + "build": "npm run clean && npm run gen-translation-modules && npm run transpile && npm run build-parsers && chmod a+x dist/bin/cli.js && npm run copy-dl && npm run build-functors && npm run copy-functors", "test": "c8 mocha", "lint": "eslint src/ test/ --ext=ts", "lint:fix": "eslint src/ test/ --ext=ts --fix", diff --git a/tsconfig.json b/tsconfig.json index 6219868..614e056 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,5 +26,5 @@ }, "include": ["src/**/*"], - "exclude": ["src/lib/souffle/value_header.ts"] + "exclude": [] } From 0499e67b9e13928d940095fbbfaeab82c164d94d Mon Sep 17 00:00:00 2001 From: Dimitar Bounov Date: Sat, 9 Mar 2024 02:56:34 +0200 Subject: [PATCH 10/10] Fix review comments --- src/lib/souffle/ast/declarations/adt.ts | 4 ++-- src/lib/souffle/ast/declarations/component.ts | 8 +++++--- src/lib/souffle/ast/declarations/directive.ts | 10 ++++++---- src/lib/souffle/ast/declarations/functor.ts | 2 +- src/lib/souffle/ast/declarations/record_type.ts | 2 +- src/lib/souffle/ast/declarations/relation.ts | 6 ++++-- src/lib/souffle/ast/declarations/rule.ts | 2 +- src/lib/souffle/ast/expressions/binary.ts | 17 ++++++++++++++++- src/lib/souffle/ast/expressions/unary.ts | 4 ++-- src/lib/souffle/ast/rules/atom.ts | 2 +- .../souffle/ast/rules/constraints/comparison.ts | 2 +- test/samples/analyses/fcall.json | 2 ++ test/succ.spec.ts | 4 ++-- 13 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/lib/souffle/ast/declarations/adt.ts b/src/lib/souffle/ast/declarations/adt.ts index 92b00e3..f8b9704 100644 --- a/src/lib/souffle/ast/declarations/adt.ts +++ b/src/lib/souffle/ast/declarations/adt.ts @@ -13,9 +13,9 @@ export class AlgebraicDataType extends Declaration { } pp(indent: string = ""): string { - return `${indent}.type ${this.name} = [${this.branches + return `${indent}.type ${this.name} = ${this.branches .map((b) => `${b[0]} {${b[1].map((f) => `${f[0]}: ${f[1].pp()}`).join(", ")}}`) - .join(" | ")}]`; + .join(" | ")}`; } children(): Iterable { diff --git a/src/lib/souffle/ast/declarations/component.ts b/src/lib/souffle/ast/declarations/component.ts index ea6dee3..c8a83df 100644 --- a/src/lib/souffle/ast/declarations/component.ts +++ b/src/lib/souffle/ast/declarations/component.ts @@ -18,10 +18,12 @@ export class Component extends Declaration { } pp(indent: string = ""): string { + const innerIndent = indent + " "; + return `${indent}.comp ${Component.ppCompInv([this.name, this.typeParams])}${ - this.bases.length ? 0 : this.bases.map(Component.ppCompInv).join(", ") + this.bases.length == 0 ? "" : ":" + this.bases.map(Component.ppCompInv).join(", ") } { - ${this.body.map((x) => x.pp(indent + " ")).join("\n")} + ${this.body.map((x) => x.pp(innerIndent)).join("\n")} }`; } @@ -30,6 +32,6 @@ export class Component extends Declaration { } getStructId(): any { - return [this.name, ...this.typeParams, ...this.bases, ...this.body]; + return [this.name, this.typeParams, this.bases, this.body]; } } diff --git a/src/lib/souffle/ast/declarations/directive.ts b/src/lib/souffle/ast/declarations/directive.ts index 65c90ca..e626c1f 100644 --- a/src/lib/souffle/ast/declarations/directive.ts +++ b/src/lib/souffle/ast/declarations/directive.ts @@ -13,9 +13,11 @@ export class Directive extends Declaration { } pp(indent: string = ""): string { - return `${indent}${this.type} ${this.name}(${this.parameters - .map(([name, val]) => `${name} = ${val}`) - .join(", ")})`; + const paramStr = this.parameters + .map(([name, val]) => `${name} = ${typeof val === "string" ? `"${val}"` : val}`) + .join(", "); + + return `${indent}${this.type} ${this.name}${paramStr.length > 0 ? `(${paramStr})` : ""}`; } children(): Iterable { @@ -23,6 +25,6 @@ export class Directive extends Declaration { } getStructId(): any { - return [this.type, this.name, ...this.parameters]; + return [this.type, this.name, this.parameters]; } } diff --git a/src/lib/souffle/ast/declarations/functor.ts b/src/lib/souffle/ast/declarations/functor.ts index cd89048..f30dbf6 100644 --- a/src/lib/souffle/ast/declarations/functor.ts +++ b/src/lib/souffle/ast/declarations/functor.ts @@ -24,6 +24,6 @@ export class Functor extends Declaration { } getStructId(): any { - return [this.name, ...this.args, this.returnType, this.stateful]; + return [this.name, this.args, this.returnType, this.stateful]; } } diff --git a/src/lib/souffle/ast/declarations/record_type.ts b/src/lib/souffle/ast/declarations/record_type.ts index d4b41a3..1c612b9 100644 --- a/src/lib/souffle/ast/declarations/record_type.ts +++ b/src/lib/souffle/ast/declarations/record_type.ts @@ -22,6 +22,6 @@ export class RecordType extends Declaration { } getStructId(): any { - return [this.name, ...this.fields]; + return [this.name, this.fields]; } } diff --git a/src/lib/souffle/ast/declarations/relation.ts b/src/lib/souffle/ast/declarations/relation.ts index 93c05b4..559cde2 100644 --- a/src/lib/souffle/ast/declarations/relation.ts +++ b/src/lib/souffle/ast/declarations/relation.ts @@ -40,7 +40,7 @@ export class Relation extends Declaration { return `${indent}.decl ${this.name}(${this.args .map((a) => `${a[0]}: ${a[1].pp()}`) - .join(", ")}) ${[...this.tags].join(" ")}${ + .join(", ")}) ${[...this.tags].join(" ") + " "}${ choiceStrs.length > 0 ? `choice-domain ${choiceStrs.join(", ")}` : "" }`; } @@ -50,6 +50,8 @@ export class Relation extends Declaration { } getStructId(): any { - return [this.name, ...this.args, [...this.tags], this.choiceDomains]; + const tags = [...this.tags]; + tags.sort(); + return [this.name, this.args, tags, this.choiceDomains]; } } diff --git a/src/lib/souffle/ast/declarations/rule.ts b/src/lib/souffle/ast/declarations/rule.ts index 9896c0b..45c71be 100644 --- a/src/lib/souffle/ast/declarations/rule.ts +++ b/src/lib/souffle/ast/declarations/rule.ts @@ -19,7 +19,7 @@ export class Rule extends Declaration { let queryPlanStr = ""; if (this.queryPlan.length > 0) { - queryPlanStr += ".plan"; + queryPlanStr += " .plan"; queryPlanStr += this.queryPlan .map(([num, nums]) => `${num}: (${nums.map((x) => `${x}`).join(", ")})`) .join(", "); diff --git a/src/lib/souffle/ast/expressions/binary.ts b/src/lib/souffle/ast/expressions/binary.ts index 16ab7cf..40e8a56 100644 --- a/src/lib/souffle/ast/expressions/binary.ts +++ b/src/lib/souffle/ast/expressions/binary.ts @@ -1,7 +1,22 @@ import { Node, Src } from "../node"; import { Expression } from "./expression"; -export type BinaryOp = "+"; +export type BinaryOp = + | "+" + | "-" + | "*" + | "/" + | "%" + | "^" + | "land" + | "lor" + | "lxor" + | "band" + | "bor" + | "bxor" + | "bshl" + | "bshr" + | "bshru"; export class BinaryOperator extends Expression { constructor( diff --git a/src/lib/souffle/ast/expressions/unary.ts b/src/lib/souffle/ast/expressions/unary.ts index c7bbbff..ad44ca5 100644 --- a/src/lib/souffle/ast/expressions/unary.ts +++ b/src/lib/souffle/ast/expressions/unary.ts @@ -1,7 +1,7 @@ import { Node, Src } from "../node"; import { Expression } from "./expression"; -export type UnaryOp = "-" | "~" | "!"; +export type UnaryOp = "-" | "bnot" | "lnot"; export class UnaryOperator extends Expression { constructor( @@ -13,7 +13,7 @@ export class UnaryOperator extends Expression { } pp(): string { - return `${this.op}(${this.subExpr.pp()})`; + return `(${this.op}${this.subExpr.pp()})`; } children(): Iterable { diff --git a/src/lib/souffle/ast/rules/atom.ts b/src/lib/souffle/ast/rules/atom.ts index 4a46e81..a0a27c4 100644 --- a/src/lib/souffle/ast/rules/atom.ts +++ b/src/lib/souffle/ast/rules/atom.ts @@ -19,6 +19,6 @@ export class Atom extends Node { } getStructId(): any { - return [this.name, ...this.args]; + return [this.name, this.args]; } } diff --git a/src/lib/souffle/ast/rules/constraints/comparison.ts b/src/lib/souffle/ast/rules/constraints/comparison.ts index 6bfc642..4bb209c 100644 --- a/src/lib/souffle/ast/rules/constraints/comparison.ts +++ b/src/lib/souffle/ast/rules/constraints/comparison.ts @@ -15,7 +15,7 @@ export class Comparison extends Constraint { } pp(): string { - return `${this.lhs.pp()} ${this.op} ${this.rhs.pp()}`; + return `(${this.lhs.pp()} ${this.op} ${this.rhs.pp()})`; } children(): Iterable { diff --git a/test/samples/analyses/fcall.json b/test/samples/analyses/fcall.json index fba8b15..caffa8b 100644 --- a/test/samples/analyses/fcall.json +++ b/test/samples/analyses/fcall.json @@ -12,7 +12,9 @@ [52, 15, [52, [15, null]]], [52, 22, [52, [8, [22, null]]]], [52, 29, [52, [15, [29, null]]]], + [52, 29, [52, [8, [22, [29, null]]]]], [52, 40, [52, [15, [29, [40, null]]]]], + [52, 40, [52, [8, [22, [29, [40, null]]]]]], [59, 59, [59, [59, null]]] ] } diff --git a/test/succ.spec.ts b/test/succ.spec.ts index 73e022f..929e974 100644 --- a/test/succ.spec.ts +++ b/test/succ.spec.ts @@ -185,13 +185,13 @@ describe("Test succ relation for all samples", () => { describe(sample, () => { let units: sol.SourceUnit[]; let infer: sol.InferType; - let contents: string; + let contents: Buffer; let succ: Fact[]; let succFirst: NdGraph; let g: NdGraph; before(async () => { - contents = fse.readFileSync(sample, { encoding: "utf-8" }); + contents = fse.readFileSync(sample); const result = await sol.compileSol(sample, "auto"); const data = result.data;