Added abstract class for code generation - CustomCodeGeneratorAbstract
authorJakub Nesveda <jakubnesveda@seznam.cz>
Wed, 21 Aug 2013 22:21:58 +0200
changeset 494 e4f35fce9e0f
parent 493 db3ea1dbd584
child 495 685a2fc308b5
Added abstract class for code generation - CustomCodeGeneratorAbstract
CustomCodeGeneratorAbstract.st
Make.proto
Make.spec
abbrev.stc
bc.mak
jn_refactoring_custom.st
libInit.cc
refactoring_custom.rc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CustomCodeGeneratorAbstract.st	Wed Aug 21 22:21:58 2013 +0200
@@ -0,0 +1,699 @@
+"
+ COPYRIGHT (c) 2002 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'jn:refactoring_custom' }"
+
+Object subclass:#CustomCodeGeneratorAbstract
+	instanceVariableNames:'compositeChangeCollector compositeChangeNesting userPreferences
+		generateComments confirmChanges targetClass'
+	classVariableNames:'GenerateCommentsForGetters GenerateCommentsForSetters
+		CopyrightTemplate'
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomCodeGeneratorAbstract class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2002 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+    This utility class contains various code generation facilites;
+    these were extracted from the old and newBrowser.
+    There is probably more to come...
+
+    Note: being refactored into separate per-language generators
+
+    [author:]
+        Claus Gittiner
+"
+! !
+
+!CustomCodeGeneratorAbstract class methodsFor:'instance creation'!
+
+new
+    ^ self basicNew initialize.
+! !
+
+!CustomCodeGeneratorAbstract class methodsFor:'compilation'!
+
+compile:theCode forClass:aClass inCategory:cat 
+    "install some code for a class.
+     If refactory browser stuff is avaliable the refactory tools are used to support undo"
+
+    ^ self new compile:theCode forClass:aClass inCategory:cat
+! !
+
+!CustomCodeGeneratorAbstract class methodsFor:'interface specs'!
+
+initialMenuSpecForApplications
+    "return a menuSpec with typical stuff in it"
+
+    "This resource specification was automatically generated by the CustomCodeGeneratorAbstract."
+
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
+
+    "
+     MenuEditor new openOnClass:self andSelector:#initialMenuSpecForApplications
+    "
+
+    <resource: #menu>
+
+    ^ #(#Menu
+           #(
+             #(#MenuItem
+                #label: 'File'
+                #translateLabel: true
+                #submenu: 
+                 #(#Menu
+                     #(
+                       #(#MenuItem
+                          #label: 'New'
+                          #translateLabel: true
+                          #value: #menuNew
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'Open...'
+                          #translateLabel: true
+                          #value: #menuOpen
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'Save'
+                          #translateLabel: true
+                          #value: #menuSave
+                      )
+                       #(#MenuItem
+                          #label: 'Save As...'
+                          #translateLabel: true
+                          #value: #menuSaveAs
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'Exit'
+                          #translateLabel: true
+                          #value: #closeRequest
+                      )
+                    ) nil
+                    nil
+                )
+            )
+             #(#MenuItem
+                #label: 'Help'
+                #translateLabel: true
+                #startGroup: #right
+                #submenu: 
+                 #(#Menu
+                     #(
+                       #(#MenuItem
+                          #label: 'Documentation'
+                          #translateLabel: true
+                          #value: #openDocumentation
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'About this Application...'
+                          #translateLabel: true
+                          #value: #openAboutThisApplication
+                      )
+                    ) nil
+                    nil
+                )
+            )
+          ) nil
+          nil
+      )
+!
+
+initialPageMenuSpecForWebApplications
+    "return a menuSpec with typical stuff in it"
+
+    "This resource specification was automatically generated by the CustomCodeGeneratorAbstract."
+
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
+
+    "
+     MenuEditor new openOnClass:self andSelector:#initialPageMenuSpecForWebApplications
+    "
+
+    <resource: #menu>
+
+    ^ #(#Menu
+           #(
+             #(#MenuItem
+                #label: 'File'
+                #translateLabel: true
+                #submenu: 
+                 #(#Menu
+                     #(
+                       #(#MenuItem
+                          #label: 'New'
+                          #translateLabel: true
+                          #value: #menuNew
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'Open...'
+                          #translateLabel: true
+                          #value: #menuOpen
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'Save'
+                          #translateLabel: true
+                          #value: #menuSave
+                      )
+                       #(#MenuItem
+                          #label: 'Save As...'
+                          #translateLabel: true
+                          #value: #menuSaveAs
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'Exit'
+                          #translateLabel: true
+                          #value: #closeRequest
+                      )
+                    ) nil
+                    nil
+                )
+            )
+             #(#MenuItem
+                #label: 'Help'
+                #translateLabel: true
+                #startGroup: #right
+                #submenu: 
+                 #(#Menu
+                     #(
+                       #(#MenuItem
+                          #label: 'Documentation'
+                          #translateLabel: true
+                          #value: #openDocumentation
+                      )
+                       #(#MenuItem
+                          #label: '-'
+                      )
+                       #(#MenuItem
+                          #label: 'About this Application...'
+                          #translateLabel: true
+                          #value: #openAboutThisApplication
+                      )
+                    ) nil
+                    nil
+                )
+            )
+          ) nil
+          nil
+      )
+!
+
+initialPageSpecForWebApplications
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:self andSelector:#initialPageSpecForWebApplications
+    "
+
+    <resource: #canvas>
+
+    ^ #(#FullSpec
+          #window: 
+           #(#WindowSpec
+              #name: '%1'
+              #layout: #(#LayoutFrame 204 0 162 0 503 0 461 0)
+              #label: '%1'
+              #min: #(#Point 10 10)
+              #max: #(#Point 1024 768)
+              #bounds: #(#Rectangle 204 162 504 462)
+              #menu: #pageMenu
+              #usePreferredExtent: false
+          )
+          #component: 
+           #(#SpecCollection
+              #collection: #()
+          )
+      )
+
+    "Modified: / 14-07-2011 / 16:44:20 / cg"
+!
+
+initialToolbarMenuSpec
+    "This resource specification was automatically generated
+     by the MenuEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
+
+
+    "
+     MenuEditor new openOnClass:CustomCodeGeneratorAbstract andSelector:#initialToolbarMenuSpec
+     (Menu new fromLiteralArrayEncoding:(CustomCodeGeneratorAbstract initialToolbarMenuSpec)) startUp
+    "
+
+    <resource: #menu>
+
+    ^ 
+     #(Menu
+        (
+         (MenuItem
+            label: 'Reload'
+            itemValue: menuReload
+            translateLabel: true
+            isButton: true
+            labelImage: (ResourceRetriever ToolbarIconLibrary reload24x24Icon)
+          )
+         )
+        nil
+        nil
+      )
+!
+
+initialWindowSpecForApplications
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:CustomCodeGeneratorAbstract andSelector:#initialWindowSpecForApplications
+    "
+
+    <resource: #canvas>
+
+    ^ 
+     #(FullSpec
+        name: initialWindowSpecForApplications
+        window: 
+       (WindowSpec
+          label: '%1'
+          name: '%1'
+          min: (Point 10 10)
+          bounds: (Rectangle 0 0 300 300)
+          menu: mainMenu
+        )
+        component: 
+       (SpecCollection
+          collection: (
+           (LabelSpec
+              label: 'Hello World'
+              name: 'Label1'
+              layout: (LayoutFrame 0 0.0 60 0 0 1.0 219 0)
+              translateLabel: true
+            )
+           )
+         
+        )
+      )
+
+    "Modified: / 07-05-2010 / 14:21:48 / cg"
+!
+
+initialWindowSpecForApplications2
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:CustomCodeGeneratorAbstract andSelector:#initialWindowSpecForApplications2
+    "
+
+    <resource: #canvas>
+
+    ^ 
+     #(FullSpec
+        name: initialWindowSpecForApplications2
+        window: 
+       (WindowSpec
+          label: '%1'
+          name: '%1'
+          min: (Point 10 10)
+          bounds: (Rectangle 0 0 300 300)
+          menu: mainMenu
+        )
+        component: 
+       (SpecCollection
+          collection: (
+           (MenuPanelSpec
+              name: 'ToolBar1'
+              layout: (LayoutFrame 0 0.0 0 0 0 1.0 36 0)
+              menu: toolbarMenu
+              textDefault: true
+            )
+           (ViewSpec
+              name: 'Box1'
+              layout: (LayoutFrame 1 0 36 0 0 1 -26 1)
+              level: 1
+              component: 
+             (SpecCollection
+                collection: (
+                 (LabelSpec
+                    label: 'Hello World'
+                    name: 'Contents'
+                    layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+                    translateLabel: true
+                  )
+                 )
+               
+              )
+            )
+           (ViewSpec
+              name: 'Box2'
+              layout: (LayoutFrame 0 0 -26 1 0 1 0 1)
+              level: 1
+              component: 
+             (SpecCollection
+                collection: (
+                 (LabelSpec
+                    label: 'InfoLabel'
+                    name: 'Label2'
+                    layout: (LayoutFrame 0 0 -26 1 -1 1 0 1)
+                    level: -1
+                    translateLabel: true
+                    labelChannel: infoLabelHolder
+                    adjust: left
+                  )
+                 )
+               
+              )
+            )
+           )
+         
+        )
+      )
+!
+
+initialWindowSpecForDialogs
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:CustomCodeGeneratorAbstract andSelector:#initialWindowSpecForDialogs
+    "
+
+    <resource: #canvas>
+
+    ^ 
+     #(FullSpec
+        name: initialWindowSpecForDialogs
+        window: 
+       (WindowSpec
+          label: '%1'
+          name: '%1'
+          min: (Point 10 10)
+          bounds: (Rectangle 0 0 300 300)
+        )
+        component: 
+       (SpecCollection
+          collection: (
+           (HorizontalPanelViewSpec
+              name: 'buttonPanel'
+              layout: (LayoutFrame 0 0.0 -40 1 0 1.0 0 1.0)
+              horizontalLayout: spreadSpaceMax
+              verticalLayout: center
+              horizontalSpace: 3
+              verticalSpace: 3
+              reverseOrderIfOKAtLeft: true
+              component: 
+             (SpecCollection
+                collection: (
+                 (ActionButtonSpec
+                    label: 'Cancel'
+                    name: 'cancelButton'
+                    translateLabel: true
+                    tabable: true
+                    model: cancel
+                    extent: (Point 125 22)
+                  )
+                 (ActionButtonSpec
+                    label: 'OK'
+                    name: 'okButton'
+                    translateLabel: true
+                    tabable: true
+                    model: accept
+                    isDefault: true
+                    extent: (Point 125 22)
+                  )
+                 )
+               
+              )
+            )
+           )
+         
+        )
+      )
+
+    "Modified: / 07-05-2010 / 14:21:55 / cg"
+! !
+
+!CustomCodeGeneratorAbstract class methodsFor:'private'!
+
+canUseRefactoringSupport
+    "check if refactory browser stuff is avaliable"
+
+     ^ RefactoryChangeManager notNil 
+    and:[RefactoryChangeManager isLoaded
+    and:[UserPreferences current useRefactoringSupport]]
+!
+
+methodNameTemplateFor:aSelector
+    self subclassResponsibility
+! !
+
+!CustomCodeGeneratorAbstract class methodsFor:'utilities'!
+
+missingRequiredProtocolFor:aClass
+    "return the missing required protocol; 
+     that is the set of selectors which send #subclassResponsibility in a superclass and 
+     have no implementation in aClass or in any class between aClass and that superclass"
+
+    |requiredSelectors implementedSelectors|
+
+    requiredSelectors := IdentitySet new.
+    implementedSelectors := IdentitySet withAll:(aClass methodDictionary keys).
+
+    aClass allSuperclassesDo:[:eachSuperClass |
+        eachSuperClass methodDictionary keysAndValuesDo:[:eachSelector :eachMethod |
+            (eachMethod sends:#subclassResponsibility or:#subclassResponsibility:) ifTrue:[
+                (implementedSelectors includes:eachSelector) ifFalse:[
+                    requiredSelectors add:eachSelector.
+                ]
+            ] ifFalse:[
+                (requiredSelectors includes:eachSelector) ifFalse:[
+                    implementedSelectors add:eachSelector.
+                ].
+            ].
+        ]
+    ].
+    ^ requiredSelectors
+
+    "Modified: / 08-08-2011 / 18:44:58 / cg"
+! !
+
+!CustomCodeGeneratorAbstract methodsFor:'bulk changes'!
+
+addChange:aChange
+    compositeChangeCollector addChange:aChange
+!
+
+executeCollectedChangesNamed:name
+    "if both the compositeChangeCollector and I myself think, that it should be confirmed,
+     the let user do it - I am not sure, if the heuristics here is useful;
+     it might be better to let the generator decide (for example, if it does high-impact
+     changes, as opposed to simple ones)"
+
+    compositeChangeCollector notNil ifTrue:[
+        compositeChangeNesting := compositeChangeNesting - 1.
+        compositeChangeNesting == 0 ifTrue:[
+            compositeChangeCollector name:name.
+            compositeChangeCollector changesSize == 0 ifTrue:[
+                self information:'Nothing generated.'.
+            ] ifFalse:[
+                "JV@2012-04-04: Here used to be a code for confirming changes.
+                 The has moved to RefactoryChangeManager so all refactorings
+                 are also subject to confirmation (is enabled in UserPreferences)"
+                RefactoryChangeManager instance performChange: compositeChangeCollector
+            ].
+            compositeChangeCollector := nil.
+        ]
+    ]
+
+    "Modified (comment): / 04-08-2011 / 17:30:27 / cg"
+    "Modified (format): / 04-04-2012 / 16:35:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+startCollectChanges
+    (self canUseRefactoringSupport) ifTrue:[
+        compositeChangeCollector isNil ifTrue:[
+            compositeChangeCollector := CompositeRefactoryChange new.
+            compositeChangeNesting := 0.
+        ].
+        compositeChangeNesting := compositeChangeNesting + 1.
+    ]
+! !
+
+!CustomCodeGeneratorAbstract methodsFor:'compilation'!
+
+compile:theCode forClass:aClass inCategory:cat 
+    "install some code for a class.
+     If refactory browser stuff is avaliable the refactory tools are used to support undo"
+
+    self
+        compile:theCode forClass:aClass inCategory:cat 
+        skipIfSame:true
+!
+
+compile:theCode forClass:aClass inCategory:cat skipIfSame:skipIfSame 
+    "install some code for a class.
+     If refactory browser stuff is avaliable the refactory tools are used to support undo"
+
+    |change compiler selector oldMthd isSame|
+
+    isSame := false.
+    skipIfSame ifTrue:[
+        compiler := aClass compilerClass new.
+        compiler parseMethod:theCode in:aClass ignoreErrors:true ignoreWarnings:true.
+
+        selector := compiler selector.
+        selector notNil ifTrue:[
+            oldMthd := aClass compiledMethodAt:selector.
+            isSame := (oldMthd notNil and:[oldMthd source = theCode]).
+            isSame ifTrue:[^ self ].
+        ].
+    ].
+
+    self canUseRefactoringSupport ifFalse:[
+        "/ compile immediately
+        aClass compile:theCode classified:cat.
+        ^ self.
+    ].
+
+    change := InteractiveAddMethodChange compile:(theCode asString) in:aClass classified:cat.
+
+    "/ if collecting, add to changes (to be executed as one change at the end,
+    "/ in order to have only one change in the undo-list (instead of many)
+    compositeChangeCollector notNil ifTrue:[
+        compositeChangeCollector addChange:change
+    ] ifFalse:[
+        RefactoryChangeManager performChange:change.
+    ]
+
+    "Modified: / 21-08-2006 / 18:39:06 / cg"
+    "Modified (format): / 21-01-2012 / 10:40:59 / cg"
+! !
+
+!CustomCodeGeneratorAbstract methodsFor:'initialization'!
+
+confirmChanges
+    "if true, let user confirm complicated changes; if false, just do it"
+
+    ^ confirmChanges ? true
+
+    "Created: / 04-08-2011 / 17:31:45 / cg"
+!
+
+confirmChanges:aBoolean
+    "if true, let user confirm complicated changes; if false, just do it"
+
+    confirmChanges := aBoolean
+
+    "Created: / 04-08-2011 / 17:26:47 / cg"
+!
+
+initialize
+    userPreferences := UserPreferences current.
+    generateComments := userPreferences generateComments.
+! !
+
+!CustomCodeGeneratorAbstract methodsFor:'private'!
+
+canUseRefactoringSupport
+    "check if refactory browser stuff is avaliable"
+
+     ^ self class canUseRefactoringSupport
+!
+
+privCreateClassResponsibleProtocolFor:aClass
+    "create stubs for the required protocol.
+     aClass may be a a MetaClass or a non-MetaClass"
+
+    |requiredProtocol|
+
+    requiredProtocol := self class missingRequiredProtocolFor:aClass.
+    requiredProtocol do:[:eachSelector |
+        |code implClass|
+
+        implClass := aClass whichClassImplements:eachSelector.
+        implClass == Object ifFalse:[
+            code := self codeFor_shouldImplementFor:eachSelector inClass:aClass.
+
+            self 
+                compile:code
+                forClass:aClass 
+                inCategory:(implClass compiledMethodAt:eachSelector) category.
+        ]
+    ].
+! !
+
+!CustomCodeGeneratorAbstract class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libtool/CustomCodeGeneratorAbstract.st,v 1.100 2012-10-15 20:17:19 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/libtool/CustomCodeGeneratorAbstract.st,v 1.100 2012-10-15 20:17:19 cg Exp $'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id: CustomCodeGeneratorAbstract.st 8074 2012-11-30 17:23:39Z vranyj1 $'
+! !
+
--- a/Make.proto	Fri Aug 16 00:00:50 2013 +0200
+++ b/Make.proto	Wed Aug 21 22:21:58 2013 +0200
@@ -126,6 +126,7 @@
 
 # BEGINMAKEDEPEND --- do not remove this line; make depend needs it
 $(OUTDIR)CustomCodeGenerator.$(O) CustomCodeGenerator.$(H): CustomCodeGenerator.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)CustomCodeGeneratorAbstract.$(O) CustomCodeGeneratorAbstract.$(H): CustomCodeGeneratorAbstract.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)CustomCodeGeneratorAndRefactoringManager.$(O) CustomCodeGeneratorAndRefactoringManager.$(H): CustomCodeGeneratorAndRefactoringManager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)CustomRefactoring.$(O) CustomRefactoring.$(H): CustomRefactoring.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)DummyCodeGenerator.$(O) DummyCodeGenerator.$(H): DummyCodeGenerator.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
--- a/Make.spec	Fri Aug 16 00:00:50 2013 +0200
+++ b/Make.spec	Wed Aug 21 22:21:58 2013 +0200
@@ -51,6 +51,7 @@
 
 COMMON_CLASSES= \
 	CustomCodeGenerator \
+	CustomCodeGeneratorAbstract \
 	CustomCodeGeneratorAndRefactoringManager \
 	CustomRefactoring \
 	DummyCodeGenerator \
@@ -62,6 +63,7 @@
 
 COMMON_OBJS= \
     $(OUTDIR_SLASH)CustomCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)CustomCodeGeneratorAbstract.$(O) \
     $(OUTDIR_SLASH)CustomCodeGeneratorAndRefactoringManager.$(O) \
     $(OUTDIR_SLASH)CustomRefactoring.$(O) \
     $(OUTDIR_SLASH)DummyCodeGenerator.$(O) \
--- a/abbrev.stc	Fri Aug 16 00:00:50 2013 +0200
+++ b/abbrev.stc	Wed Aug 21 22:21:58 2013 +0200
@@ -2,6 +2,7 @@
 # this file is needed for stc to be able to compile modules independently.
 # it provides information about a classes filename, category and especially namespace.
 CustomCodeGenerator CustomCodeGenerator jn:refactoring_custom 'Interface-Refactoring-Custom' 0
+CustomCodeGeneratorAbstract CustomCodeGeneratorAbstract jn:refactoring_custom 'Interface-Refactoring-Custom' 0
 CustomCodeGeneratorAndRefactoringManager CustomCodeGeneratorAndRefactoringManager jn:refactoring_custom 'Interface-Refactoring-Custom' 0
 CustomCodeTests CustomCodeTests jn:refactoring_custom '* as yet unspecified *' 1
 CustomRefactoring CustomRefactoring jn:refactoring_custom 'Interface-Refactoring-Custom' 0
--- a/bc.mak	Fri Aug 16 00:00:50 2013 +0200
+++ b/bc.mak	Wed Aug 21 22:21:58 2013 +0200
@@ -72,6 +72,7 @@
 
 # BEGINMAKEDEPEND --- do not remove this line; make depend needs it
 $(OUTDIR)CustomCodeGenerator.$(O) CustomCodeGenerator.$(H): CustomCodeGenerator.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)CustomCodeGeneratorAbstract.$(O) CustomCodeGeneratorAbstract.$(H): CustomCodeGeneratorAbstract.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)CustomCodeGeneratorAndRefactoringManager.$(O) CustomCodeGeneratorAndRefactoringManager.$(H): CustomCodeGeneratorAndRefactoringManager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)CustomRefactoring.$(O) CustomRefactoring.$(H): CustomRefactoring.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)DummyCodeGenerator.$(O) DummyCodeGenerator.$(H): DummyCodeGenerator.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
--- a/jn_refactoring_custom.st	Fri Aug 16 00:00:50 2013 +0200
+++ b/jn_refactoring_custom.st	Wed Aug 21 22:21:58 2013 +0200
@@ -41,6 +41,7 @@
      exclude individual packages in the #excludedFromPreRequisites method."
 
     ^ #(
+        #'stx:goodies/refactoryBrowser/changes'    "CompositeRefactoryChange - referenced by CustomCodeGeneratorAbstract>>startCollectChanges "
     )
 !
 
@@ -65,6 +66,7 @@
     ^ #(
         "<className> or (<className> attributes...) in load order"
         CustomCodeGenerator
+        CustomCodeGeneratorAbstract
         CustomCodeGeneratorAndRefactoringManager
         (CustomCodeTests autoload)
         CustomRefactoring
--- a/libInit.cc	Fri Aug 16 00:00:50 2013 +0200
+++ b/libInit.cc	Wed Aug 21 22:21:58 2013 +0200
@@ -28,6 +28,7 @@
 OBJ snd; struct __vmData__ *__pRT__; {
 __BEGIN_PACKAGE2__("libjn_refactoring_custom", _libjn_refactoring_custom_Init, "jn:refactoring_custom");
 _CustomCodeGenerator_Init(pass,__pRT__,snd);
+_CustomCodeGeneratorAbstract_Init(pass,__pRT__,snd);
 _CustomCodeGeneratorAndRefactoringManager_Init(pass,__pRT__,snd);
 _CustomRefactoring_Init(pass,__pRT__,snd);
 _DummyCodeGenerator_Init(pass,__pRT__,snd);
--- a/refactoring_custom.rc	Fri Aug 16 00:00:50 2013 +0200
+++ b/refactoring_custom.rc	Wed Aug 21 22:21:58 2013 +0200
@@ -25,7 +25,7 @@
       VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
       VALUE "ProductName", "ProductName\0"
       VALUE "ProductVersion", "6.2.3.895\0"
-      VALUE "ProductDate", "Thu, 15 Aug 2013 22:00:37 GMT\0"
+      VALUE "ProductDate", "Wed, 21 Aug 2013 20:20:45 GMT\0"
     END
 
   END