PageRenderTime 23ms CodeModel.GetById 13ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/logilab-astng-0.23.1/mixins.py

#
Python | 136 lines | 62 code | 20 blank | 54 comment | 8 complexity | 24622beccb850d24e1370f1bb54db44d MD5 | raw file
  1# This program is free software; you can redistribute it and/or modify it under
  2# the terms of the GNU Lesser General Public License as published by the Free Software
  3# Foundation; either version 2 of the License, or (at your option) any later
  4# version.
  5#
  6# This program is distributed in the hope that it will be useful, but WITHOUT
  7# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  9#
 10# You should have received a copy of the GNU Lesser General Public License along with
 11# this program; if not, write to the Free Software Foundation, Inc.,
 12# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 13# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 14# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 15# copyright 2003-2010 Sylvain Thenault, all rights reserved.
 16# contact mailto:thenault@gmail.com
 17#
 18# This file is part of logilab-astng.
 19#
 20# logilab-astng is free software: you can redistribute it and/or modify it
 21# under the terms of the GNU Lesser General Public License as published by the
 22# Free Software Foundation, either version 2.1 of the License, or (at your
 23# option) any later version.
 24#
 25# logilab-astng is distributed in the hope that it will be useful, but
 26# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 27# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 28# for more details.
 29#
 30# You should have received a copy of the GNU Lesser General Public License along
 31# with logilab-astng. If not, see <http://www.gnu.org/licenses/>.
 32"""This module contains some mixins for the different nodes.
 33"""
 34
 35from logilab.astng.exceptions import (ASTNGBuildingException, InferenceError,
 36                                      NotFoundError)
 37
 38
 39class BlockRangeMixIn(object):
 40    """override block range """
 41    def set_line_info(self, lastchild):
 42        self.fromlineno = self.lineno
 43        self.tolineno = lastchild.tolineno
 44        self.blockstart_tolineno = self._blockstart_toline()
 45
 46    def _elsed_block_range(self, lineno, orelse, last=None):
 47        """handle block line numbers range for try/finally, for, if and while
 48        statements
 49        """
 50        if lineno == self.fromlineno:
 51            return lineno, lineno
 52        if orelse:
 53            if lineno >= orelse[0].fromlineno:
 54                return lineno, orelse[-1].tolineno
 55            return lineno, orelse[0].fromlineno - 1
 56        return lineno, last or self.tolineno
 57
 58class FilterStmtsMixin(object):
 59    """Mixin for statement filtering and assignment type"""
 60
 61    def _get_filtered_stmts(self, _, node, _stmts, mystmt):
 62        """method used in _filter_stmts to get statemtents and trigger break"""
 63        if self.statement() is mystmt:
 64            # original node's statement is the assignment, only keep
 65            # current node (gen exp, list comp)
 66            return [node], True
 67        return _stmts, False
 68
 69    def ass_type(self):
 70        return self
 71
 72
 73class AssignTypeMixin(object):
 74
 75    def ass_type(self):
 76        return self
 77
 78    def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt):
 79        """method used in filter_stmts"""
 80        if self is mystmt:
 81            return _stmts, True
 82        if self.statement() is mystmt:
 83            # original node's statement is the assignment, only keep
 84            # current node (gen exp, list comp)
 85            return [node], True
 86        return _stmts, False
 87
 88
 89class ParentAssignTypeMixin(AssignTypeMixin):
 90
 91    def ass_type(self):
 92        return self.parent.ass_type()
 93
 94
 95
 96class FromImportMixIn(FilterStmtsMixin):
 97    """MixIn for From and Import Nodes"""
 98
 99    def _infer_name(self, frame, name):
100        return name
101
102    def do_import_module(self, modname):
103        """return the ast for a module whose name is <modname> imported by <self>
104        """
105        # handle special case where we are on a package node importing a module
106        # using the same name as the package, which may end in an infinite loop
107        # on relative imports
108        # XXX: no more needed ?
109        mymodule = self.root()
110        level = getattr(self, 'level', None) # Import as no level
111        # XXX we should investigate deeper if we really want to check
112        # importing itself: modname and mymodule.name be relative or absolute
113        if mymodule.relative_to_absolute_name(modname, level) == mymodule.name:
114            # FIXME: we used to raise InferenceError here, but why ?
115            return mymodule
116        try:
117            return mymodule.import_module(modname, level=level)
118        except ASTNGBuildingException:
119            raise InferenceError(modname)
120        except SyntaxError, ex:
121            raise InferenceError(str(ex))
122
123    def real_name(self, asname):
124        """get name from 'as' name"""
125        for name, _asname in self.names:
126            if name == '*':
127                return asname
128            if not _asname:
129                name = name.split('.', 1)[0]
130                _asname = name
131            if asname == _asname:
132                return name
133        raise NotFoundError(asname)
134
135
136