831 addChange:aChange |
831 addChange:aChange |
832 compositeChangeCollector addChange:aChange |
832 compositeChangeCollector addChange:aChange |
833 ! |
833 ! |
834 |
834 |
835 executeCollectedChangesNamed:name |
835 executeCollectedChangesNamed:name |
|
836 |
|
837 | changes | |
|
838 |
836 compositeChangeCollector notNil ifTrue:[ |
839 compositeChangeCollector notNil ifTrue:[ |
837 compositeChangeNesting := compositeChangeNesting - 1. |
840 compositeChangeNesting := compositeChangeNesting - 1. |
838 compositeChangeNesting == 0 ifTrue:[ |
841 compositeChangeNesting == 0 ifTrue:[ |
839 compositeChangeCollector name:name. |
842 compositeChangeCollector name:name. |
840 compositeChangeCollector changesSize == 0 ifTrue:[ |
843 compositeChangeCollector changesSize == 0 ifTrue:[ |
841 self information:'Nothing generated.'. |
844 self information:'Nothing generated.'. |
842 ] ifFalse:[ |
845 ] ifFalse:[ |
843 RefactoryChangeManager performChange:compositeChangeCollector. |
846 compositeChangeCollector changesSize == 1 |
|
847 ifTrue: [ |
|
848 RefactoryChangeManager instance performChange: compositeChangeCollector |
|
849 ] ifFalse: [ |
|
850 changes := Tools::ChangeSetBrowser confirmChanges: |
|
851 (ChangeSet with:compositeChangeCollector). |
|
852 changes do:[:chg|RefactoryChangeManager instance performChange: chg]. |
|
853 ]. |
844 ]. |
854 ]. |
845 compositeChangeCollector := nil. |
855 compositeChangeCollector := nil. |
846 ] |
856 ] |
847 ] |
857 ] |
848 ! |
858 ! |
1077 "create an (almost) empty testCase class" |
1087 "create an (almost) empty testCase class" |
1078 |
1088 |
1079 self subclassResponsibility |
1089 self subclassResponsibility |
1080 ! |
1090 ! |
1081 |
1091 |
|
1092 createVisitorMethodsIn:visitedClass andCompilerClass:visitorClass |
|
1093 " |
|
1094 This is much like createVisitorMethodsIn:andVisitorClass:, |
|
1095 but generates |
|
1096 acceptVisitor:forEffect: |
|
1097 and |
|
1098 visit<NODE>:forEffect: |
|
1099 in visit* methods. |
|
1100 " |
|
1101 |
|
1102 |sel superSel | |
|
1103 |
|
1104 self assert:( visitedClass isMeta not ). |
|
1105 self assert:( visitorClass isMeta not ). |
|
1106 |
|
1107 self startCollectChanges. |
|
1108 |
|
1109 sel := ('visit' , visitedClass nameWithoutPrefix , ':'). |
|
1110 superSel := ('visit' , visitedClass superclass nameWithoutPrefix , ':'). |
|
1111 |
|
1112 (visitedClass includesSelector:#acceptVisitor:forEffect:) ifFalse: |
|
1113 [self addChange: |
|
1114 (CodeGenerator new |
|
1115 class: visitedClass; |
|
1116 protocol: 'visiting'; |
|
1117 source: ('acceptVisitor: visitor forEffect: effect |
|
1118 "Double dispatch back to the visitor, passing my type encoded in |
|
1119 the selector (visitor pattern) and given effect" |
|
1120 |
|
1121 "stub code automatically generated - please change if required" |
|
1122 |
|
1123 ^visitor `@sel: self forEffect: effect'); |
|
1124 replace: '`@sel:' with: sel asSymbol; |
|
1125 change) |
|
1126 ]. |
|
1127 |
|
1128 |
|
1129 |
|
1130 |
|
1131 (visitorClass includesSelector:(sel, 'forEffect:') asSymbol) ifFalse:[ |
|
1132 self addChange: |
|
1133 (CodeGenerator new |
|
1134 class: visitorClass; |
|
1135 protocol: 'visiting'; |
|
1136 source: ('`@sel: anObject forEffect: effect |
|
1137 "dispatched back from the visited object (visitor pattern)" |
|
1138 |
|
1139 ^ self `@superSel: anObject forEffect: effect'); |
|
1140 replace: '`@sel:' with: sel asSymbol; |
|
1141 replace: '`@superSel:' with: superSel asSymbol; |
|
1142 change) |
|
1143 ]. |
|
1144 |
|
1145 |
|
1146 (visitorClass includesSelector:#'visit:') ifFalse:[ |
|
1147 self |
|
1148 compile: |
|
1149 ('visit:anObject |
|
1150 "visit anObject (visitor pattern). |
|
1151 The object should call back one of my visitXXXX methods." |
|
1152 |
|
1153 ^ anObject acceptVisitor:self |
|
1154 ') |
|
1155 forClass:visitorClass |
|
1156 inCategory:'visiting'. |
|
1157 ]. |
|
1158 |
|
1159 self executeCollectedChangesNamed:('Create Compiler Visiting Methods'). |
|
1160 |
|
1161 "Created: / 20-03-2010 / 10:49:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
1162 ! |
|
1163 |
|
1164 createVisitorMethodsIn:visitedClass andVisitorClass2:visitorClass |
|
1165 " |
|
1166 This is much like createVisitorMethodsIn:andVisitorClass:, |
|
1167 but generates |
|
1168 self visitSuperclass: anObject |
|
1169 in visit* methods. |
|
1170 " |
|
1171 |
|
1172 |sel superSel | |
|
1173 |
|
1174 self assert:( visitedClass isMeta not ). |
|
1175 self assert:( visitorClass isMeta not ). |
|
1176 |
|
1177 self startCollectChanges. |
|
1178 |
|
1179 sel := ('visit' , visitedClass nameWithoutPrefix , ':'). |
|
1180 superSel := ('visit' , visitedClass superclass nameWithoutPrefix , ':'). |
|
1181 self createAcceptVisitorMethod:sel in:visitedClass. |
|
1182 |
|
1183 (visitorClass includesSelector:sel) ifFalse:[ |
|
1184 self addChange: |
|
1185 (CodeGenerator new |
|
1186 class: visitorClass; |
|
1187 protocol: 'visiting'; |
|
1188 source: ('`@sel: anObject |
|
1189 "dispatched back from the visited %2-object (visitor pattern)" |
|
1190 |
|
1191 ^ self `@superSel: anObject'); |
|
1192 replace: '`@sel:' with: sel asSymbol; |
|
1193 replace: '`@superSel:' with: superSel asSymbol; |
|
1194 change) |
|
1195 ]. |
|
1196 |
|
1197 |
|
1198 (visitorClass includesSelector:#'visit:') ifFalse:[ |
|
1199 self |
|
1200 compile: |
|
1201 ('visit:anObject |
|
1202 "visit anObject (visitor pattern). |
|
1203 The object should call back one of my visitXXXX methods." |
|
1204 |
|
1205 ^ anObject acceptVisitor:self |
|
1206 ') |
|
1207 forClass:visitorClass |
|
1208 inCategory:'visiting'. |
|
1209 ]. |
|
1210 |
|
1211 self executeCollectedChangesNamed:('Add Visitor Pattern'). |
|
1212 |
|
1213 "Created: / 07-07-2009 / 19:53:10 / Jan Vrany <vranyj1@fel.cvut.cz>" |
|
1214 ! |
|
1215 |
1082 createVisitorMethodsIn:visitedClass andVisitorClass:visitorClass |
1216 createVisitorMethodsIn:visitedClass andVisitorClass:visitorClass |
1083 "create acceptVisitor: in visitedClass and acceptXXX in visitorClass. (I'm tired of typing)" |
1217 "create acceptVisitor: in visitedClass and acceptXXX in visitorClass. (I'm tired of typing)" |
1084 |
1218 |
1085 self subclassResponsibility |
1219 self subclassResponsibility |
1086 ! |
1220 ! |