예제 #1
0
파일: visitor.py 프로젝트: yang/pystarch
    def visit_If(self, node):
        self.check_type(node.test, Bool())
        test_value = static_evaluate(node.test, self.context())
        if not isinstance(test_value, UnknownValue):
            self.warn('constant-if-condition', node)

        ext_ctx = self.context()
        if_inferences, else_inferences = maybe_inferences(node.test, ext_ctx)

        # don't visit unreachable code
        if test_value is True:
            self._visit_branch(node.body, if_inferences)
            return
        if test_value is False:
            self._visit_branch(node.orelse, else_inferences)
            return

        if_scope = self._visit_branch(node.body, if_inferences)
        else_scope = self._visit_branch(node.orelse, else_inferences)

        diffs = set(if_scope.names()) ^ set(else_scope.names())
        for diff in diffs:
            if diff not in self._context:
                self.warn('conditionally-assigned', node, diff)

        common = set(if_scope.names()) & set(else_scope.names())
        for name in common:
            types = [if_scope.get_type(name), else_scope.get_type(name)]
            unified_type = unify_types(types)
            self._context.add(Symbol(name, unified_type))
            if isinstance(unified_type, Unknown):
                if not any(isinstance(x, Unknown) for x in types):
                    self.warn('conditional-type', node, name)
예제 #2
0
    def visit_If(self, node):
        self.check_type(node.test, Bool())
        test_value = static_evaluate(node.test, self.context())
        if not isinstance(test_value, UnknownValue):
            self.warn('constant-if-condition', node)

        ext_ctx = self.context()
        if_inferences, else_inferences = maybe_inferences(node.test, ext_ctx)

        # don't visit unreachable code
        if test_value is True:
            self._visit_branch(node.body, if_inferences)
            return
        if test_value is False:
            self._visit_branch(node.orelse, else_inferences)
            return

        if_scope = self._visit_branch(node.body, if_inferences)
        else_scope = self._visit_branch(node.orelse, else_inferences)

        diffs = set(if_scope.names()) ^ set(else_scope.names())
        for diff in diffs:
            if diff not in self._context:
                self.warn('conditionally-assigned', node, diff)

        common = set(if_scope.names()) & set(else_scope.names())
        for name in common:
            types = [if_scope.get_type(name), else_scope.get_type(name)]
            unified_type = unify_types(types)
            self._context.add(Symbol(name, unified_type))
            if isinstance(unified_type, Unknown):
                if not any(isinstance(x, Unknown) for x in types):
                    self.warn('conditional-type', node, name)
예제 #3
0
파일: visitor.py 프로젝트: yang/pystarch
 def _check_return(self, return_type, static_value=None):
     previous_type = self._context.get_type()
     new_type = (unify_types([previous_type, return_type])
                 if previous_type is not None else return_type)
     value = (static_value or UnknownValue()
              if previous_type is None else UnknownValue())
     self._context.set_return(Symbol('return', new_type, value))
예제 #4
0
 def _check_return(self, return_type, static_value=None):
     previous_type = self._context.get_type()
     new_type = (unify_types([previous_type, return_type])
                 if previous_type is not None else return_type)
     value = (static_value or UnknownValue() if previous_type is None else
              UnknownValue())
     self._context.set_return(Symbol('return', new_type, value))