-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathScopeObject.py
147 lines (121 loc) · 3.96 KB
/
ScopeObject.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import re
class ScopeObject:
idCounter = 0
def __init__(self, line: str, parent):
''' takes a line of python code and scope type and parent node '''
self.__line = line
self.__children = []
self.__parent = parent
self.__id = ScopeObject.idCounter
ScopeObject.idCounter += 1
def get_line(self):
return self.__line
def __str__(self):
''' returns the string of the code '''
string = self.get_line() or ""
if not self.is_statement():
for child in self.__children:
string += str(child)
return string
def ascend_scope(self):
''' moves the requested line to a higher scope if possible, return false if not'''
def remove_ltab(child):
print("HAD TABS: ", child.get_line().count("\t"))
child.__raw_replace(child.get_line()[1:])
print("NOW HAS TABS: ", child.get_line().count("\t"))
for subchild in child.get_children():
remove_ltab(subchild)
if self.is_root() or self.__parent.is_root():
print("FAILED TO ASCEND")
return False
else:
pindex = self.__parent.get_parent().index_of(self.__parent)
self.__parent.remove_child(self)
self.__parent = self.__parent.get_parent()
self.__parent.add_child(self, pindex)
remove_ltab(self)
def refactor(self, old_name, new_name):
if old_name.strip() == "":
return
self.__line.replace(old_name, new_name)
print("REFACTORING ", r"\b" + old_name + r"\b", " WITH ", new_name, " IN ", str(self.__line.encode("unicode-escape")))
self.replace(re.sub(r"\b" + old_name + r"\b", new_name, self.__line.replace("\t", "")))
print("NOW: ", str(self.__line.encode("unicode-escape")))
for child in self.__children:
child.refactor(old_name, new_name)
def replace(self, new_line: str):
''' replace the old lines with the new line '''
self.__line = "\t"*self.__line.count("\t") + new_line
def __iter__(self):
''' iterates line by line '''
if(self.__line != None):
yield self.__line
for child in self.__children:
for line in child:
yield line
def get_type(self):
''' Possible types are FUNCTION LOOP CLASS STATEMENT '''
return self.__typeOfScope()
def is_statement(self):
''' returns if this scope object represents a statement '''
return len(self.__children) == 0
# THE FOLLLOWING IS TREE PROCESSING, UNNEEDED FOR YOU GUYS
def add_child(self, new_child, index = None):
''' inserts another line of code at the specified index (default end) '''
if self.get_type() == "STATEMENT":
return
if(isinstance(new_child, str)):
nchild = ScopeObject(new_child, self)
else:
nchild = new_child
if(index == None):
self.__children.append(nchild)
else:
self.__children.insert(index, nchild)
nchild.__parent = self
def set_parent(self, other):
self.__parent = other
def index_of(self, child):
for i, c in enumerate(self.__children):
if child == c:
return i
return -1
def get_child(self, line):
for child in self.__children:
if(child.get_line() == line):
return child
def get_children(self):
return self.__children
def remove_child(self, rchild):
if(isinstance(rchild, str)):
for child in self.__children:
if(child.get_line() == child):
remove_child(child)
else:
self.__children.remove(rchild)
def get_id(self):
return self.__id
def size_of(self):
''' returns the number of contained lines/scopes '''
return len(self.__children)
def is_root(self):
return self.__parent == None
def get_parent(self):
return self.__parent
def __raw_replace(self, new):
self.__line = new
def __eq__(self, other):
if isinstance(other, ScopeObject):
return self.__id == other.__id
else:
return False
def __typeOfScope(self):
''' returns the type of scope that the code is '''
if(self.__parent == None):
return "ROOT"
CodeTypes = {"for": "FORLOOP", "while": "WHILELOOP", "def" : "FUNCTION", "class": "CLASS", "if": "CONDITIONAL", "else": "CONDITIONAL", "elif": "CONDITIONAL"}
code = self.__line.replace(" ", "").strip().lower()
for k,v in CodeTypes.items():
if(code.startswith(k)):
return v
return "STATEMENT"