def visit_ListComp(self, node): gen = node.generators[0] start = 0 end = 0 if type(gen.iter) == ast.Call and gen.iter.func.id.endswith('range'): # This is really a special-case hacking of [... for i in # range(i)] comprehensions that are used in the polyglot # tests sometimes. It won't handle translating arbitrary # comprehensions to Java streams. if len(gen.iter.args) == 1: end = gen.iter.args[0].n elif len(gen.iter.args) == 2: start = gen.iter.args[0].n end = gen.iter.args[1].n else: # Somebody came up with a creative new use for # comprehensions in the test suite... raise Unhandled("ListComp hack couldn't handle: ", ast.dump(node)) self.write("(func() []interface{} {\n") self.write(" res := []interface{}{}\n") self.write(" for iterator_ := %s; iterator_ < %s; iterator_++ {\n" % (start, end)) self.write(" ") self.visit(gen.target) self.write(" := iterator_\n") self.write(" res = append(res, ") self.visit(node.elt) self.write(")\n") self.write(" }\n") self.write(" return res\n") self.write("}())")
def visit_ListComp(self, node): gen = node.generators[0] if type(gen.iter) == ast.Call and gen.iter.func.id.endswith('range'): # This is really a special-case hacking of [... for i in # range(i)] comprehensions that are used in the polyglot # tests sometimes. It won't handle translating arbitrary # comprehensions to Java streams. self.write("LongStream.range(") if len(gen.iter.args) == 1: self.write("0, ") self.visit(gen.iter.args[0]) elif len(gen.iter.args) == 2: self.visit(gen.iter.args[0]) self.write(", ") self.visit(gen.iter.args[1]) self.write(").boxed()") else: # Somebody came up with a creative new use for # comprehensions in the test suite... raise Unhandled("ListComp hack couldn't handle: ", ast.dump(node)) self.write(".map(") self.visit(gen.target) self.write(" -> ") self.visit(node.elt) self.write(").collect(Collectors.toList())")
def visit_BinOp(self, node): opMap = { ast.Add: " + ", ast.Sub: " - ", ast.Mult: " * ", ast.Div: " / ", ast.Mod: " % ", } if self.is_string_mul(node): return if self.is_array_concat(node): return if self.is_byte_array_add(node): return t = type(node.op) if t in opMap.keys(): self.visit(node.left) self.write(opMap[t]) self.visit(node.right) elif t == ast.Pow: if type(node.left) == ast.Num and node.left.n == 2: self.visit(node.left) self.write(" << ") self.visit(node.right) else: raise Unhandled("Can't do exponent with non 2 base")
def get_bound(bound, default): if bound is None: return default elif type(bound) == ast.UnaryOp and type(bound.op) == ast.USub: return -bound.operand.n elif type(bound) == ast.Num: return bound.n else: raise Unhandled("Not handling bound: %s" % ast.dump(bound))
def visit_Subscript(self, node): if node.slice is None or type(node.slice.value) != ast.Num: logger.error("While doing: %s", ast.dump(node)) raise Unhandled("Only integers subscript can be converted." " Got %s" % node.slice.value.s) self.visit(node.value) self.write(".get(") self.write(str(node.slice.value.n)) self.write(")")
def visit_NameConstant(self, node): if node.value is None: self.write("null") elif node.value is True: self.write("true") elif node.value is False: self.write("false") else: raise Unhandled("Don't know NameConstant with value %s" % node.value)
def py_to_go_type(py_type): '''Converts python types to their Go equivalents''' if py_type is None: return None elif isinstance(py_type, str): # This can be called on something already converted return py_type elif py_type.__name__ == 'function': return 'func()' elif (py_type.__module__ == 'datetime' and py_type.__name__ == 'datetime'): return 'time.Time' elif py_type.__module__ == 'builtins': if py_type.__name__.endswith('Error'): return 'error' return { bool: 'bool', bytes: '[]byte', int: 'int', float: 'float64', str: 'string', dict: 'map[interface{}]interface{}', list: '[]interface{}', object: 'map[interface{}]interface{}', type(None): 'interface{}', }[py_type] elif py_type.__module__ == 'rethinkdb.ast': return "r.Term" # Anomalous non-rule based capitalization in the python driver # return { # }.get(py_type.__name__, py_type.__name__) elif py_type.__module__ == 'rethinkdb.errors': return py_type.__name__ elif py_type.__module__ == '?test?': return { 'int_cmp': 'int', 'float_cmp': 'float64', 'err_regex': 'Err', 'partial': 'compare.Expected', 'bag': 'compare.Expected', 'uuid': 'compare.Regex', # clashes with ast.Uuid }.get(py_type.__name__, camel(py_type.__name__)) elif py_type.__module__ == 'rethinkdb.query': # All of the constants like minval maxval etc are defined in # query.py, but no type name is provided to `type`, so we have # to pull it out of a class variable return camel(py_type.st) else: raise Unhandled( "Don't know how to convert python type {}.{} to Go".format( py_type.__module__, py_type.__name__))
def visit_Assign(self, node): if len(node.targets) != 1: Unhandled("We only support assigning to one variable") type = self.compute_type(node) self.write(type + " ") self.write(node.targets[0].id) self.write(" = (") self.write(type) self.write(") (") if is_reql(self._type): ReQLVisitor(self.reql_vars, out=self.out, type_=type, is_def=True).visit(node.value) else: self.visit(node.value) self.write(");")
def to_args_optargs(self, func='', optargs=[]): optarg_aliases = { 'JsOpts': 'JSOpts', 'HttpOpts': 'HTTPOpts', 'Iso8601Opts': 'ISO8601Opts', 'IndexCreateFuncOpts': 'IndexCreateOpts' } optarg_field_aliases = { 'nonvoting_replica_tags': 'NonVotingReplicaTags', } if not func: raise Unhandled("Missing function name") optarg_type = camel(func) + 'Opts' optarg_type = optarg_aliases.get(optarg_type, optarg_type) optarg_type = 'r.' + optarg_type self.write('.OptArgs(') self.write(optarg_type) self.write('{') for optarg in optargs: # Hack to skip tests that check for unknown opt args, # this is not possible in Go due to static types if optarg.arg == 'return_vals': self.skip( "test not required since optargs are statically typed") return if optarg.arg == 'foo': self.skip( "test not required since optargs are statically typed") return if type(optarg.value) == ast.Name and optarg.value.id == 'null': self.skip( "test not required since go does not support null optargs") return field_name = optarg_field_aliases.get(optarg.arg, camel(optarg.arg)) self.write(field_name) self.write(": ") self.cast_null(optarg.value) self.write(', ') self.write('})')
def py_to_java_type(py_type, node): """Converts python types to their Java equivalents""" if py_type is None: return None elif isinstance(py_type, str): # This can be called on something already converted return py_type elif py_type.__name__ == "function": return "ReqlFunction1" elif py_type.__module__ == "datetime" and py_type.__name__ == "datetime": return "OffsetDateTime" elif py_type.__module__ == "builtins": return { bool: "Boolean", bytes: "byte[]", int: "Long", float: "Double", str: "String", dict: "Map", list: "List", object: "Object", type(None): "Object", }[py_type] elif py_type.__module__ == "rethinkdb.ast": # Anomalous non-rule based capitalization in the python driver return {"DB": "Db"}.get(py_type.__name__, py_type.__name__) elif py_type.__module__ == "rethinkdb.errors": return py_type.__name__ elif py_type.__module__ == "?test?": return { "uuid": "UUIDMatch" }.get( # clashes with ast.Uuid py_type.__name__, metajava.camel(py_type.__name__)) elif py_type.__module__ == "rethinkdb.query": # All of the constants like minval maxval etc are defined in # query.py, but no type name is provided to `type`, so we have # to pull it out of a class variable assert py_type.__name__ == "RqlConstant" return metajava.camel(node.st) else: raise Unhandled( "Don't know how to convert python type {}.{} to java".format( py_type.__module__, py_type.__name__))
def visit_Compare(self, node): opMap = { ast.Lt: "lt", ast.Gt: "gt", ast.GtE: "ge", ast.LtE: "le", ast.Eq: "eq", ast.NotEq: "ne", } if len(node.ops) != 1: # Python syntax allows chained comparisons (a < b < c) but # we don't deal with that here raise Unhandled("Compare hack bailed on: ", ast.dump(node)) left = node.left right = node.comparators[0] func_name = opMap[type(node.ops[0])] if self.is_not_reql(node.left): self.prefix(func_name, left, right) else: self.infix(func_name, left, right)
def py_to_java_type(py_type): '''Converts python types to their Java equivalents''' if py_type is None: return None elif isinstance(py_type, str): # This can be called on something already converted return py_type elif py_type.__name__ == 'function': return 'ReqlFunction1' elif (py_type.__module__ == 'datetime' and py_type.__name__ == 'datetime'): return 'OffsetDateTime' elif py_type.__module__ == 'builtins': return { bool: 'Boolean', bytes: 'byte[]', int: 'Long', float: 'Double', str: 'String', dict: 'Map', list: 'List', object: 'Object', type(None): 'Object', }[py_type] elif py_type.__module__ == 'rethinkdb.ast': # Anomalous non-rule based capitalization in the python driver return {'DB': 'Db'}.get(py_type.__name__, py_type.__name__) elif py_type.__module__ == 'rethinkdb.errors': return py_type.__name__ elif py_type.__module__ == '?test?': return { 'uuid': 'UUIDMatch', # clashes with ast.Uuid }.get(py_type.__name__, metajava.camel(py_type.__name__)) elif py_type.__module__ == 'rethinkdb.query': # All of the constants like minval maxval etc are defined in # query.py, but no type name is provided to `type`, so we have # to pull it out of a class variable return metajava.camel(py_type.st) else: raise Unhandled( "Don't know how to convert python type {}.{} to java".format( py_type.__module__, py_type.__name__))
def visit_Assign(self, node): if len(node.targets) != 1: Unhandled("We only support assigning to one variable") var = node.targets[0].id self.write("var " + var + " ") if is_reql(self._type): self.write('r.Term') else: self.write(self.type) self.write(" = ") if is_reql(self._type): ReQLVisitor( self.reql_vars, out=self.out, type_=self.type, is_def=True, ).visit(node.value) elif var == 'upper_limit': # Manually set value since value in test causes an error self.write('2<<52 - 1') elif var == 'lower_limit': # Manually set value since value in test causes an error self.write('1 - 2<<52') else: self.visit(node.value)
def visit_Subscript(self, node): self.visit(node.value) if type(node.slice) == ast.Index: # Syntax like a[2] or a["b"] if self.smart_bracket and type(node.slice.value) == ast.Str: self.write(".g(") elif self.smart_bracket and type(node.slice.value) == ast.Num: self.write(".nth(") else: self.write(".bracket(") self.visit(node.slice.value) self.write(")") elif type(node.slice) == ast.Slice: # Syntax like a[1:2] or a[:2] self.write(".slice(") lower, upper, rclosed = self.get_slice_bounds(node.slice) self.write(str(lower)) self.write(", ") self.write(str(upper)) self.write(")") if rclosed: self.write('.optArg("right_bound", "closed")') else: raise Unhandled("No translation for ExtSlice")
def visit_Subscript(self, node): self.visit(node.value) if type(node.slice) == ast.Index: # Syntax like a[2] or a["b"] if self.smart_bracket and type(node.slice.value) == ast.Str: self.write(".Field(") elif self.smart_bracket and type(node.slice.value) == ast.Num: self.write(".Nth(") else: self.write(".AtIndex(") self.visit(node.slice.value) self.write(")") elif type(node.slice) == ast.Slice: # Syntax like a[1:2] or a[:2] self.write(".Slice(") lower, upper, rclosed = self.get_slice_bounds(node.slice) self.write(str(lower)) self.write(", ") self.write(str(upper)) if rclosed: self.write(', r.SliceOpts{RightBound: "closed"}') self.write(")") else: raise Unhandled("No translation for ExtSlice")
def generic_visit(self, node): logger.error("While translating: %s", ast.dump(node)) logger.error("Got as far as: %s", ''.join(self.out)) raise Unhandled("Don't know what this thing is: " + str(type(node)))