-
Notifications
You must be signed in to change notification settings - Fork 64
/
SLLocalizableVariableCollector.class.st
176 lines (131 loc) · 4.88 KB
/
SLLocalizableVariableCollector.class.st
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"
I am a visitor starting from a statement that accumulates all used variables that should be localized/externalized around the statement.
I use a SLCallGraphFreeVariableCollector to visit methods calls I find in the statement.
CAREFUL: I am a stateful AST visitor and I cannot be reused.
Once instantiated and used, the variables are accessed through the #localizableVariables message.
# Usage
```smalltalk
collector := SLLocalizableVariableCollector
inCodeGenerator: codeGenerator
localizableCandidateVariables: replacementDict keys
callgraphVariableCollector: callgraphVariableCollector.
aStatement accept: collector.
collector localizableVariables.
```
"
Class {
#name : #SLLocalizableVariableCollector,
#superclass : #Object,
#instVars : [
'codeGenerator',
'alreadyVisited',
'callgraphVariableCollector',
'localizableCandidateVariables',
'localizableVariables'
],
#category : #'Slang-Optimizations'
}
{ #category : #'instance creation' }
SLLocalizableVariableCollector class >> inCodeGenerator: aCodeGenerator localizableCandidateVariables: aCollectionOfCandidates callgraphVariableCollector: aCollector [
^ self new
codeGenerator: aCodeGenerator;
localizableCandidateVariables: aCollectionOfCandidates;
callgraphVariableCollector: aCollector;
yourself
]
{ #category : #accessing }
SLLocalizableVariableCollector >> callgraphVariableCollector [
^ callgraphVariableCollector
]
{ #category : #accessing }
SLLocalizableVariableCollector >> callgraphVariableCollector: anObject [
callgraphVariableCollector := anObject
]
{ #category : #accessing }
SLLocalizableVariableCollector >> codeGenerator [
^ codeGenerator
]
{ #category : #accessing }
SLLocalizableVariableCollector >> codeGenerator: anObject [
codeGenerator := anObject
]
{ #category : #initialization }
SLLocalizableVariableCollector >> initialize [
super initialize.
localizableVariables := Set new.
alreadyVisited := Set new.
]
{ #category : #accessing }
SLLocalizableVariableCollector >> localizableCandidateVariables [
^ localizableCandidateVariables
]
{ #category : #accessing }
SLLocalizableVariableCollector >> localizableCandidateVariables: anObject [
localizableCandidateVariables := anObject
]
{ #category : #accessing }
SLLocalizableVariableCollector >> localizableVariables [
^ localizableVariables
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitAssignmentNode: aTAssignmentNode [
aTAssignmentNode variable accept: self.
aTAssignmentNode expression accept: self.
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitCaseStatementNode: aTCaseStmtNode [
"Do not recurse on children of a case statement.
Children will be recursed as separate statements"
aTCaseStmtNode expression accept: self
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitConstantNode: aTConstantNode [
"Nothing for constants"
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitGoToNode: aTGoToNode [
"Nothing"
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitInlineNode: aTInlineNode [
"Do not recurse on children of an inline statement.
Children will be recursed as separate statements"
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitLabeledCommentNode: aTLabeledCommentNode [
"Nothing"
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitReturnNode: aTReturnNode [
"If we are doing a return node, we should externalize everything, no need to go into children"
localizableVariables addAll: localizableCandidateVariables
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitSendNode: aTSendNode [
(codeGenerator isDynamicCall: aTSendNode)
ifTrue: [
"If we are visiting dynamic call, we should externalize everything since we do not know at compile time what function will be called"
localizableVariables addAll: localizableCandidateVariables.
^ self ].
aTSendNode receiver accept: self.
aTSendNode arguments do: [ :argument | argument accept: self ].
callgraphVariableCollector startFromSelector: aTSendNode selector.
(callgraphVariableCollector freeVariablesUsedByMethodNamed: aTSendNode selector)
select: [ :each | localizableCandidateVariables includes: each ]
thenDo: [ :each | localizableVariables add: each ]
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitStatementListNode: aTStatementListNode [
aTStatementListNode statements do: [ :e | e accept: self ]
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitSwitchStatementNode: aTSwitchStmtNode [
"Do not recurse on children of a case statement.
Children will be recursed as separate statements"
aTSwitchStmtNode expression accept: self
]
{ #category : #visiting }
SLLocalizableVariableCollector >> visitVariableNode: aTVariableNode [
(localizableCandidateVariables includes: aTVariableNode name)
ifTrue: [ localizableVariables add: aTVariableNode name ]
]