/
MetalinkTargetResolver.class.st
122 lines (104 loc) · 4.3 KB
/
MetalinkTargetResolver.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
"
My job is to resolve targets for metalinks to be put on. I only return the target(s) i resolved for the given parameters, which could be:
- a collection of ast nodes
- a slot
- a temporary variable
- a literal variable
Some methods have an option parameter. This is the case for links to be put on slots, temporaries and literal variables.
The option can be one of the following:
#all - will lookup for all access nodes.
#read - will lookup for read nodes only.
#write - will lookup for write nodes only (i.e. assignment nodes) .
I do not take care that methods, slots or globals do exist. Users must ensure they provide valid parameters and/or to handle possible errors.
I only have utility methods in class side.
"
Class {
#name : #MetalinkTargetResolver,
#superclass : #Object,
#category : #'Reflectivity-Installer'
}
{ #category : #resolving }
MetalinkTargetResolver class >> classFor: aClassOrObject [
| class |
aClassOrObject isClass
ifTrue: [ ^ aClassOrObject ].
class := aClassOrObject class.
^ class isAnonymous
ifTrue: [ class superclass ]
ifFalse: [ class ]
]
{ #category : #api }
MetalinkTargetResolver class >> classVariableNamed: aClassVariableName for: aClassOrObject [
^ self lookupClassVariableNamed: aClassVariableName asSymbol in: aClassOrObject
]
{ #category : #api }
MetalinkTargetResolver class >> classVariableNamed: aClassVariableName for: aClassOrObject option: option [
| var |
var := self lookupClassVariableNamed: aClassVariableName asSymbol in: aClassOrObject.
^ self resolveASTLookupFor: var option: option
]
{ #category : #resolving }
MetalinkTargetResolver class >> lookupASTForMethodNamed: aMethodName in: aClassOrObject [
| class |
class := self classFor: aClassOrObject.
^ (class lookupSelector: aMethodName) ast
]
{ #category : #resolving }
MetalinkTargetResolver class >> lookupClassVariableNamed: aClassVariableName in: aClassOrObject [
^ (self classFor: aClassOrObject) classVariableNamed: aClassVariableName
]
{ #category : #resolving }
MetalinkTargetResolver class >> lookupSlotNamed: aSlotName in: aClassOrObject [
| class |
class := self classFor: aClassOrObject.
^ class slotNamed: aSlotName
]
{ #category : #resolving }
MetalinkTargetResolver class >> lookupTemporaryNamed: aTempVarName inMethod: aMethodName for: aClassOrObject [
| class method |
class := self classFor: aClassOrObject.
method := class lookupSelector: aMethodName.
^ method temporaryVariableNamed: aTempVarName
]
{ #category : #api }
MetalinkTargetResolver class >> methodNamed: aMethodName for: aClassOrObject [
^ self lookupASTForMethodNamed: aMethodName asSymbol in: aClassOrObject
]
{ #category : #resolving }
MetalinkTargetResolver class >> resolveASTLookupFor: varOrSlot option: option [
^ (self resolvingBlocForOption: option) value: varOrSlot
]
{ #category : #'resolving - private' }
MetalinkTargetResolver class >> resolvingBlocForOption: option [
option = #write
ifTrue: [ ^ [ :varOrSlot | varOrSlot assignmentNodes asIdentitySet ] ].
option = #read
ifTrue: [ ^ [ :varOrSlot | varOrSlot readNodes asIdentitySet] ].
^ [ :varOrSlot | (OrderedCollection with: varOrSlot assignmentNodes with: varOrSlot readNodes) flattened asIdentitySet ]
]
{ #category : #api }
MetalinkTargetResolver class >> slotNamed: aSlotName for: aClassOrObject [
^ self lookupSlotNamed: aSlotName asSymbol in: aClassOrObject
]
{ #category : #api }
MetalinkTargetResolver class >> slotNamed: aSlotName for: aClassOrObject option: option [
| slot |
slot := self lookupSlotNamed: aSlotName asSymbol in: aClassOrObject.
^ self resolveASTLookupFor: slot option: option
]
{ #category : #api }
MetalinkTargetResolver class >> slotOrVarNodesFor: slotOrVar inMethod: method option: option [
| nodes |
nodes := (self resolvingBlocForOption: option) value: slotOrVar.
^ nodes select: [ :node | node methodNode method = method ]
]
{ #category : #api }
MetalinkTargetResolver class >> temporaryNamed: aTempVarName inMethod: aMethodName for: aClassOrObject [
^ self lookupTemporaryNamed: aTempVarName asSymbol inMethod: aMethodName for: aClassOrObject
]
{ #category : #api }
MetalinkTargetResolver class >> temporaryNamed: aTempVarName inMethod: aMethodName for: aClassOrObject option: option [
| temp |
temp := self lookupTemporaryNamed: aTempVarName asSymbol inMethod: aMethodName for: aClassOrObject.
^ self resolveASTLookupFor: temp option: option
]