forked from bonzini/gst-visualgst
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAddMethodUndoCommand.st
109 lines (81 loc) · 3.05 KB
/
AddMethodUndoCommand.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
UndoCommand subclass: AddMethodUndoCommand [
| selector method category classOrMeta oldCompiledMethod browserWidget compiledMethod |
AddMethodUndoCommand class >> add: aString classified: aCategory in: aClass [
<category: 'instance creation'>
^ (self new)
add: aString classified: aCategory in: aClass;
yourself
]
AddMethodUndoCommand class >> add: aString classified: aCategory in: aClass browser: aGtkBrowserWidget [
<category: 'instance creation'>
^ (self new)
add: aString classified: aCategory in: aClass browser: aGtkBrowserWidget;
yourself
]
compileError: aString line: anInteger [
<category: 'error printing'>
browserWidget isNil ifFalse: [ GtkLauncher compileError: aString line: anInteger ].
^ self preconditionFailed: aString
]
compileError: aString pos: pos [
<category: 'error printing'>
^ self compileError: aString line: nil
]
add: aString classified: aCategory in: aClass browser: aGtkBrowserWidget [
<category: 'initialize'>
self add: aString classified: aCategory in: aClass.
browserWidget := aGtkBrowserWidget.
]
add: aString classified: aCategory in: aClass [
<category: 'initialize'>
method := aString.
category := (#('still unclassified' '*') includes: (aCategory))
ifTrue: [ nil ]
ifFalse: [ aCategory ].
classOrMeta := aClass
]
description [
<category: 'accessing'>
^ 'Add a method'
]
precondition [
<category: 'checking'>
| parser node |
parser := STInST.RBBracketedMethodParser new
errorBlock: [ :string :pos | self compileError: string pos: pos. ^false ];
initializeParserWith: method type: #'on:errorBlock:';
yourself.
selector := parser parseMethod selector.
oldCompiledMethod := classOrMeta methodDictionary ifNotNil: [ classOrMeta methodDictionary at: selector ifAbsent: [ nil ] ].
" TODO: use compile:classified:ifError: if there is no category "
compiledMethod := classOrMeta
compile: method
ifError: [ :fname :lineNo :errorString |
self compileError: errorString line: lineNo.
^ false ].
^ true
]
undo [
<category: 'events'>
| selector |
browserWidget ifNotNil: [ browserWidget codeSaved ].
classOrMeta methodDictionary removeMethod: compiledMethod.
oldCompiledMethod
ifNotNil: [
classOrMeta methodDictionary insertMethod: oldCompiledMethod.
selector := oldCompiledMethod selector ]
ifNil: [ selector := nil ].
]
redo [
<category: 'events'>
browserWidget ifNotNil: [ browserWidget codeSaved ].
oldCompiledMethod ifNotNil: [ classOrMeta methodDictionary removeMethod: oldCompiledMethod ].
classOrMeta methodDictionary insertMethod: compiledMethod.
browserWidget ifNotNil: [ classOrMeta isClass
ifTrue: [ browserWidget selectAnInstanceMethod: compiledMethod selector ]
ifFalse: [ browserWidget selectAClassMethod: compiledMethod selector ] ]
]
displayError [
<Category: 'error'>
]
]