-
-
Notifications
You must be signed in to change notification settings - Fork 346
/
ASTCache.class.st
89 lines (71 loc) · 2.44 KB
/
ASTCache.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
"
I am a simple cache for AST nodes corresponding to CompiledMethods in the image. The cache is emptied when the image is saved.
The cached #ast is for one interesting for speed (that is, in situations where you ask for it often).
The other use-case is if you want to annotate the AST and keep that annotation around (till the next image save, but you can subscribe to ASTCacheReset and re-install the AST in the cache after cleaning. (This is used by MetaLinks to make sure they survive image restart).
The last thing that it provides is that we do have a quite powerful mapping between bytecode/text/context and the AST. Regardless of how you navigate, you get the same object.
e.g. even this one works:
[ 1+2 ] sourceNode == thisContext method ast blockNodes first
**NOTE** due to the cached AST, Modification of the AST can be a problem.
Code that wants to modify the AST without making sure the compiledMethod is in sync later should use #parseTree.
"
Class {
#name : #ASTCache,
#superclass : #WeakIdentityKeyDictionary,
#classVars : [
'CacheMissStrategy'
],
#classInstVars : [
'default'
],
#category : #'AST-Core-Parser'
}
{ #category : #'private - announcements' }
ASTCache class >> announceCacheReset [
SystemAnnouncer uniqueInstance announce: ASTCacheReset new
]
{ #category : #accessing }
ASTCache class >> at: aCompiledMethod [
^ self default at: aCompiledMethod
]
{ #category : #accessing }
ASTCache class >> cacheMissStrategy [
^ CacheMissStrategy
ifNil: [ CacheMissStrategy := ASTCacheMissStrategy new ]
]
{ #category : #accessing }
ASTCache class >> cacheMissStrategy: aCacheMissStrategy [
^ CacheMissStrategy := aCacheMissStrategy
]
{ #category : #accessing }
ASTCache class >> default [
^ default ifNil: [
SessionManager default registerSystemClassNamed: self name.
default := self new ]
]
{ #category : #accessing }
ASTCache class >> default: anASTCache [
default := anASTCache
]
{ #category : #initialization }
ASTCache class >> reset [
<script>
self default reset.
self announceCacheReset
]
{ #category : #'system startup' }
ASTCache class >> shutDown [
self reset
]
{ #category : #accessing }
ASTCache >> at: aCompiledMethod [
"for doit methods, the ast is stored in the method propery"
^ aCompiledMethod propertyAt: #ast ifAbsent: [
self
at: aCompiledMethod
ifAbsentPut: [
self class cacheMissStrategy getASTFor: aCompiledMethod ] ]
]
{ #category : #initialization }
ASTCache >> reset [
self removeAll
]