-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mavo.Script.getVariables(ast)
function to extract expression variables
#975
Comments
Implementation sketch, entirely untested, may or may not be correct: function getVariables(node) {
let args;
switch (node.type):
case "LiteralExpression":
return [];
case "UnaryExpression":
return getVariables(node.argument);
case "CallExpression":
args = node.arguments; break;
case "Compound":
args = node.body; break;
case "BinaryExpression":
args = [node.left, node.right]; break;
case "ArrayExpression":
args = node.elements; break;
case "ConditionalExpression":
args = [node.test, node.consequent, node.alternate]; break;
case "ThisExpression":
case "Identifier":
case "MemberExpression":
default:
return [node];
}
if (args) {
return args.flatMap(arg => getVariables(arg));
}
} |
@LeaVerou Follow-up on An example:
In the implementation for
|
I guess a better way to phrase it would be are |
Think of the problem we're solving. Why are we writing this function? What do we aim to do with it? If you haven't read it yet, #967 will provide some essential context. |
Pasting my Slack message here for posterity: Thinking more about getVariables(), I think it should return all, including globals, and the surrounding code should deal with globals etc. Especially since if we rewrite Mavo apps to use Vue, we’d want to know which globals are being used so we can expose them. That also makes it more portable and more general purpose. In fact, I wonder if it should return functions as well, just separately. I.e. a data structure like |
Implemented in vastly, marking this as closed |
This is part of #967 and depends on #974
What would this function do?
This function would extract variables, i.e. non-literal operands, from a Mavo expression and return them as an array of AST nodes (object literals with a
type
attribute).Requirements:
Identifier
orMemberExpression
or (more rarely) aThisExpression
. However, not all nodes of these types will be part of a variable.MemberExpression
nodes (e.g.foo.bar.baz
) we want the topmostMemberExpression
node.Step 1: Map generalized AST structures to separate
getVariables()
functionsFor each AST structure identified in #974, write a function that maps it to an array of its variables.
For example, for the type of expression in Step 2 of #974, there is only one operand, which is returned by
ast.arguments[0]
,whereas for an expression of the form
foo(bar + 1)
,ast.arguments[0]
would be aBinaryExpression
— there we'd get the variable viaast.arguments[0].left
.You will probably notice a lot of patterns here, and will already start consolidating similar AST structures and coming up with a prototype algorithm. This is great!
Step 2: Create automated tests
Create a
Mavo.Script.getVariables(ast)
function, with the signature described above, but do not implement it yet.Add a page in test.mavo.io, pick one expression from each AAST category, and create tests for the function.
Step 5: Write algorithm to extract variables
Hopefully, after Step 1, this will be an easy task.
Use the tests you wrote in Step 2 to verify the algorithm is correct.
The text was updated successfully, but these errors were encountered: