示例#1
0
文件: tests.py 项目: tomaskulich/inf
class TestResolve(unittest.TestCase): #{{{

    def setUp(self):
        pr_num=Typez(kind='prim', node=ast.Num())
        pr_str=Typez(kind='prim', node=ast.Str())
        self.scope=Scope(is_root=True)
        self.scope.update({'xxx':pr_str})

        scope1=Scope(parent=self.scope)
        scope1.update({'a': pr_num, 'b': pr_str})
        self.type1=Typez(kind='obj', scope=scope1)

        scope2=Scope(parent=self.scope)
        scope2.update({'c': pr_num, 'd': pr_str})
        self.type2=Typez(kind='obj', scope=scope2)
        self.type2=scope2

        scope12=Scope(parent=self.scope)
        scope12.update({'a':self.type1, 'b': self.type2})
        self.type12=Typez(kind='obj', scope=scope12)

        self.type3=Typez(kind='multi', scope=Scope(parent=self.scope))
        self.type3.multi=[self.type12, self.type1]

        self.scope.update({'type1':self.type1, 'type2': self.type2, 'type12': self.type12, 'type3': self.type3})

    def test_resolve_type1_in_scope(self):
        res=self.scope.resolve('type1', 'straight')
        self.assertEqual(res, self.type1)

    def test_resolve_in_type(self):
        res=self.type1.resolve('a', 'straight')
        self.assertEqual(res.kind,'prim')
        self.assertIsInstance(res.node, ast.Num)
        self.assertEqual(self.scope.resolve('c', 'straight').value, 'None')

    def test_resolve_multi(self):
        res=self.type3.resolve('a', 'straight')
        self.assertEqual(res.kind,'multi')
        self.assertEqual(len(res.multi),2)
        prim=[val_type for _type in res.multi for key,val_type in _type.scope.items() if _type.kind=='prim']
        self.assertEqual(len(prim),1)

    def test_resolve_cascade(self):
        self.assertRaises(Exception, self.type1.resolve, 'xxx','cascade')
        res1=self.type1.scope.resolve('xxx','cascade')
        res2=self.scope.resolve('xxx','straight')
        self.assertEqual(res1,res2)

    def test_resolve_class(self):
        num=self.type1.resolve('a', 'straight')
        self.assertRaises(Exception, num, '__add__','cascade')
        self.assertRaises(Exception, num, '__add__','straight')
        add=num.resolve('__add__', 'class')
        self.assertIsInstance(add, Typez)
        self.assertEqual(add.kind, 'func')
        self.assertIsInstance(add.node, ast.FunctionDef)
示例#2
0
文件: tests.py 项目: kapucko/dipl
class TestResolve(InferTestCase): #{{{

    def setUp(self):
        num_class = Typez(kind = 'class')
        num_class.scope['__add__'] = Typez(kind = 'func')

        pr_num = Typez(kind = 'pr_num', __class__ = num_class )
        pr_str = Typez(kind = 'pr_str')
        self.scope = Scope(is_root = True)
        self.scope.update({'xxx':pr_str})

        scope1 = Scope(parent = self.scope)
        scope1.update({'a': pr_num, 'b': pr_str})
        self.type1 = Typez(kind = 'obj', scope = scope1)

        scope2 = Scope(parent = self.scope)
        scope2.update({'c': pr_num, 'd': pr_str})
        self.type2 = Typez(kind = 'obj', scope = scope2)
        self.type2 = scope2

        scope12 = Scope(parent = self.scope)
        scope12.update({'a':self.type1, 'b': self.type2})
        self.type12 = Typez(kind = 'obj', scope = scope12)

        self.scope.update({'type1':self.type1, 'type2': self.type2, 'type12': self.type12})

    def test_resolve_type1_in_scope(self):
        res = self.scope.resolve('type1', 'straight')
        self.assertEqual(res, self.type1)

    def test_resolve_in_type(self):
        res = self.type1.resolve('a', 'straight')
        self.assertEqual(res.kind,'pr_num')
        self.assertEqual(self.scope.resolve('c'), None)


    def test_resolve_cascade(self):
        self.assertRaises(Exception, self.type1.resolve, 'xxx','cascade')
        res1 = self.type1.scope.resolve('xxx','cascade')
        res2 = self.scope.resolve('xxx','straight')
        self.assertEqual(res1,res2)

    def test_resolve_class(self):

        num = self.type1.resolve('a', 'straight')
        self.assertRaises(Exception, num.resolve, '__add__', 'cascade')
        add = num.resolve('__add__', 'straight')
        self.assertEqual(add, None)
        add = num.resolve('__add__', 'class')
        self.assertIsInstance(add, Typez)
        self.assertEqual(add.kind, 'func')
示例#3
0
    def exec_Call(self, node, scope):
        #first let's find out which function should be called. This should be easy when doing func()
        #call, but it can be tricky when using constructs such as 'a.b.c.func()'
        self_type=None
        #covers func() case
        if isinstance(node.func,ast.Name):
            logger.debug("? exec_Call "+node.func.id +" "+str(node))
            call_type=scope.resolve(node.func.id,'cascade')
        #covers a.b.c.func() case
        elif isinstance(node.func, ast.Attribute):
            logger.debug("? exec_Call "+node.func.attr +" "+str(node))
            call_type=self.eval_code(node.func, scope)
            if typez.is_none(call_type):
                self.warn(node.func, message='nonexistent_attribute', symbol=node.func.attr)
                return typez.none_type

            #whether we are dealing with function or with a method should be already resolved by
            #exec_Attribute
            if hasattr(call_type, 'is_method'):
                if call_type.is_method:
                    self_type=self.eval_code(node.func.value, scope)
        else:
            raise Exception('should not get here')

        #now we know what to invoke. Now we must distinguist whether it is func/method call or 'new'
        #statement.

        #Call-ing function or method
        if call_type.kind=='func':
            args=[self.eval_code(arg,scope) for arg in node.args]
            if self_type:
                args=[self_type]+args
            return self._exec_fun(call_type, args, call_type.scope)

        #Call-ing as a 'new' statement 
        if call_type.kind=='class':
            args=[self.eval_code(arg,scope) for arg in node.args]
            new=Typez(kind='obj', scope=Scope(parent=call_type.scope))
            args=[new]+args
            new.scope['__class__']=call_type
            constructor=call_type.resolve('__init__', 'straight')
            new.obj=self._exec_fun(constructor, args, new.scope)
            return new
        raise Exception('calling node must be either function or class')
示例#4
0
文件: parse_ast.py 项目: kapucko/dipl
    def exec_Call(self, node, scope):
        #first let's find out which function should be called. This should be easy when doing func()
        #call, but it can be tricky when using constructs such as 'a.b.c.func()'

        #covers func() case
        if isinstance(node.func, ast.Name):
            logger.debug("? exec_Call "+node.func.id +" "+str(node))
            call_type = scope.resolve(node.func.id,'cascade')
            if call_type is None:
               call_type = any_type 
        #covers a.b.c.func() case
        elif isinstance(node.func, ast.Attribute):
            logger.debug("? exec_Call "+node.func.attr +" "+str(node))
            call_type = self.eval_code(node.func, scope)
            if call_type.kind == 'any':
                return any_type

        else:
            raise Exception('should not get here')

        #now we know what to invoke. Now we must distinguish whether it is func/method call or 'new'
        #statement.

        #TODO: dorobit spustanie 'any' kind
        #Call-ing function or method
        if call_type.kind == 'func':
            args = [self.eval_code(arg, scope) for arg in node.args]
            if call_type.is_method:
                args = [call_type.self_obj]+args
            return self._exec_fun(call_type, args, call_type.scope, node=node)

        #Call-ing as a 'new' statement 
        if call_type.kind == 'class':
            args = [self.eval_code(arg,scope) for arg in node.args]
            new = Typez(kind = 'obj', parent_scope = scope)
            args = [new]+args
            new.scope['__class__'] = call_type
            constructor = call_type.resolve('__init__', 'class')
            if constructor:
                new.obj = self._exec_fun(constructor, args, new.scope, node=node)
            return new
        self.warn(node, message = 'nonexistent_function', symbol = node.func.id)
示例#5
0
文件: tests.py 项目: kapucko/dipl
    def setUp(self):
        num_class = Typez(kind = 'class')
        num_class.scope['__add__'] = Typez(kind = 'func')

        pr_num = Typez(kind = 'pr_num', __class__ = num_class )
        pr_str = Typez(kind = 'pr_str')
        self.scope = Scope(is_root = True)
        self.scope.update({'xxx':pr_str})

        scope1 = Scope(parent = self.scope)
        scope1.update({'a': pr_num, 'b': pr_str})
        self.type1 = Typez(kind = 'obj', scope = scope1)

        scope2 = Scope(parent = self.scope)
        scope2.update({'c': pr_num, 'd': pr_str})
        self.type2 = Typez(kind = 'obj', scope = scope2)
        self.type2 = scope2

        scope12 = Scope(parent = self.scope)
        scope12.update({'a':self.type1, 'b': self.type2})
        self.type12 = Typez(kind = 'obj', scope = scope12)

        self.scope.update({'type1':self.type1, 'type2': self.type2, 'type12': self.type12})
示例#6
0
文件: tests.py 项目: tomaskulich/inf
    def setUp(self):
        pr_num=Typez(kind='prim', node=ast.Num())
        pr_str=Typez(kind='prim', node=ast.Str())
        self.scope=Scope(is_root=True)
        self.scope.update({'xxx':pr_str})

        scope1=Scope(parent=self.scope)
        scope1.update({'a': pr_num, 'b': pr_str})
        self.type1=Typez(kind='obj', scope=scope1)

        scope2=Scope(parent=self.scope)
        scope2.update({'c': pr_num, 'd': pr_str})
        self.type2=Typez(kind='obj', scope=scope2)
        self.type2=scope2

        scope12=Scope(parent=self.scope)
        scope12.update({'a':self.type1, 'b': self.type2})
        self.type12=Typez(kind='obj', scope=scope12)

        self.type3=Typez(kind='multi', scope=Scope(parent=self.scope))
        self.type3.multi=[self.type12, self.type1]

        self.scope.update({'type1':self.type1, 'type2': self.type2, 'type12': self.type12, 'type3': self.type3})
示例#7
0
文件: parse_ast.py 项目: kapucko/dipl
 def exec_List(self, node, scope):
     res = Typez(kind = 'obj', node = node, klass_name = 'inf_list')
     for item in node.elts:
         item_val = self.eval_code(item, scope)
         append = res.resolve('append', 'class')
         self._exec_fun(append, item_val, scope, node=node)