def visit_TryExcept(self, node): if node.orelse: raise NotImplementedError('Try-except else handler not implemented') self.indent() self.output('try') self.block(node.body, context=BlockContext(self.stack[-1])) self.output(' catch($e) ') self.push(BlockContext(self.stack[-1])) if_start = None if_end = None for handler in node.handlers: if handler.type is not None: if handler.name is not None: body = handler.body[:] body.insert(0, ast.Assign( [handler.name], ast_call(ast_load('JS'), ast.Str('$e')) )) else: body = handler.body types = [handler.type] if isinstance(handler.type, _ast.Name) else handler.type conditions = [ ast_call( ast_load('isinstance'), ast_call(ast_load('JS'), ast.Str('$e')), type_, ) for type_ in types ] _if = ast.If( ast.BoolOp(ast.Or(), conditions), body, [] ) if if_start is None: if_start = if_end = _if else: if_end.orelse, if_end = [_if], _if else: if handler is not node.handlers[-1]: raise SyntaxError("default 'except:' must be last") if if_start is None: self.block(handler.body) else: if_end.orelse = handler.body if if_start is not None: self.visit(if_start) self.pop() self.output('\n')
class TestBlockContextWithParent: def setUp(self): p = BlockContext(None) self.c = BlockContext(p) def test_indent(self): assert self.c.indent == 2 def test_add_str(self): self.c.add('foo') assert str(self.c) == '{\nfoo }'
class TestBlockContext: def setUp(self): self.c = BlockContext(None) self.c2 = BlockContext(self.c) def test_indent(self): assert self.c.indent == 0 assert self.c2.indent == 2 def test_str(self): assert str(self.c) == '{\n}' def test_add_str(self): self.c.add('foo') assert str(self.c) == '{\nfoo}'
def visit_While(self, node): self.indent() self.output('while(') self.visit(node.test) self.output(') ') self.block(node.body, context=BlockContext(self.stack[-1])) self.output('\n')
def visit_If(self, node, skip_indent=False): if not skip_indent: self.indent() self.output('if(') self.visit(node.test) self.output(') ') self.block(node.body, context=BlockContext(self.stack[-1])) if node.orelse: self.output(' else ') if len(node.orelse) == 1 and isinstance(node.orelse[0], _ast.If): self.visit_If(node.orelse[0], True) else: self.block(node.orelse, context=BlockContext(self.stack[-1])) self.output('\n') else: self.output('\n')
def visit_For(self, node): if node.orelse: raise Exception('for-else is not supported.') if isinstance(node.iter, _ast.Call) and isinstance(node.iter.func, _ast.Name) and \ node.iter.func.id == 'range': if len(node.iter.args) == 1: start = ast.Num(0) stop = node.iter.args[0] step = ast.Num(1) cmp_op = ast.Lt() elif len(node.iter.args) == 2: start = node.iter.args[0] stop = node.iter.args[1] step = ast.Num(1) cmp_op = ast.Lt() elif len(node.iter.args) == 3: start = node.iter.args[0] stop = node.iter.args[1] step = node.iter.args[2] if not isinstance(step, _ast.Num): raise Exception( 'range() only supports literal numeric step') if step.n >= 0: cmp_op = ast.Lt() else: cmp_op = ast.Gt() else: raise Exception('range() expects 1, 2 or 3 parameters') self.indent() self.output('for(') self.visit(node.target) self.output(' = ') self.visit(start) self.output('; ') self.visit(ast.Compare(node.target, [cmp_op], [stop])) self.output('; ') self.visit(node.target) self.output(' += ') self.visit(step) self.output(') ') else: self.indent() self.output('for(') self.visit(node.target) self.output(' in ') self.visit(node.iter) self.output(') ') self.block(node.body, context=BlockContext(self.stack[-1])) self.output('\n')
def visit_Dict(self, node): self.push(context=BlockContext(self.stack[-1])) first = True for key, value in zip(node.keys, node.values): if not isinstance(key, _ast.Str) and \ not isinstance(key, _ast.Num): raise Exception( 'Dictionary keys can only be variables, strings or numbers' ) if not first: self.output(',\n') else: first = False self.indent() self.visit(key) self.output(': ') self.visit(value) self.output('\n') self.pop()
def setUp(self): self.c = BlockContext(None) self.c2 = BlockContext(self.c)
def setUp(self): p = BlockContext(None) self.c = BlockContext(p)