Path: blob/master/elisp/emacs-for-python/rope-dist/rope/refactor/wildcards.py
1428 views
from rope.base import ast, evaluate, builtins, pyobjects1from rope.refactor import patchedast, occurrences234class Wildcard(object):56def get_name(self):7"""Return the name of this wildcard"""89def matches(self, suspect, arg):10"""Return `True` if `suspect` matches this wildcard"""111213class Suspect(object):1415def __init__(self, pymodule, node, name):16self.name = name17self.pymodule = pymodule18self.node = node192021class DefaultWildcard(object):22"""The default restructuring wildcard2324The argument passed to this wildcard is in the25``key1=value1,key2=value2,...`` format. Possible keys are:2627* name - for checking the reference28* type - for checking the type29* object - for checking the object30* instance - for checking types but similar to builtin isinstance31* exact - matching only occurrences with the same name as the wildcard32* unsure - matching unsure occurrences3334"""3536def __init__(self, project):37self.project = project3839def get_name(self):40return 'default'4142def matches(self, suspect, arg=''):43args = parse_arg(arg)4445if not self._check_exact(args, suspect):46return False47if not self._check_object(args, suspect):48return False49return True5051def _check_object(self, args, suspect):52kind = None53expected = None54unsure = args.get('unsure', False)55for check in ['name', 'object', 'type', 'instance']:56if check in args:57kind = check58expected = args[check]59if expected is not None:60checker = _CheckObject(self.project, expected,61kind, unsure=unsure)62return checker(suspect.pymodule, suspect.node)63return True6465def _check_exact(self, args, suspect):66node = suspect.node67if args.get('exact'):68if not isinstance(node, ast.Name) or not node.id == suspect.name:69return False70else:71if not isinstance(node, ast.expr):72return False73return True747576def parse_arg(arg):77if isinstance(arg, dict):78return arg79result = {}80tokens = arg.split(',')81for token in tokens:82if '=' in token:83parts = token.split('=', 1)84result[parts[0].strip()] = parts[1].strip()85else:86result[token.strip()] = True87return result888990class _CheckObject(object):9192def __init__(self, project, expected, kind='object', unsure=False):93self.project = project94self.kind = kind95self.unsure = unsure96self.expected = self._evaluate(expected)9798def __call__(self, pymodule, node):99pyname = self._evaluate_node(pymodule, node)100if pyname is None or self.expected is None:101return self.unsure102if self._unsure_pyname(pyname, unbound=self.kind=='name'):103return True104if self.kind == 'name':105return self._same_pyname(self.expected, pyname)106else:107pyobject = pyname.get_object()108if self.kind == 'object':109objects = [pyobject]110if self.kind == 'type':111objects = [pyobject.get_type()]112if self.kind == 'instance':113objects = [pyobject]114objects.extend(self._get_super_classes(pyobject))115objects.extend(self._get_super_classes(pyobject.get_type()))116for pyobject in objects:117if self._same_pyobject(self.expected.get_object(), pyobject):118return True119return False120121def _get_super_classes(self, pyobject):122result = []123if isinstance(pyobject, pyobjects.AbstractClass):124for superclass in pyobject.get_superclasses():125result.append(superclass)126result.extend(self._get_super_classes(superclass))127return result128129def _same_pyobject(self, expected, pyobject):130return expected == pyobject131132def _same_pyname(self, expected, pyname):133return occurrences.same_pyname(expected, pyname)134135def _unsure_pyname(self, pyname, unbound=True):136return self.unsure and occurrences.unsure_pyname(pyname, unbound)137138def _split_name(self, name):139parts = name.split('.')140expression, kind = parts[0], parts[-1]141if len(parts) == 1:142kind = 'name'143return expression, kind144145def _evaluate_node(self, pymodule, node):146scope = pymodule.get_scope().get_inner_scope_for_line(node.lineno)147expression = node148if isinstance(expression, ast.Name) and \149isinstance(expression.ctx, ast.Store):150start, end = patchedast.node_region(expression)151text = pymodule.source_code[start:end]152return evaluate.eval_str(scope, text)153else:154return evaluate.eval_node(scope, expression)155156def _evaluate(self, code):157attributes = code.split('.')158pyname = None159if attributes[0] in ('__builtin__', '__builtins__'):160class _BuiltinsStub(object):161def get_attribute(self, name):162return builtins.builtins[name]163def __getitem__(self, name):164return builtins.builtins[name]165def __contains__(self, name):166return name in builtins.builtins167pyobject = _BuiltinsStub()168else:169pyobject = self.project.pycore.get_module(attributes[0])170for attribute in attributes[1:]:171pyname = pyobject[attribute]172if pyname is None:173return None174pyobject = pyname.get_object()175return pyname176177178