Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
marvel
GitHub Repository: marvel/qnf
Path: blob/master/elisp/emacs-for-python/rope-dist/rope/refactor/wildcards.py
1428 views
1
from rope.base import ast, evaluate, builtins, pyobjects
2
from rope.refactor import patchedast, occurrences
3
4
5
class Wildcard(object):
6
7
def get_name(self):
8
"""Return the name of this wildcard"""
9
10
def matches(self, suspect, arg):
11
"""Return `True` if `suspect` matches this wildcard"""
12
13
14
class Suspect(object):
15
16
def __init__(self, pymodule, node, name):
17
self.name = name
18
self.pymodule = pymodule
19
self.node = node
20
21
22
class DefaultWildcard(object):
23
"""The default restructuring wildcard
24
25
The argument passed to this wildcard is in the
26
``key1=value1,key2=value2,...`` format. Possible keys are:
27
28
* name - for checking the reference
29
* type - for checking the type
30
* object - for checking the object
31
* instance - for checking types but similar to builtin isinstance
32
* exact - matching only occurrences with the same name as the wildcard
33
* unsure - matching unsure occurrences
34
35
"""
36
37
def __init__(self, project):
38
self.project = project
39
40
def get_name(self):
41
return 'default'
42
43
def matches(self, suspect, arg=''):
44
args = parse_arg(arg)
45
46
if not self._check_exact(args, suspect):
47
return False
48
if not self._check_object(args, suspect):
49
return False
50
return True
51
52
def _check_object(self, args, suspect):
53
kind = None
54
expected = None
55
unsure = args.get('unsure', False)
56
for check in ['name', 'object', 'type', 'instance']:
57
if check in args:
58
kind = check
59
expected = args[check]
60
if expected is not None:
61
checker = _CheckObject(self.project, expected,
62
kind, unsure=unsure)
63
return checker(suspect.pymodule, suspect.node)
64
return True
65
66
def _check_exact(self, args, suspect):
67
node = suspect.node
68
if args.get('exact'):
69
if not isinstance(node, ast.Name) or not node.id == suspect.name:
70
return False
71
else:
72
if not isinstance(node, ast.expr):
73
return False
74
return True
75
76
77
def parse_arg(arg):
78
if isinstance(arg, dict):
79
return arg
80
result = {}
81
tokens = arg.split(',')
82
for token in tokens:
83
if '=' in token:
84
parts = token.split('=', 1)
85
result[parts[0].strip()] = parts[1].strip()
86
else:
87
result[token.strip()] = True
88
return result
89
90
91
class _CheckObject(object):
92
93
def __init__(self, project, expected, kind='object', unsure=False):
94
self.project = project
95
self.kind = kind
96
self.unsure = unsure
97
self.expected = self._evaluate(expected)
98
99
def __call__(self, pymodule, node):
100
pyname = self._evaluate_node(pymodule, node)
101
if pyname is None or self.expected is None:
102
return self.unsure
103
if self._unsure_pyname(pyname, unbound=self.kind=='name'):
104
return True
105
if self.kind == 'name':
106
return self._same_pyname(self.expected, pyname)
107
else:
108
pyobject = pyname.get_object()
109
if self.kind == 'object':
110
objects = [pyobject]
111
if self.kind == 'type':
112
objects = [pyobject.get_type()]
113
if self.kind == 'instance':
114
objects = [pyobject]
115
objects.extend(self._get_super_classes(pyobject))
116
objects.extend(self._get_super_classes(pyobject.get_type()))
117
for pyobject in objects:
118
if self._same_pyobject(self.expected.get_object(), pyobject):
119
return True
120
return False
121
122
def _get_super_classes(self, pyobject):
123
result = []
124
if isinstance(pyobject, pyobjects.AbstractClass):
125
for superclass in pyobject.get_superclasses():
126
result.append(superclass)
127
result.extend(self._get_super_classes(superclass))
128
return result
129
130
def _same_pyobject(self, expected, pyobject):
131
return expected == pyobject
132
133
def _same_pyname(self, expected, pyname):
134
return occurrences.same_pyname(expected, pyname)
135
136
def _unsure_pyname(self, pyname, unbound=True):
137
return self.unsure and occurrences.unsure_pyname(pyname, unbound)
138
139
def _split_name(self, name):
140
parts = name.split('.')
141
expression, kind = parts[0], parts[-1]
142
if len(parts) == 1:
143
kind = 'name'
144
return expression, kind
145
146
def _evaluate_node(self, pymodule, node):
147
scope = pymodule.get_scope().get_inner_scope_for_line(node.lineno)
148
expression = node
149
if isinstance(expression, ast.Name) and \
150
isinstance(expression.ctx, ast.Store):
151
start, end = patchedast.node_region(expression)
152
text = pymodule.source_code[start:end]
153
return evaluate.eval_str(scope, text)
154
else:
155
return evaluate.eval_node(scope, expression)
156
157
def _evaluate(self, code):
158
attributes = code.split('.')
159
pyname = None
160
if attributes[0] in ('__builtin__', '__builtins__'):
161
class _BuiltinsStub(object):
162
def get_attribute(self, name):
163
return builtins.builtins[name]
164
def __getitem__(self, name):
165
return builtins.builtins[name]
166
def __contains__(self, name):
167
return name in builtins.builtins
168
pyobject = _BuiltinsStub()
169
else:
170
pyobject = self.project.pycore.get_module(attributes[0])
171
for attribute in attributes[1:]:
172
pyname = pyobject[attribute]
173
if pyname is None:
174
return None
175
pyobject = pyname.get_object()
176
return pyname
177
178