def for_of_statement_to_gast(node): gast = {} gast["type"] = "forOfStatement" gast["init"] = jr.node_to_gast(node.left) gast["iter"] = jr.node_to_gast(node.right) gast["body"] = jr.node_to_gast(node.body) return gast
def func_declarations_to_gast(node): gast = {} gast["type"] = "functionDeclaration" gast["id"] = js_router.node_to_gast(node.id) gast["params"] = js_router.node_to_gast(node.params) gast["body"] = js_router.node_to_gast(node.body) return gast
def for_range_statement_to_gast(node): gast = {} gast["type"] = "forRangeStatement" gast["init"] = jr.node_to_gast(node.init) gast["test"] = jr.node_to_gast(node.test) gast["update"] = jr.node_to_gast(node.update) gast["body"] = jr.node_to_gast(node.body) return gast
def arrow_function_to_gast(node): ''' Takes arrow function or anon function and convert into a gast node. This node stores the same fields as a function node but doesn't store name ''' gast = {} gast["type"] = "arrowExpression" gast["params"] = js_router.node_to_gast(node.params) gast["body"] = js_router.node_to_gast(node.body) return gast
def assign_to_gast(node): """ Handles js var declarations to generic AST node """ gast = {} gast["type"] = "varAssign" # only works with single assignment gast["kind"] = node.kind gast["varId"] = js_router.node_to_gast(node.declarations[0].id) gast["varValue"] = js_router.node_to_gast(node.declarations[0].init) return gast
def call_expression_to_gast(node): """ takes python ast call node and converts to generic ast format example print('hello'): exampleIn Call(func=Name(id='print'), args=[Str(s='hello')], keywords=[]) exampleOut {'type': 'funcCall', 'value': {'type': 'logStatement'}, 'args': [{'type': 'str', 'value': 'hello'}]} """ gast = {} gast["type"] = "funcCall" gast["value"] = js_router.node_to_gast(node.callee) gast["args"] = js_router.node_to_gast(node.arguments) return gast
def aug_assign_to_gast(node): """ Handles augmented assignment to generic AST node example: js code: x += 1 gast: {'type': 'augAssign', 'left': {'type': 'name', 'value': 'x'}, 'op': '+=', 'right': {'type': 'num', 'value': 1}} """ gast = {"type": "augAssign"} gast["left"] = js_router.node_to_gast(node.left) gast["op"] = node.operator gast['right'] = js_router.node_to_gast(node.right) return gast
def while_statement_to_gast(node): gast = {} gast["type"] = "whileStatement" # Code re-used from js_conditional. TODO: figure out how to go through router body = node.body if body.type == "BlockStatement": gast["body"] = jr.node_to_gast(body) else: gast["body"] = [jr.node_to_gast(body)] gast["test"] = jr.node_to_gast(node.test) return gast
def js_to_gast(js_input): """ takes js string and converts it to a generic AST """ input_ast = '' try: input_ast = esprima.parseScript(js_input, {"tokens": False}) except: # this will signal to translate that error occurred return None return js_router.node_to_gast(input_ast)
def member_expression_to_gast(node): """ Converts Member Expression to our generic AST recursively Used for functions called on objects and std funcs like console.log """ if node.computed == True: return subscript_to_gast(node) if node.object.name == "console" and node.property.name == "log": return {"type": "logStatement"} gast = {"value": js_router.node_to_gast(node.object)} func_name = node.property.name # The tool only currently supports the built in functions below # TODO add other built in function translations if func_name in {func.name for func in built_in.js_built_in_functions}: gast["type"] = "builtInAttribute" gast["id"] = built_in.js_built_in_functions[func_name].value return gast gast["type"] = "attribute" gast["id"] = node.property.name return gast
def if_statement_to_gast(node): gast = {} gast["type"] = "if" """ The reason for the below logic is to make the following two expressions evaluate to the same gast if (true) {console.log("This is true")} if (true) console.log("This is true") In the future, we should have a discussion about how we want to handle single line vs. block statements for javascript. This works for now. TODO """ body = node.consequent if body.type == "BlockStatement": gast["body"] = jr.node_to_gast(body) else: gast["body"] = [jr.node_to_gast(body)] """ For now, I added in this logic so that the none type would be replaced by an empty list as specified in gast contract. Since Cory is working on none types, I did not want to add this in until merge. Eventually the whole code block should be replaced with gast["orelse"] = jr.node_to_gast(node.alternate) TODO """ alt = node.alternate if alt == None: gast["orelse"] = jr.node_to_gast([]) else: # FIXME: nested if statement same problem as in body if alt.type == "BlockStatement": gast["orelse"] = jr.node_to_gast(alt) else: gast["orelse"] = [jr.node_to_gast(alt)] # gast["test"] = jr.node_to_gast(node.test) return gast
def subscript_to_gast(node): gast = {"type": "subscript"} gast["index"] = js_router.node_to_gast(node.property) gast["value"] = js_router.node_to_gast(node.object) return gast
def convert_expression_to_gast(node): """ parses through top level expression """ return js_router.node_to_gast(node.expression)