syntax | Cell 25 | Cell 27 | Search

The exprToXpath function takes in a code parameter and uses various dependencies to convert it into an XPath expression, including selecting function declarations, extracting parameter names, and creating minimizing expressions. This function is then exported as a module, making it available for use in other parts of the application.

Run example

npm run import -- "select from code"

select from code

var importer = require('../Core');
var {
    selectAst, makeXpaths, minXpath,
    htmlToTree
} = importer.import("select code tree",
"make xpaths",
"minimize xpath",
"html to tree");

function exprToXpath(code) {
    // create an XPath search out of the function body
    //   using the parameters as matching predicates
    code = selectAst([
        `(*/FunctionDeclaration|*/*/ArrowFunctionExpression)`
    ], code.toString())[0]
    
    var expression = selectAst([
        `Identifier[@parent-attr="params"]/@name`,
        // select all elements from func that match param name
        //   TODO: default functionality can be overridden by specifying
        //   a function as the default parameter value
        (name) => selectAst([`BlockStatement//*[@name="${name}"]`], code)[0]
    ], code)[0]; // TODO: make multiple expressions?
    if(!expression) {
        throw new Error(`can't match expression ${JSON.stringify(htmlToTree(code))}`)
    }
    var xpath = makeXpaths(expression);
    // add minimizing expressions, unique to the original context
    var min = minXpath(xpath, selectAst(`BlockStatement`, code));
    delete code;
    return min;
}

module.exports = {
    exprToXpath
}

What the code could have been:

// Import the necessary modules
const { selectAst, makeXpaths, minXpath, htmlToTree } = require('../Core');

/**
 * Generates an XPath from a given function expression.
 * 
 * @param {string} code - The function expression as a string of JavaScript code.
 * @returns {string} The minimized XPath expression.
 * @throws {Error} If no expression can be matched in the code.
 */
function exprToXpath(code) {
    // Create an AST from the code
    const ast = selectAst([
        `(*/FunctionDeclaration|*/*/ArrowFunctionExpression)`
    ], code);
    
    if (!ast.length) {
        throw new Error(`Invalid code: ${htmlToTree(code)}`);
    }
    
    // Extract the function parameters
    const params = selectAst([
        `FunctionDeclaration/ParameterList/Parameter`
    ], ast[0]);
    
    if (!params.length) {
        throw new Error('No function parameters found.');
    }
    
    // Generate XPath expressions for each parameter
    const xpaths = params.map((param, index) => {
        const name = selectAst([`Name`, `Identifier`], param)[0];
        if (!name) {
            throw new Error(`No name found for parameter at index ${index}`);
        }
        return makeXpaths(name);
    });
    
    // Minimize the XPath expressions based on the function context
    const minimizedXpaths = xpaths.map(xpath => minXpath(xpath, selectAst(`BlockStatement`, ast[0])));
    
    return minimizedXpaths[0]; // Return the first minimized XPath (if multiple expressions are needed, implement a join operation)
}

module.exports = { exprToXpath };

Code Breakdown

Importing Dependencies

var importer = require('../Core');
var {
    selectAst, makeXpaths, minXpath,
    htmlToTree
} = importer.import([
   'select code tree','make xpaths','minimize xpath',
    'html to tree']);

The code imports dependencies from a core module using the require function. It utilizes the import function to load specific functions and assign them to variables.

exprToXpath Function

function exprToXpath(code) {
    // create an XPath search out of the function body
    //   using the parameters as matching predicates
    code = selectAst([
        `(*/FunctionDeclaration|*/*/ArrowFunctionExpression)`
    ], code.toString())[0]
    
    var expression = selectAst([
        `Identifier[@parent-attr="params"]/@name`,
        // select all elements from func that match param name
        //   TODO: default functionality can be overridden by specifying
        //   a function as the default parameter value
        (name) => selectAst([`BlockStatement//*[@name="${name}"]`], code)[0]
    ], code)[0]; // TODO: make multiple expressions?
    if (!expression) {
        throw new Error(`can't match expression ${JSON.stringify(htmlToTree(code))}`)
    }
    var xpath = makeXpaths(expression);
    // add minimizing expressions, unique to the original context
    var min = minXpath(xpath, selectAst(`BlockStatement`, code));
    delete code;
    return min;
}

This function, exprToXpath, takes a code parameter and is responsible for converting it to an XPath expression. It performs the following steps:

  1. Selects the function declaration or arrow function expression from the code using selectAst.
  2. Extracts the parameter names from the function declaration.
  3. Creates an XPath search for each match.
  4. Selects the minimizing expression from the resulting XPath search.
  5. Returns the minimizing expression.

Exporting Function

module.exports = {
    exprToXpath
}

The exprToXpath function is exported as a module, making it available for use in other parts of the application.