def while_statement_to_gast(node): """ Handle while statements in java to gast """ gast = {"type": "whileStatement"} gast["body"] = java_router.node_to_gast(node.body) gast["test"] = java_router.node_to_gast(node.condition) return gast
def bin_op_to_gast(node): """ Binops to gast for java """ gast = {"type": "binOp"} gast["left"] = java_router.node_to_gast(node.operandl.member) gast["op"] = node.operator gast["right"] = java_router.node_to_gast(node.operandr) return gast
def aug_assign_to_gast(node): """ Handles augmented assignment in java but not the incrementor and decrementor operations """ gast = {"type": "augAssign"} gast["left"] = java_router.node_to_gast(node.expressionl.member) gast["op"] = node.type gast["right"] = java_router.node_to_gast(node.value) return gast
def for_range_to_gast(node): """ Handle java range loops recursively using the router """ gast = {"type": "forRangeStatement"} gast["body"] = java_router.node_to_gast(node.body) gast["init"] = java_router.node_to_gast(node.control.init) gast["test"] = java_router.node_to_gast(node.control.condition) gast["update"] = java_router.node_to_gast(node.control.update[0]) return gast
def for_of_to_gast(node): """ Handle java for of loops that iterate over elements in an array, dictionary, etc. """ gast = {"type": "forOfStatement"} # TODO revaluate how we do variable assignment to account for this type of var assignment gast["init"] = java_router.node_to_gast( node.control.var.declarators[0].name) gast["body"] = java_router.node_to_gast(node.body) gast["iter"] = java_router.node_to_gast(node.control.iterable.member) return gast
def if_to_gast(node): gast = {"type": "if"} gast["body"] = java_router.node_to_gast(node.then_statement) gast["test"] = java_router.node_to_gast(node.condition) if node.else_statement == None: gast["orelse"] = [] elif type(node.else_statement) == javalang.tree.IfStatement: gast["orelse"] = [java_router.node_to_gast(node.else_statement)] else: gast["orelse"] = java_router.node_to_gast(node.else_statement) return gast
def java_to_gast(java_input): ''' Input will be wrapped in a class and main function if no functions are present If functions are present it will be wrapped in a class If a class declaration is given an error will be thrown ''' class_main_wrapped = ''' class Test {{ public static void {wrapper}(String[] args) {{ {java_input} }} }}'''.format(wrapper=java_constants.ARTIFICIAL_WRAPPER, java_input=java_input) class_wrapped = ''' class Test {{ {java_input} }}'''.format(java_input=java_input) # try to compile java with both wrappers - if one compiles start to build ast try: # if input compiles without wrapper it includes a class which is unsupported input_ast = javalang.parse.parse(java_input) # throw an error since classes are not supported return None except: try: input_ast = javalang.parse.parse(class_main_wrapped) except: try: input_ast = javalang.parse.parse(class_wrapped) except: # this will signal to translate that error occurred return None return java_router.node_to_gast(input_ast)
def class_declaration_to_gast(node): gast = {"type": "root"} ''' If the method in class is main function only translate that method and ignore function header We are assuming user only wants body of function translated ''' if type(node.body[0]) == javalang.tree.MethodDeclaration and node.body[ 0].name == java_constants.ARTIFICIAL_WRAPPER: ''' functions with name artificial wrapper means you should only translate the body of that function not the function header and body. ''' gast["body"] = java_router.node_to_gast(node.body[0].body) else: gast["body"] = java_router.node_to_gast(node.body) return gast
def node_list_to_gast_list(node): ''' Takes list of nodes and converts to a list of equivalent gast nodes ''' gast_list = [] for i in range(0, len(node)): gast_list.append(java_router.node_to_gast(node[i])) return gast_list
def assign_to_gast(node): """ Handles java var declarations to generic AST node """ gast = {"type": "varAssign", "kind": "let"} gast["varValue"] = java_router.node_to_gast(node.initializer) # var name stored as string but we don't want to return gast string node gast["varId"] = {"type": "name", "value": node.name} return gast
def member_reference_to_gast(node): """ Handles increment and decrement operators """ gast = {"type": "augAssign"} if len(node.postfix_operators) == 0: return {"type": "error", "value": "unsupported"} gast["left"] = java_router.node_to_gast(node.member) gast["op"] = node.postfix_operators[0] return gast
def array_to_gast(node): ''' Takes an array of java ast nodes and converts to gast array node ''' gast = {"type": "arr"} gast_list = [] for i in range(0, len(node)): gast_list.append(java_router.node_to_gast(node[i])) gast["elements"] = gast_list return gast
def method_invocation_to_gast(node): gast = {"type": "funcCall"} gast["args"] = java_router.node_to_gast(node.arguments) #TODO: change logic and add support for functions called on objects if node.qualifier == "System.out" and node.member == "println": gast["value"] = {"type": "logStatement"} else: # function called on object if node.qualifier: object_list = (node.qualifier.split(".")) object_list.append(node.member) gast["value"] = list_to_attribute_value_node(object_list) else: gast["value"] = {"type": "name", "value": node.member} return gast
def function_delcaration_to_gast(node): gast = {"type": "functionDeclaration"} gast["params"] = java_router.node_to_gast(node.parameters) gast["id"] = {"type": "name", "value": node.name} gast["body"] = java_router.node_to_gast(node.body) return gast