def test_reserve_name(self):
     scope = codegen.Scope()
     name1 = scope.reserve_name('name')
     name2 = scope.reserve_name('name')
     self.assertEqual(name1, 'name')
     self.assertNotEqual(name1, name2)
     self.assertEqual(name2, 'name2')
 def test_reserve_name_function_arg_disallowed(self):
     scope = codegen.Scope()
     scope.reserve_name('name')
     self.assertRaises(AssertionError,
                       scope.reserve_name,
                       'name',
                       function_arg=True)
 def test_reserve_name_function_arg(self):
     scope = codegen.Scope()
     scope.reserve_function_arg_name('arg_name')
     scope.reserve_name('myfunc')
     func = codegen.Function('myfunc',
                             args=['arg_name'],
                             parent_scope=scope)
     self.assertNotIn('arg_name2', func.all_reserved_names())
 def test_function_call_unknown(self):
     scope = codegen.Scope()
     self.assertRaises(AssertionError,
                       codegen.FunctionCall,
                       'a_function',
                       [],
                       {},
                       scope)
 def test_scope_variable_helper(self):
     # Scope.variable is more convenient than using VariableReference
     # manually, we use that from now on.
     scope = codegen.Scope()
     name = scope.reserve_name('name')
     ref1 = codegen.VariableReference(name, scope)
     ref2 = scope.variable(name)
     self.assertEqual(ref1, ref2)
    def test_reserve_name_nested(self):
        parent = codegen.Scope()
        parent_name = parent.reserve_name('name')
        self.assertEqual(parent_name, 'name')

        child1 = codegen.Scope(parent_scope=parent)
        child2 = codegen.Scope(parent_scope=parent)

        child1_name = child1.reserve_name('name')
        self.assertNotEqual(child1_name, parent_name)

        child2_name = child2.reserve_name('name')
        self.assertNotEqual(child2_name, parent_name)

        # But children can have same names, they don't shadow each other.
        # To be deterministic, we expect the same name
        self.assertEqual(child1_name, child2_name)
 def test_string_join_collapse_strings(self):
     scope = codegen.Scope()
     scope.reserve_name('tmp', properties={codegen.PROPERTY_TYPE: text_type})
     var = scope.variable('tmp')
     join1 = codegen.ConcatJoin.build([
         codegen.String('hello '),
         codegen.String('there '),
         var,
         codegen.String(' how'),
         codegen.String(' are you?'),
     ])
     self.assertCodeEqual(as_source_code(join1), "'hello there ' + tmp + ' how are you?'")
    def test_try_catch_has_assignment_for_name_2(self):
        scope = codegen.Scope()
        try_ = codegen.Try([], scope)
        name = scope.reserve_name('foo')

        # Add to 'except'
        try_.except_block.add_assignment(name, codegen.String('x'))
        self.assertFalse(try_.has_assignment_for_name(name))

        # Add to 'else'
        try_.else_block.add_assignment(name, codegen.String('x'), allow_multiple=True)
        self.assertTrue(try_.has_assignment_for_name(name))
 def test_try_catch_multiple_exceptions(self):
     scope = codegen.Scope()
     scope.reserve_name('MyError')
     scope.reserve_name('OtherError')
     try_ = codegen.Try([scope.variable('MyError'),
                         scope.variable('OtherError')], scope)
     self.assertCodeEqual(as_source_code(try_), """
         try:
             pass
         except (MyError, OtherError):
             pass
     """)
示例#10
0
 def test_variable_reference_function_arg_check(self):
     scope = codegen.Scope()
     func_name = scope.reserve_name('myfunc')
     func = codegen.Function(func_name, args=['my_arg'],
                             parent_scope=scope)
     # Can't use undefined 'some_name'
     self.assertRaises(AssertionError,
                       codegen.VariableReference,
                       'some_name',
                       func)
     # But can use function argument 'my_arg'
     ref = codegen.VariableReference('my_arg', func)
     self.assertCodeEqual(as_source_code(ref), 'my_arg')
示例#11
0
    def test_try_catch_has_assignment_for_name_1(self):
        scope = codegen.Scope()
        try_ = codegen.Try([], scope)
        name = scope.reserve_name('foo')
        self.assertFalse(try_.has_assignment_for_name(name))

        # Just add to 'try' block
        try_.try_block.add_assignment(name, codegen.String('x'))
        # Not all branches define name, so overall can't trust the name
        # to be defined at the end.
        self.assertFalse(try_.has_assignment_for_name(name))

        # Now add to 'except' block as well
        try_.except_block.add_assignment(name, codegen.String('x'), allow_multiple=True)
        self.assertTrue(try_.has_assignment_for_name(name))
示例#12
0
    def test_multiple_add_assignment_in_inherited_scope(self):
        # try/if etc inherit their scope from function
        scope = codegen.Scope()
        scope.reserve_name('myfunc')
        func = codegen.Function('myfunc',
                                args=[],
                                parent_scope=scope)
        try_ = codegen.Try([], func)
        name = func.reserve_name('name')

        # We'd really like to ensure no multiple assignments ever,
        # but the way that if/try etc. work make that hard.
        # Instead, we add a keyword argument to allow the second assignment.
        try_.try_block.add_assignment(name, codegen.Number(1))
        self.assertRaises(AssertionError,
                          try_.try_block.add_assignment,
                          name, codegen.Number(2))
        self.assertRaises(AssertionError,
                          try_.except_block.add_assignment,
                          name, codegen.Number(2))
        try_.except_block.add_assignment(name, codegen.Number(2),
                                         allow_multiple=True)
示例#13
0
 def test_try_catch(self):
     scope = codegen.Scope()
     scope.reserve_name('MyError')
     try_ = codegen.Try([scope.variable('MyError')], scope)
     self.assertCodeEqual(as_source_code(try_), """
         try:
             pass
         except MyError:
             pass
     """)
     scope.reserve_name('x')
     scope.reserve_name('y')
     scope.reserve_name('z')
     try_.try_block.add_assignment('x', codegen.String("x"))
     try_.except_block.add_assignment('y', codegen.String("y"))
     try_.else_block.add_assignment('z', codegen.String("z"))
     self.assertCodeEqual(as_source_code(try_), """
         try:
             x = 'x'
         except MyError:
             y = 'y'
         else:
             z = 'z'
     """)
示例#14
0
 def test_reserve_name_after_reserve_function_arg(self):
     scope = codegen.Scope()
     scope.reserve_function_arg_name('my_arg')
     name = scope.reserve_name('my_arg')
     self.assertEqual(name, 'my_arg2')
示例#15
0
 def test_dict_lookup(self):
     scope = codegen.Scope()
     scope.reserve_name('tmp')
     var = scope.variable('tmp')
     lookup = codegen.DictLookup(var, codegen.String('x'))
     self.assertCodeEqual(as_source_code(lookup), "tmp['x']")
示例#16
0
 def test_variable_reference_check(self):
     scope = codegen.Scope()
     self.assertRaises(AssertionError,
                       codegen.VariableReference,
                       'name',
                       scope)
示例#17
0
 def test_variable_reference(self):
     scope = codegen.Scope()
     name = scope.reserve_name('name')
     ref = codegen.VariableReference(name, scope)
     self.assertEqual(as_source_code(ref), 'name')
示例#18
0
 def test_name_properties(self):
     scope = codegen.Scope()
     scope.reserve_name('name', properties={'FOO': True})
     self.assertEqual(scope.get_name_properties('name'),
                      {'FOO': True})
示例#19
0
 def test_reserve_function_arg_after_reserve_name(self):
     scope = codegen.Scope()
     scope.reserve_name('my_arg')
     self.assertRaises(AssertionError,
                       scope.reserve_function_arg_name,
                       'my_arg')